follows.test.ts 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. import { ApolloServer } from 'apollo-server-express'
  2. import { Mongoose } from 'mongoose'
  3. import { Aggregates } from '../src/types'
  4. import { ApolloServerTestClient } from 'apollo-server-testing/dist/createTestClient'
  5. import { buildAggregates, connectMongoose, createServer } from '../src/server'
  6. import { createTestClient } from 'apollo-server-testing'
  7. import {
  8. FOLLOW_CHANNEL,
  9. FollowChannel,
  10. FollowChannelArgs,
  11. GET_CHANNEL_FOLLOWS,
  12. GetChannelFollows,
  13. GetChannelFollowsArgs,
  14. UNFOLLOW_CHANNEL,
  15. UnfollowChannel,
  16. UnfollowChannelArgs,
  17. } from './queries/follows'
  18. import { ChannelFollowsInfo } from '../src/entities/ChannelFollowsInfo'
  19. import { ChannelEventsBucketModel } from '../src/models/ChannelEvent'
  20. import { TEST_BUCKET_SIZE } from './setup'
  21. const FIRST_CHANNEL_ID = '22'
  22. const SECOND_CHANNEL_ID = '23'
  23. describe('Channel follows resolver', () => {
  24. let server: ApolloServer
  25. let mongoose: Mongoose
  26. let aggregates: Aggregates
  27. let query: ApolloServerTestClient['query']
  28. let mutate: ApolloServerTestClient['mutate']
  29. beforeEach(async () => {
  30. mongoose = await connectMongoose(process.env.MONGO_URL!)
  31. aggregates = await buildAggregates()
  32. server = await createServer(mongoose, aggregates)
  33. const testClient = createTestClient(server)
  34. query = testClient.query
  35. mutate = testClient.mutate
  36. })
  37. afterEach(async () => {
  38. await server.stop()
  39. await ChannelEventsBucketModel.deleteMany({})
  40. await mongoose.disconnect()
  41. })
  42. const followChannel = async (channelId: string) => {
  43. const followChannelResponse = await mutate<FollowChannel, FollowChannelArgs>({
  44. mutation: FOLLOW_CHANNEL,
  45. variables: { channelId },
  46. })
  47. expect(followChannelResponse.errors).toBeUndefined()
  48. return followChannelResponse.data?.followChannel
  49. }
  50. const unfollowChannel = async (channelId: string) => {
  51. const unfollowChannelResponse = await mutate<UnfollowChannel, UnfollowChannelArgs>({
  52. mutation: UNFOLLOW_CHANNEL,
  53. variables: { channelId },
  54. })
  55. expect(unfollowChannelResponse.errors).toBeUndefined()
  56. return unfollowChannelResponse.data?.unfollowChannel
  57. }
  58. const getChannelFollows = async (channelId: string) => {
  59. const channelFollowsResponse = await query<GetChannelFollows, GetChannelFollowsArgs>({
  60. query: GET_CHANNEL_FOLLOWS,
  61. variables: { channelId },
  62. })
  63. expect(channelFollowsResponse.errors).toBeUndefined()
  64. return channelFollowsResponse.data?.channelFollows
  65. }
  66. it('should return null for unknown channel follows', async () => {
  67. const channelFollows = await getChannelFollows(FIRST_CHANNEL_ID)
  68. expect(channelFollows).toBeNull()
  69. })
  70. it('should properly handle channel follow', async () => {
  71. const expectedChannelFollows: ChannelFollowsInfo = {
  72. id: FIRST_CHANNEL_ID,
  73. follows: 1,
  74. }
  75. let addChannelFollowData = await followChannel(FIRST_CHANNEL_ID)
  76. expect(addChannelFollowData).toEqual(expectedChannelFollows)
  77. let channelFollows = await getChannelFollows(FIRST_CHANNEL_ID)
  78. expect(channelFollows).toEqual(expectedChannelFollows)
  79. expectedChannelFollows.follows++
  80. addChannelFollowData = await followChannel(FIRST_CHANNEL_ID)
  81. expect(addChannelFollowData).toEqual(expectedChannelFollows)
  82. channelFollows = await getChannelFollows(FIRST_CHANNEL_ID)
  83. expect(channelFollows).toEqual(expectedChannelFollows)
  84. })
  85. it('should properly handle channel unfollow', async () => {
  86. const expectedChannelFollows: ChannelFollowsInfo = {
  87. id: FIRST_CHANNEL_ID,
  88. follows: 5,
  89. }
  90. await followChannel(FIRST_CHANNEL_ID)
  91. await followChannel(FIRST_CHANNEL_ID)
  92. await followChannel(FIRST_CHANNEL_ID)
  93. await followChannel(FIRST_CHANNEL_ID)
  94. await followChannel(FIRST_CHANNEL_ID)
  95. let channelFollows = await getChannelFollows(FIRST_CHANNEL_ID)
  96. expect(channelFollows).toEqual(expectedChannelFollows)
  97. expectedChannelFollows.follows--
  98. const unfollowChannelData = await unfollowChannel(FIRST_CHANNEL_ID)
  99. expect(unfollowChannelData).toEqual(expectedChannelFollows)
  100. channelFollows = await getChannelFollows(FIRST_CHANNEL_ID)
  101. expect(channelFollows).toEqual(expectedChannelFollows)
  102. })
  103. it('should keep the channel follows non-negative', async () => {
  104. const expectedChannelFollows: ChannelFollowsInfo = {
  105. id: FIRST_CHANNEL_ID,
  106. follows: 0,
  107. }
  108. await followChannel(FIRST_CHANNEL_ID)
  109. await followChannel(FIRST_CHANNEL_ID)
  110. await unfollowChannel(FIRST_CHANNEL_ID)
  111. await unfollowChannel(FIRST_CHANNEL_ID)
  112. await unfollowChannel(FIRST_CHANNEL_ID)
  113. const channelFollows = await getChannelFollows(FIRST_CHANNEL_ID)
  114. expect(channelFollows).toEqual(expectedChannelFollows)
  115. })
  116. it('should distinct follows of separate channels', async () => {
  117. const expectedFirstChannelFollows: ChannelFollowsInfo = {
  118. id: FIRST_CHANNEL_ID,
  119. follows: 1,
  120. }
  121. const expectedSecondChannelFollows: ChannelFollowsInfo = {
  122. id: SECOND_CHANNEL_ID,
  123. follows: 1,
  124. }
  125. const firstChannelFollowData = await followChannel(FIRST_CHANNEL_ID)
  126. const secondChannelFollowData = await followChannel(SECOND_CHANNEL_ID)
  127. expect(firstChannelFollowData).toEqual(expectedFirstChannelFollows)
  128. expect(secondChannelFollowData).toEqual(expectedSecondChannelFollows)
  129. expectedFirstChannelFollows.follows++
  130. await followChannel(FIRST_CHANNEL_ID)
  131. const firstChannelFollows = await getChannelFollows(FIRST_CHANNEL_ID)
  132. const secondChannelFollows = await getChannelFollows(SECOND_CHANNEL_ID)
  133. expect(firstChannelFollows).toEqual(expectedFirstChannelFollows)
  134. expect(secondChannelFollows).toEqual(expectedSecondChannelFollows)
  135. })
  136. it('should properly rebuild the aggregate', async () => {
  137. const expectedFirstChannelFollows: ChannelFollowsInfo = {
  138. id: FIRST_CHANNEL_ID,
  139. follows: 3,
  140. }
  141. const expectedSecondChannelFollows: ChannelFollowsInfo = {
  142. id: SECOND_CHANNEL_ID,
  143. follows: 4,
  144. }
  145. const checkFollows = async () => {
  146. const firstChannelFollows = await getChannelFollows(FIRST_CHANNEL_ID)
  147. const secondChannelFollows = await getChannelFollows(SECOND_CHANNEL_ID)
  148. expect(firstChannelFollows).toEqual(expectedFirstChannelFollows)
  149. expect(secondChannelFollows).toEqual(expectedSecondChannelFollows)
  150. }
  151. await followChannel(FIRST_CHANNEL_ID)
  152. await followChannel(FIRST_CHANNEL_ID)
  153. await followChannel(FIRST_CHANNEL_ID)
  154. await followChannel(SECOND_CHANNEL_ID)
  155. await followChannel(SECOND_CHANNEL_ID)
  156. await followChannel(SECOND_CHANNEL_ID)
  157. await followChannel(SECOND_CHANNEL_ID)
  158. await followChannel(SECOND_CHANNEL_ID)
  159. await unfollowChannel(SECOND_CHANNEL_ID)
  160. await checkFollows()
  161. await server.stop()
  162. aggregates = await buildAggregates()
  163. server = await createServer(mongoose, aggregates)
  164. const testClient = createTestClient(server)
  165. query = testClient.query
  166. mutate = testClient.mutate
  167. await checkFollows()
  168. })
  169. it('should properly handle saving events across buckets', async () => {
  170. const eventsCount = TEST_BUCKET_SIZE * 2 + 1
  171. const expectedChannelFollows: ChannelFollowsInfo = {
  172. id: FIRST_CHANNEL_ID,
  173. follows: eventsCount,
  174. }
  175. for (let i = 0; i < eventsCount; i++) {
  176. await followChannel(FIRST_CHANNEL_ID)
  177. }
  178. const channelFollows = await getChannelFollows(FIRST_CHANNEL_ID)
  179. expect(channelFollows).toEqual(expectedChannelFollows)
  180. })
  181. })