SplitTestSessionHandlerTests.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. const Path = require('path')
  2. const SandboxedModule = require('sandboxed-module')
  3. const sinon = require('sinon')
  4. const { expect } = require('chai')
  5. const MODULE_PATH = Path.join(
  6. __dirname,
  7. '../../../../app/src/Features/SplitTests/SplitTestSessionHandler'
  8. )
  9. describe('SplitTestSessionHandler', function () {
  10. beforeEach(function () {
  11. this.SplitTestCache = {
  12. get: sinon.stub().resolves(),
  13. }
  14. this.SplitTestUserGetter = {}
  15. this.Metrics = {}
  16. this.SplitTestSessionHandler = SandboxedModule.require(MODULE_PATH, {
  17. requires: {
  18. './SplitTestCache': this.SplitTestCache,
  19. './SplitTestUserGetter': this.SplitTestUserGetter,
  20. '@overleaf/metrics': this.Metrics,
  21. },
  22. })
  23. })
  24. it('should read from the splitTests field', async function () {
  25. const session = {
  26. splitTests: {
  27. 'anon-test-1': [
  28. {
  29. variantName: 'default',
  30. versionNumber: 1,
  31. phase: 'release',
  32. assignedAt: new Date(1712872800000), // 2024-04-11 22:00:00
  33. },
  34. ],
  35. 'anon-test-2': [
  36. {
  37. variantName: 'default',
  38. versionNumber: 1,
  39. phase: 'release',
  40. assignedAt: new Date(1712307600000), // 2024-04-05 09:00:00
  41. },
  42. {
  43. variantName: 'v-2',
  44. versionNumber: 2,
  45. phase: 'release',
  46. assignedAt: new Date(1712581200000), // 2024-04-08 13:00:00
  47. },
  48. ],
  49. },
  50. sta: ``,
  51. }
  52. const assignments =
  53. await this.SplitTestSessionHandler.promises.getAssignments(session)
  54. expect(assignments).to.deep.equal({
  55. 'anon-test-1': [
  56. {
  57. variantName: 'default',
  58. versionNumber: 1,
  59. phase: 'release',
  60. assignedAt: new Date(1712872800000),
  61. },
  62. ],
  63. 'anon-test-2': [
  64. {
  65. variantName: 'default',
  66. versionNumber: 1,
  67. phase: 'release',
  68. assignedAt: new Date(1712307600000),
  69. },
  70. {
  71. variantName: 'v-2',
  72. versionNumber: 2,
  73. phase: 'release',
  74. assignedAt: new Date(1712581200000),
  75. },
  76. ],
  77. })
  78. })
  79. it('should not read from the sta field', async function () {
  80. this.SplitTestCache.get = sinon.stub().resolves(
  81. new Map(
  82. Object.entries({
  83. 'anon-test-1': {
  84. _id: '661f92a4669764bb03f73e37',
  85. name: 'anon-test-1',
  86. versions: [
  87. {
  88. versionNumber: 1,
  89. variants: [
  90. {
  91. name: 'enabled',
  92. },
  93. ],
  94. },
  95. ],
  96. },
  97. 'anon-test-2': {
  98. _id: '661f92a9d68ea711d6bf2df4',
  99. name: 'anon-test-2',
  100. versions: [
  101. {
  102. versionNumber: 1,
  103. variants: [
  104. {
  105. name: 'v-1',
  106. },
  107. {
  108. name: 'v-2',
  109. },
  110. ],
  111. },
  112. ],
  113. },
  114. })
  115. )
  116. )
  117. const session = {
  118. sta: `Zh+SpGaXZLsD9z43_1=d:sbrvs0;Zh+SqdaOpxHWvy30_1=d:sbtqg0;Zh+SqdaOpxHWvy30_2=1:sbsi00`,
  119. }
  120. const assignments =
  121. await this.SplitTestSessionHandler.promises.getAssignments(session)
  122. expect(assignments).to.deep.equal({
  123. 'anon-test-1': [
  124. {
  125. variantName: 'default',
  126. versionNumber: 1,
  127. phase: 'release',
  128. assignedAt: new Date(1712829600000),
  129. },
  130. ],
  131. 'anon-test-2': [
  132. {
  133. variantName: 'default',
  134. versionNumber: 1,
  135. phase: 'release',
  136. assignedAt: new Date(1712916000000),
  137. },
  138. {
  139. variantName: 'v-2',
  140. versionNumber: 2,
  141. phase: 'release',
  142. assignedAt: new Date(1712858400000),
  143. },
  144. ],
  145. })
  146. })
  147. it('should merge assignments from both splitTests and sta fields', async function () {
  148. this.SplitTestCache.get = sinon.stub().resolves(
  149. new Map(
  150. Object.entries({
  151. 'anon-test-1': {
  152. _id: '661f92a4669764bb03f73e37',
  153. name: 'anon-test-1',
  154. versions: [
  155. {
  156. versionNumber: 1,
  157. variants: [
  158. {
  159. name: 'enabled',
  160. },
  161. ],
  162. },
  163. ],
  164. },
  165. 'anon-test-2': {
  166. _id: '661f92a9d68ea711d6bf2df4',
  167. name: 'anon-test-2',
  168. versions: [
  169. {
  170. versionNumber: 1,
  171. variants: [
  172. {
  173. name: 'v-1',
  174. },
  175. {
  176. name: 'v-2',
  177. },
  178. ],
  179. },
  180. ],
  181. },
  182. })
  183. )
  184. )
  185. const session = {
  186. splitTests: {
  187. 'anon-test-1': [
  188. {
  189. variantName: 'default',
  190. versionNumber: 1,
  191. phase: 'release',
  192. assignedAt: new Date(1712872800000),
  193. },
  194. ],
  195. 'anon-test-2': [
  196. {
  197. variantName: 'default',
  198. versionNumber: 1,
  199. phase: 'release',
  200. assignedAt: new Date(1712307600000),
  201. },
  202. ],
  203. },
  204. sta: `Zh+SqdaOpxHWvy30_2=1:sbsi00`,
  205. }
  206. const assignments =
  207. await this.SplitTestSessionHandler.promises.getAssignments(session)
  208. expect(assignments).to.deep.equal({
  209. 'anon-test-1': [
  210. {
  211. variantName: 'default',
  212. versionNumber: 1,
  213. phase: 'release',
  214. assignedAt: new Date(1712872800000),
  215. },
  216. ],
  217. 'anon-test-2': [
  218. {
  219. variantName: 'default',
  220. versionNumber: 1,
  221. phase: 'release',
  222. assignedAt: new Date(1712307600000),
  223. },
  224. {
  225. variantName: 'v-2',
  226. versionNumber: 2,
  227. phase: 'release',
  228. assignedAt: new Date(1712858400000),
  229. },
  230. ],
  231. })
  232. })
  233. })