@genspectrum/dashboard-components 1.12.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +0 -7
  2. package/custom-elements.json +6 -25
  3. package/dist/components.d.ts +30 -36
  4. package/dist/components.js +943 -757
  5. package/dist/components.js.map +1 -1
  6. package/dist/util.d.ts +46 -30
  7. package/package.json +1 -5
  8. package/src/lapisApi/lapisApi.ts +21 -1
  9. package/src/lapisApi/lapisTypes.ts +36 -0
  10. package/src/preact/components/annotated-mutation.tsx +2 -2
  11. package/src/preact/{mutationsOverTime/mutations-over-time-grid.tsx → components/features-over-time-grid.tsx} +45 -52
  12. package/src/preact/genomeViewer/genome-data-viewer.tsx +2 -2
  13. package/src/preact/mutationsOverTime/MutationOverTimeData.ts +6 -4
  14. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay/aminoAcidMutations.json +5482 -0
  15. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay/aminoAcidMutationsOverTime.json +5496 -0
  16. package/src/preact/mutationsOverTime/__mockData__/byWeek/mutationsOverTime.json +7100 -0
  17. package/src/preact/mutationsOverTime/__mockData__/byWeek/nucleotideMutations.json +10122 -0
  18. package/src/preact/mutationsOverTime/__mockData__/defaultMockData/mutationsOverTime.json +12646 -0
  19. package/src/preact/mutationsOverTime/__mockData__/defaultMockData/nucleotideMutations.json +12632 -0
  20. package/src/preact/mutationsOverTime/__mockData__/request1800s/mutationsOverTime.json +16 -0
  21. package/src/preact/mutationsOverTime/__mockData__/request1800s/nucleotideMutations.json +11 -0
  22. package/src/preact/mutationsOverTime/__mockData__/withDisplayMutations/mutationsOverTime.json +52 -0
  23. package/src/preact/mutationsOverTime/getFilteredMutationsOverTime.spec.ts +3 -3
  24. package/src/preact/mutationsOverTime/mutations-over-time-grid-tooltip.tsx +3 -6
  25. package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +199 -12
  26. package/src/preact/mutationsOverTime/mutations-over-time.tsx +30 -35
  27. package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.tsx +30 -3
  28. package/src/query/queryDatesInDataset.ts +89 -0
  29. package/src/query/queryMutationsOverTime.spec.ts +526 -548
  30. package/src/query/queryMutationsOverTime.ts +21 -232
  31. package/src/query/queryQueriesOverTime.spec.ts +432 -0
  32. package/src/query/queryQueriesOverTime.ts +125 -0
  33. package/src/utilEntrypoint.ts +3 -1
  34. package/src/utils/mutations.spec.ts +6 -0
  35. package/src/utils/mutations.ts +1 -1
  36. package/src/utils/temporalClass.ts +4 -0
  37. package/src/web-components/visualization/gs-mutations-over-time.spec-d.ts +0 -3
  38. package/src/web-components/visualization/gs-mutations-over-time.stories.ts +283 -17
  39. package/src/web-components/visualization/gs-mutations-over-time.tsx +0 -9
  40. package/standalone-bundle/dashboard-components.js +8935 -8781
  41. package/standalone-bundle/dashboard-components.js.map +1 -1
  42. package/dist/assets/mutationOverTimeWorker-f8Kp0S6V.js.map +0 -1
  43. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay.ts +0 -47170
  44. package/src/preact/mutationsOverTime/__mockData__/byWeek.ts +0 -54026
  45. package/src/preact/mutationsOverTime/__mockData__/defaultMockData.ts +0 -108385
  46. package/src/preact/mutationsOverTime/__mockData__/mockConversion.ts +0 -54
  47. package/src/preact/mutationsOverTime/__mockData__/noDataWhenNoMutationsAreInFilter.ts +0 -23
  48. package/src/preact/mutationsOverTime/__mockData__/noDataWhenThereAreNoDatesInFilter.ts +0 -23
  49. package/src/preact/mutationsOverTime/__mockData__/showsMessageWhenTooManyMutations.ts +0 -65527
  50. package/src/preact/mutationsOverTime/__mockData__/withDisplayMutations.ts +0 -352
  51. package/src/preact/mutationsOverTime/__mockData__/withGaps.ts +0 -298
  52. package/src/preact/mutationsOverTime/mutationOverTimeWorker.mock.ts +0 -33
  53. package/src/preact/mutationsOverTime/mutationOverTimeWorker.ts +0 -29
  54. package/src/preact/webWorkers/useWebWorker.ts +0 -74
  55. package/src/preact/webWorkers/workerFunction.ts +0 -30
  56. package/src/query/queryMutationsOverTimeNewEndpoint.spec.ts +0 -988
  57. package/standalone-bundle/assets/mutationOverTimeWorker-AhhjjklP.js.map +0 -1
@@ -3,114 +3,104 @@ import { describe, expect, it } from 'vitest';
3
3
  import { queryMutationsOverTimeData } from './queryMutationsOverTime';
4
4
  import { DUMMY_LAPIS_URL, lapisRequestMocks } from '../../vitest.setup';
5
5
 
6
- describe('queryMutationsOverTime', () => {
6
+ describe('queryMutationsOverTimeNewEndpoint', () => {
7
7
  it('should fetch for a filter without date and sort by mutation and date', async () => {
8
8
  const lapisFilter = { field1: 'value1', field2: 'value2' };
9
9
  const dateField = 'dateField';
10
10
 
11
- lapisRequestMocks.multipleAggregated([
11
+ lapisRequestMocks.aggregated(
12
+ { ...lapisFilter, fields: [dateField] },
12
13
  {
13
- body: { ...lapisFilter, fields: [dateField] },
14
- response: {
15
- data: [
16
- { count: 1, [dateField]: '2023-01-01' },
17
- { count: 2, [dateField]: '2023-01-03' },
18
- ],
19
- },
20
- },
21
- {
22
- body: {
23
- ...lapisFilter,
24
- dateFieldFrom: '2023-01-01',
25
- dateFieldTo: '2023-01-01',
26
- fields: [],
27
- },
28
- response: { data: [{ count: 11 }] },
29
- },
30
- {
31
- body: {
32
- ...lapisFilter,
33
- dateFieldFrom: '2023-01-02',
34
- dateFieldTo: '2023-01-02',
35
- fields: [],
36
- },
37
- response: { data: [{ count: 12 }] },
14
+ data: [
15
+ { count: 1, [dateField]: '2023-01-01' },
16
+ { count: 2, [dateField]: '2023-01-03' },
17
+ ],
38
18
  },
39
- {
40
- body: {
41
- ...lapisFilter,
42
- dateFieldFrom: '2023-01-03',
43
- dateFieldTo: '2023-01-03',
44
- fields: [],
45
- },
46
- response: { data: [{ count: 13 }] },
47
- },
48
- ]);
49
-
19
+ );
50
20
  lapisRequestMocks.multipleMutations(
51
21
  [
52
22
  {
53
23
  body: {
54
24
  ...lapisFilter,
55
25
  dateFieldFrom: '2023-01-01',
56
- dateFieldTo: '2023-01-01',
57
- minProportion: 0.001,
58
- },
59
- response: { data: [getSomeTestMutation(0.1, 1), getSomeOtherTestMutation(0.4, 4)] },
60
- },
61
- {
62
- body: {
63
- ...lapisFilter,
64
- dateFieldFrom: '2023-01-02',
65
- dateFieldTo: '2023-01-02',
66
- minProportion: 0.001,
67
- },
68
- response: { data: [getSomeTestMutation(0.2, 2)] },
69
- },
70
- {
71
- body: {
72
- ...lapisFilter,
73
- dateFieldFrom: '2023-01-03',
74
26
  dateFieldTo: '2023-01-03',
75
27
  minProportion: 0.001,
76
28
  },
77
- response: { data: [getSomeTestMutation(0.3, 3)] },
29
+ response: {
30
+ data: [getSomeTestMutation(0.21, 6), getSomeOtherTestMutation(0.22, 4)],
31
+ },
78
32
  },
33
+ ],
34
+ 'nucleotide',
35
+ );
36
+ const dateRanges = [
37
+ {
38
+ dateFrom: '2023-01-01',
39
+ dateTo: '2023-01-01',
40
+ },
41
+ {
42
+ dateFrom: '2023-01-02',
43
+ dateTo: '2023-01-02',
44
+ },
45
+ {
46
+ dateFrom: '2023-01-03',
47
+ dateTo: '2023-01-03',
48
+ },
49
+ ];
50
+ lapisRequestMocks.mutationsOverTime(
51
+ [
79
52
  {
80
53
  body: {
81
- ...lapisFilter,
82
- dateFieldFrom: '2023-01-01',
83
- dateFieldTo: '2023-01-03',
84
- minProportion: 0.001,
54
+ filters: lapisFilter,
55
+ dateRanges,
56
+ includeMutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
57
+ dateField,
85
58
  },
86
59
  response: {
87
- data: [getSomeTestMutation(0.21, 6), getSomeOtherTestMutation(0.22, 4)],
60
+ data: {
61
+ data: [
62
+ [
63
+ { count: 4, coverage: 10 },
64
+ { count: 0, coverage: 10 },
65
+ { count: 0, coverage: 10 },
66
+ ],
67
+ [
68
+ { count: 1, coverage: 10 },
69
+ { count: 2, coverage: 10 },
70
+ { count: 3, coverage: 10 },
71
+ ],
72
+ ],
73
+ dateRanges,
74
+ mutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
75
+ totalCountsByDateRange: [11, 12, 13],
76
+ },
88
77
  },
89
78
  },
90
79
  ],
91
80
  'nucleotide',
92
81
  );
93
82
 
94
- const { mutationOverTimeData, overallMutationData } = await queryMutationsOverTimeData({
83
+ const { mutationOverTimeData, overallMutationData } = await queryMutationsOverTimeData(
95
84
  lapisFilter,
96
- sequenceType: 'nucleotide',
97
- lapis: DUMMY_LAPIS_URL,
98
- lapisDateField: dateField,
99
- granularity: 'day',
100
- });
85
+ 'nucleotide',
86
+ DUMMY_LAPIS_URL,
87
+ dateField,
88
+ 'day',
89
+ );
101
90
 
102
- expect(mutationOverTimeData.getAsArray()).to.deep.equal([
91
+ const expectedData = [
103
92
  [
104
- { type: 'value', proportion: 0.4, count: 4, totalCount: 11 },
105
- { type: 'belowThreshold', totalCount: 12 },
106
- { type: 'belowThreshold', totalCount: 13 },
93
+ { type: 'valueWithCoverage', count: 4, coverage: 10, totalCount: 11 },
94
+ { type: 'valueWithCoverage', count: 0, coverage: 10, totalCount: 12 },
95
+ { type: 'valueWithCoverage', count: 0, coverage: 10, totalCount: 13 },
107
96
  ],
108
97
  [
109
- { type: 'value', proportion: 0.1, count: 1, totalCount: 11 },
110
- { type: 'value', proportion: 0.2, count: 2, totalCount: 12 },
111
- { type: 'value', proportion: 0.3, count: 3, totalCount: 13 },
98
+ { type: 'valueWithCoverage', count: 1, coverage: 10, totalCount: 11 },
99
+ { type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 12 },
100
+ { type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 13 },
112
101
  ],
113
- ]);
102
+ ];
103
+ expect(mutationOverTimeData.getAsArray()).to.deep.equal(expectedData);
114
104
 
115
105
  const sequences = mutationOverTimeData.getFirstAxisKeys();
116
106
  expect(sequences[0].code).toBe('otherSequenceName:G234C');
@@ -155,44 +145,15 @@ describe('queryMutationsOverTime', () => {
155
145
  const lapisFilter = { field1: 'value1', field2: 'value2' };
156
146
  const dateField = 'dateField';
157
147
 
158
- lapisRequestMocks.multipleAggregated([
148
+ lapisRequestMocks.aggregated(
149
+ { ...lapisFilter, fields: [dateField] },
159
150
  {
160
- body: { ...lapisFilter, fields: [dateField] },
161
- response: {
162
- data: [
163
- { count: 1, [dateField]: '2023-01-01' },
164
- { count: 2, [dateField]: '2023-01-03' },
165
- ],
166
- },
151
+ data: [
152
+ { count: 1, [dateField]: '2023-01-01' },
153
+ { count: 2, [dateField]: '2023-01-03' },
154
+ ],
167
155
  },
168
- {
169
- body: {
170
- ...lapisFilter,
171
- dateFieldFrom: '2023-01-01',
172
- dateFieldTo: '2023-01-01',
173
- fields: [],
174
- },
175
- response: { data: [{ count: 11 }] },
176
- },
177
- {
178
- body: {
179
- ...lapisFilter,
180
- dateFieldFrom: '2023-01-02',
181
- dateFieldTo: '2023-01-02',
182
- fields: [],
183
- },
184
- response: { data: [{ count: 0 }] },
185
- },
186
- {
187
- body: {
188
- ...lapisFilter,
189
- dateFieldFrom: '2023-01-03',
190
- dateFieldTo: '2023-01-03',
191
- fields: [],
192
- },
193
- response: { data: [{ count: 13 }] },
194
- },
195
- ]);
156
+ );
196
157
 
197
158
  lapisRequestMocks.multipleMutations(
198
159
  [
@@ -200,67 +161,86 @@ describe('queryMutationsOverTime', () => {
200
161
  body: {
201
162
  ...lapisFilter,
202
163
  dateFieldFrom: '2023-01-01',
203
- dateFieldTo: '2023-01-01',
204
- minProportion: 0.001,
205
- },
206
- response: { data: [getSomeTestMutation(0.1, 1), getSomeOtherTestMutation(0.4, 4)] },
207
- },
208
- {
209
- body: {
210
- ...lapisFilter,
211
- dateFieldFrom: '2023-01-02',
212
- dateFieldTo: '2023-01-02',
213
- minProportion: 0.001,
214
- },
215
- response: { data: [] },
216
- },
217
- {
218
- body: {
219
- ...lapisFilter,
220
- dateFieldFrom: '2023-01-03',
221
164
  dateFieldTo: '2023-01-03',
222
165
  minProportion: 0.001,
223
166
  },
224
- response: { data: [getSomeTestMutation(0.3, 3)] },
167
+ response: {
168
+ data: [getSomeTestMutation(0.2, 4), getSomeOtherTestMutation(0.4, 4)],
169
+ },
225
170
  },
171
+ ],
172
+ 'nucleotide',
173
+ );
174
+
175
+ const dateRanges = [
176
+ {
177
+ dateFrom: '2023-01-01',
178
+ dateTo: '2023-01-01',
179
+ },
180
+ {
181
+ dateFrom: '2023-01-02',
182
+ dateTo: '2023-01-02',
183
+ },
184
+ {
185
+ dateFrom: '2023-01-03',
186
+ dateTo: '2023-01-03',
187
+ },
188
+ ];
189
+
190
+ lapisRequestMocks.mutationsOverTime(
191
+ [
226
192
  {
227
193
  body: {
228
- ...lapisFilter,
229
- dateFieldFrom: '2023-01-01',
230
- dateFieldTo: '2023-01-03',
231
- minProportion: 0.001,
194
+ filters: lapisFilter,
195
+ dateRanges,
196
+ includeMutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
197
+ dateField,
232
198
  },
233
199
  response: {
234
- data: [getSomeTestMutation(0.2, 4), getSomeOtherTestMutation(0.4, 4)],
200
+ data: {
201
+ data: [
202
+ [
203
+ { count: 4, coverage: 10 },
204
+ { count: 0, coverage: 10 },
205
+ { count: 0, coverage: 10 },
206
+ ],
207
+ [
208
+ { count: 1, coverage: 10 },
209
+ { count: 0, coverage: 10 },
210
+ { count: 3, coverage: 10 },
211
+ ],
212
+ ],
213
+ dateRanges,
214
+ mutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
215
+ totalCountsByDateRange: [11, 0, 13],
216
+ },
235
217
  },
236
218
  },
237
219
  ],
238
220
  'nucleotide',
239
221
  );
240
222
 
241
- const { mutationOverTimeData, overallMutationData } = await queryMutationsOverTimeData({
223
+ const { mutationOverTimeData } = await queryMutationsOverTimeData(
242
224
  lapisFilter,
243
- sequenceType: 'nucleotide',
244
- lapis: DUMMY_LAPIS_URL,
245
- lapisDateField: dateField,
246
- granularity: 'day',
247
- });
225
+ 'nucleotide',
226
+ DUMMY_LAPIS_URL,
227
+ dateField,
228
+ 'day',
229
+ );
248
230
 
249
231
  expect(mutationOverTimeData.getAsArray()).to.deep.equal([
250
232
  [
251
- { type: 'value', proportion: 0.4, count: 4, totalCount: 11 },
233
+ { type: 'valueWithCoverage', count: 4, coverage: 10, totalCount: 11 },
252
234
  null,
253
- { type: 'belowThreshold', totalCount: 13 },
235
+ { type: 'valueWithCoverage', count: 0, coverage: 10, totalCount: 13 },
254
236
  ],
255
237
  [
256
- { type: 'value', proportion: 0.1, count: 1, totalCount: 11 },
238
+ { type: 'valueWithCoverage', count: 1, coverage: 10, totalCount: 11 },
257
239
  null,
258
- { type: 'value', proportion: 0.3, count: 3, totalCount: 13 },
240
+ { type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 13 },
259
241
  ],
260
242
  ]);
261
243
 
262
- expect(overallMutationData.length).toBe(2);
263
-
264
244
  const sequences = mutationOverTimeData.getFirstAxisKeys();
265
245
  expect(sequences[0].code).toBe('otherSequenceName:G234C');
266
246
  expect(sequences[1].code).toBe('sequenceName:A123T');
@@ -275,44 +255,15 @@ describe('queryMutationsOverTime', () => {
275
255
  const lapisFilter = { field1: 'value1', field2: 'value2' };
276
256
  const dateField = 'dateField';
277
257
 
278
- lapisRequestMocks.multipleAggregated([
258
+ lapisRequestMocks.aggregated(
259
+ { ...lapisFilter, fields: [dateField] },
279
260
  {
280
- body: { ...lapisFilter, fields: [dateField] },
281
- response: {
282
- data: [
283
- { count: 1, [dateField]: '2023-01-01' },
284
- { count: 2, [dateField]: '2023-01-03' },
285
- ],
286
- },
261
+ data: [
262
+ { count: 1, [dateField]: '2023-01-01' },
263
+ { count: 2, [dateField]: '2023-01-03' },
264
+ ],
287
265
  },
288
- {
289
- body: {
290
- ...lapisFilter,
291
- dateFieldFrom: '2023-01-01',
292
- dateFieldTo: '2023-01-01',
293
- fields: [],
294
- },
295
- response: { data: [{ count: 11 }] },
296
- },
297
- {
298
- body: {
299
- ...lapisFilter,
300
- dateFieldFrom: '2023-01-02',
301
- dateFieldTo: '2023-01-02',
302
- fields: [],
303
- },
304
- response: { data: [{ count: 12 }] },
305
- },
306
- {
307
- body: {
308
- ...lapisFilter,
309
- dateFieldFrom: '2023-01-03',
310
- dateFieldTo: '2023-01-03',
311
- fields: [],
312
- },
313
- response: { data: [{ count: 13 }] },
314
- },
315
- ]);
266
+ );
316
267
 
317
268
  lapisRequestMocks.multipleMutations(
318
269
  [
@@ -320,90 +271,84 @@ describe('queryMutationsOverTime', () => {
320
271
  body: {
321
272
  ...lapisFilter,
322
273
  dateFieldFrom: '2023-01-01',
323
- dateFieldTo: '2023-01-01',
324
- minProportion: 0.001,
325
- },
326
- response: { data: [] },
327
- },
328
- {
329
- body: {
330
- ...lapisFilter,
331
- dateFieldFrom: '2023-01-02',
332
- dateFieldTo: '2023-01-02',
333
- minProportion: 0.001,
334
- },
335
- response: { data: [] },
336
- },
337
- {
338
- body: {
339
- ...lapisFilter,
340
- dateFieldFrom: '2023-01-03',
341
274
  dateFieldTo: '2023-01-03',
342
275
  minProportion: 0.001,
343
276
  },
344
- response: { data: [] },
277
+ response: {
278
+ data: [],
279
+ },
345
280
  },
281
+ ],
282
+ 'nucleotide',
283
+ );
284
+
285
+ const dateRanges = [
286
+ {
287
+ dateFrom: '2023-01-01',
288
+ dateTo: '2023-01-01',
289
+ },
290
+ {
291
+ dateFrom: '2023-01-02',
292
+ dateTo: '2023-01-02',
293
+ },
294
+ {
295
+ dateFrom: '2023-01-03',
296
+ dateTo: '2023-01-03',
297
+ },
298
+ ];
299
+
300
+ lapisRequestMocks.mutationsOverTime(
301
+ [
346
302
  {
347
303
  body: {
348
- ...lapisFilter,
349
- dateFieldFrom: '2023-01-01',
350
- dateFieldTo: '2023-01-03',
351
- minProportion: 0.001,
304
+ filters: lapisFilter,
305
+ dateRanges,
306
+ includeMutations: [],
307
+ dateField,
352
308
  },
353
309
  response: {
354
- data: [],
310
+ data: {
311
+ data: [],
312
+ dateRanges,
313
+ mutations: [],
314
+ totalCountsByDateRange: [],
315
+ },
355
316
  },
356
317
  },
357
318
  ],
358
319
  'nucleotide',
359
320
  );
360
321
 
361
- const { mutationOverTimeData } = await queryMutationsOverTimeData({
322
+ const { mutationOverTimeData } = await queryMutationsOverTimeData(
362
323
  lapisFilter,
363
- sequenceType: 'nucleotide',
364
- lapis: DUMMY_LAPIS_URL,
365
- lapisDateField: dateField,
366
- granularity: 'day',
367
- });
324
+ 'nucleotide',
325
+ DUMMY_LAPIS_URL,
326
+ dateField,
327
+ 'day',
328
+ );
368
329
 
369
330
  expect(mutationOverTimeData.getAsArray()).to.deep.equal([]);
370
331
  expect(mutationOverTimeData.getFirstAxisKeys()).to.deep.equal([]);
371
- expect(mutationOverTimeData.getSecondAxisKeys()).to.deep.equal([]);
332
+ const dates = mutationOverTimeData.getSecondAxisKeys();
333
+ expect(dates.length).toBe(3);
334
+ expect(dates[0].dateString).toBe('2023-01-01');
335
+ expect(dates[1].dateString).toBe('2023-01-02');
336
+ expect(dates[2].dateString).toBe('2023-01-03');
372
337
  });
373
338
 
374
339
  it('should use dateFrom from filter', async () => {
375
340
  const dateField = 'dateField';
376
341
  const lapisFilter = { field1: 'value1', field2: 'value2', [`${dateField}From`]: '2023-01-02' };
377
342
 
378
- lapisRequestMocks.multipleAggregated([
343
+ lapisRequestMocks.aggregated(
344
+ { ...lapisFilter, fields: [dateField] },
379
345
  {
380
- body: { ...lapisFilter, fields: [dateField] },
381
- response: {
382
- data: [
383
- { count: 1, [dateField]: '2023-01-01' },
384
- { count: 2, [dateField]: '2023-01-03' },
385
- ],
386
- },
387
- },
388
- {
389
- body: {
390
- ...lapisFilter,
391
- dateFieldFrom: '2023-01-02',
392
- dateFieldTo: '2023-01-02',
393
- fields: [],
394
- },
395
- response: { data: [{ count: 11 }] },
346
+ data: [
347
+ { count: 1, [dateField]: '2023-01-01' },
348
+ { count: 2, [dateField]: '2023-01-03' },
349
+ ],
396
350
  },
397
- {
398
- body: {
399
- ...lapisFilter,
400
- dateFieldFrom: '2023-01-03',
401
- dateFieldTo: '2023-01-03',
402
- fields: [],
403
- },
404
- response: { data: [{ count: 12 }] },
405
- },
406
- ]);
351
+ );
407
352
 
408
353
  lapisRequestMocks.multipleMutations(
409
354
  [
@@ -411,49 +356,67 @@ describe('queryMutationsOverTime', () => {
411
356
  body: {
412
357
  ...lapisFilter,
413
358
  dateFieldFrom: '2023-01-02',
414
- dateFieldTo: '2023-01-02',
415
- minProportion: 0.001,
416
- },
417
- response: { data: [getSomeTestMutation(0.2, 2)] },
418
- },
419
- {
420
- body: {
421
- ...lapisFilter,
422
- dateFieldFrom: '2023-01-03',
423
359
  dateFieldTo: '2023-01-03',
424
360
  minProportion: 0.001,
425
361
  },
426
- response: { data: [getSomeTestMutation(0.3, 3)] },
362
+ response: {
363
+ data: [getSomeTestMutation(0.25, 5)],
364
+ },
427
365
  },
366
+ ],
367
+ 'nucleotide',
368
+ );
369
+
370
+ const dateRanges = [
371
+ {
372
+ dateFrom: '2023-01-02',
373
+ dateTo: '2023-01-02',
374
+ },
375
+ {
376
+ dateFrom: '2023-01-03',
377
+ dateTo: '2023-01-03',
378
+ },
379
+ ];
380
+
381
+ lapisRequestMocks.mutationsOverTime(
382
+ [
428
383
  {
429
384
  body: {
430
- ...lapisFilter,
431
- dateFieldFrom: '2023-01-02',
432
- dateFieldTo: '2023-01-03',
433
- minProportion: 0.001,
385
+ filters: lapisFilter,
386
+ dateRanges,
387
+ includeMutations: ['sequenceName:A123T'],
388
+ dateField,
434
389
  },
435
390
  response: {
436
- data: [getSomeTestMutation(0.25, 5)],
391
+ data: {
392
+ data: [
393
+ [
394
+ { count: 2, coverage: 10 },
395
+ { count: 3, coverage: 10 },
396
+ ],
397
+ ],
398
+ dateRanges,
399
+ mutations: ['sequenceName:A123T'],
400
+ totalCountsByDateRange: [11, 12],
401
+ },
437
402
  },
438
403
  },
439
404
  ],
440
405
  'nucleotide',
441
406
  );
442
407
 
443
- const { mutationOverTimeData, overallMutationData } = await queryMutationsOverTimeData({
408
+ const { mutationOverTimeData } = await queryMutationsOverTimeData(
444
409
  lapisFilter,
445
- sequenceType: 'nucleotide',
446
- lapis: DUMMY_LAPIS_URL,
447
- lapisDateField: dateField,
448
- granularity: 'day',
449
- });
450
-
451
- expect(overallMutationData.length).toBe(1);
410
+ 'nucleotide',
411
+ DUMMY_LAPIS_URL,
412
+ dateField,
413
+ 'day',
414
+ );
452
415
 
453
416
  expect(mutationOverTimeData.getAsArray()).to.deep.equal([
454
417
  [
455
- { type: 'value', proportion: 0.2, count: 2, totalCount: 11 },
456
- { type: 'value', proportion: 0.3, count: 3, totalCount: 12 },
418
+ { type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 11 },
419
+ { type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 12 },
457
420
  ],
458
421
  ]);
459
422
 
@@ -469,35 +432,15 @@ describe('queryMutationsOverTime', () => {
469
432
  const dateField = 'dateField';
470
433
  const lapisFilter = { field1: 'value1', field2: 'value2', [`${dateField}To`]: '2023-01-02' };
471
434
 
472
- lapisRequestMocks.multipleAggregated([
473
- {
474
- body: { ...lapisFilter, fields: [dateField] },
475
- response: {
476
- data: [
477
- { count: 1, [dateField]: '2023-01-01' },
478
- { count: 2, [dateField]: '2023-01-03' },
479
- ],
480
- },
481
- },
482
- {
483
- body: {
484
- ...lapisFilter,
485
- dateFieldFrom: '2023-01-01',
486
- dateFieldTo: '2023-01-01',
487
- fields: [],
488
- },
489
- response: { data: [{ count: 11 }] },
490
- },
435
+ lapisRequestMocks.aggregated(
436
+ { ...lapisFilter, fields: [dateField] },
491
437
  {
492
- body: {
493
- ...lapisFilter,
494
- dateFieldFrom: '2023-01-02',
495
- dateFieldTo: '2023-01-02',
496
- fields: [],
497
- },
498
- response: { data: [{ count: 12 }] },
438
+ data: [
439
+ { count: 1, [dateField]: '2023-01-01' },
440
+ { count: 2, [dateField]: '2023-01-03' },
441
+ ],
499
442
  },
500
- ]);
443
+ );
501
444
 
502
445
  lapisRequestMocks.multipleMutations(
503
446
  [
@@ -505,47 +448,67 @@ describe('queryMutationsOverTime', () => {
505
448
  body: {
506
449
  ...lapisFilter,
507
450
  dateFieldFrom: '2023-01-01',
508
- dateFieldTo: '2023-01-01',
509
- minProportion: 0.001,
510
- },
511
- response: { data: [getSomeTestMutation(0.1, 1)] },
512
- },
513
- {
514
- body: {
515
- ...lapisFilter,
516
- dateFieldFrom: '2023-01-02',
517
451
  dateFieldTo: '2023-01-02',
518
452
  minProportion: 0.001,
519
453
  },
520
- response: { data: [getSomeTestMutation(0.2, 2)] },
454
+ response: {
455
+ data: [getSomeTestMutation(0.15, 3)],
456
+ },
521
457
  },
458
+ ],
459
+ 'nucleotide',
460
+ );
461
+
462
+ const dateRanges = [
463
+ {
464
+ dateFrom: '2023-01-01',
465
+ dateTo: '2023-01-01',
466
+ },
467
+ {
468
+ dateFrom: '2023-01-02',
469
+ dateTo: '2023-01-02',
470
+ },
471
+ ];
472
+
473
+ lapisRequestMocks.mutationsOverTime(
474
+ [
522
475
  {
523
476
  body: {
524
- ...lapisFilter,
525
- dateFieldFrom: '2023-01-01',
526
- dateFieldTo: '2023-01-02',
527
- minProportion: 0.001,
477
+ filters: lapisFilter,
478
+ dateRanges,
479
+ includeMutations: ['sequenceName:A123T'],
480
+ dateField,
528
481
  },
529
482
  response: {
530
- data: [getSomeTestMutation(0.15, 3)],
483
+ data: {
484
+ data: [
485
+ [
486
+ { count: 1, coverage: 10 },
487
+ { count: 2, coverage: 10 },
488
+ ],
489
+ ],
490
+ dateRanges,
491
+ mutations: ['sequenceName:A123T'],
492
+ totalCountsByDateRange: [11, 12],
493
+ },
531
494
  },
532
495
  },
533
496
  ],
534
497
  'nucleotide',
535
498
  );
536
499
 
537
- const { mutationOverTimeData } = await queryMutationsOverTimeData({
500
+ const { mutationOverTimeData } = await queryMutationsOverTimeData(
538
501
  lapisFilter,
539
- sequenceType: 'nucleotide',
540
- lapis: DUMMY_LAPIS_URL,
541
- lapisDateField: dateField,
542
- granularity: 'day',
543
- });
502
+ 'nucleotide',
503
+ DUMMY_LAPIS_URL,
504
+ dateField,
505
+ 'day',
506
+ );
544
507
 
545
508
  expect(mutationOverTimeData.getAsArray()).to.deep.equal([
546
509
  [
547
- { type: 'value', proportion: 0.1, count: 1, totalCount: 11 },
548
- { type: 'value', proportion: 0.2, count: 2, totalCount: 12 },
510
+ { type: 'valueWithCoverage', count: 1, coverage: 10, totalCount: 11 },
511
+ { type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 12 },
549
512
  ],
550
513
  ]);
551
514
 
@@ -561,26 +524,15 @@ describe('queryMutationsOverTime', () => {
561
524
  const dateField = 'dateField';
562
525
  const lapisFilter = { field1: 'value1', field2: 'value2', [dateField]: '2023-01-02' };
563
526
 
564
- lapisRequestMocks.multipleAggregated([
527
+ lapisRequestMocks.aggregated(
528
+ { ...lapisFilter, fields: [dateField] },
565
529
  {
566
- body: { ...lapisFilter, fields: [dateField] },
567
- response: {
568
- data: [
569
- { count: 1, [dateField]: '2023-01-01' },
570
- { count: 2, [dateField]: '2023-01-03' },
571
- ],
572
- },
530
+ data: [
531
+ { count: 1, [dateField]: '2023-01-01' },
532
+ { count: 2, [dateField]: '2023-01-03' },
533
+ ],
573
534
  },
574
- {
575
- body: {
576
- ...lapisFilter,
577
- dateFieldFrom: '2023-01-02',
578
- dateFieldTo: '2023-01-02',
579
- fields: [],
580
- },
581
- response: { data: [{ count: 11 }] },
582
- },
583
- ]);
535
+ );
584
536
 
585
537
  lapisRequestMocks.multipleMutations(
586
538
  [
@@ -597,16 +549,45 @@ describe('queryMutationsOverTime', () => {
597
549
  'nucleotide',
598
550
  );
599
551
 
600
- const { mutationOverTimeData } = await queryMutationsOverTimeData({
552
+ const dateRanges = [
553
+ {
554
+ dateFrom: '2023-01-02',
555
+ dateTo: '2023-01-02',
556
+ },
557
+ ];
558
+
559
+ lapisRequestMocks.mutationsOverTime(
560
+ [
561
+ {
562
+ body: {
563
+ filters: lapisFilter,
564
+ dateRanges,
565
+ includeMutations: ['sequenceName:A123T'],
566
+ dateField,
567
+ },
568
+ response: {
569
+ data: {
570
+ data: [[{ count: 2, coverage: 10 }]],
571
+ dateRanges,
572
+ mutations: ['sequenceName:A123T'],
573
+ totalCountsByDateRange: [11],
574
+ },
575
+ },
576
+ },
577
+ ],
578
+ 'nucleotide',
579
+ );
580
+
581
+ const { mutationOverTimeData } = await queryMutationsOverTimeData(
601
582
  lapisFilter,
602
- sequenceType: 'nucleotide',
603
- lapis: DUMMY_LAPIS_URL,
604
- lapisDateField: dateField,
605
- granularity: 'day',
606
- });
583
+ 'nucleotide',
584
+ DUMMY_LAPIS_URL,
585
+ dateField,
586
+ 'day',
587
+ );
607
588
 
608
589
  expect(mutationOverTimeData.getAsArray()).to.deep.equal([
609
- [{ type: 'value', proportion: 0.2, count: 2, totalCount: 11 }],
590
+ [{ type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 11 }],
610
591
  ]);
611
592
 
612
593
  const sequences = mutationOverTimeData.getFirstAxisKeys();
@@ -620,35 +601,15 @@ describe('queryMutationsOverTime', () => {
620
601
  const lapisFilter = { field1: 'value1', field2: 'value2' };
621
602
  const dateField = 'dateField';
622
603
 
623
- lapisRequestMocks.multipleAggregated([
604
+ lapisRequestMocks.aggregated(
605
+ { ...lapisFilter, fields: [dateField] },
624
606
  {
625
- body: { ...lapisFilter, fields: [dateField] },
626
- response: {
627
- data: [
628
- { count: 1, [dateField]: '2023-01-05' },
629
- { count: 2, [dateField]: '2023-02-15' },
630
- ],
631
- },
607
+ data: [
608
+ { count: 1, [dateField]: '2023-01-05' },
609
+ { count: 2, [dateField]: '2023-02-15' },
610
+ ],
632
611
  },
633
- {
634
- body: {
635
- ...lapisFilter,
636
- dateFieldFrom: '2023-01-01',
637
- dateFieldTo: '2023-01-31',
638
- fields: [],
639
- },
640
- response: { data: [{ count: 11 }] },
641
- },
642
- {
643
- body: {
644
- ...lapisFilter,
645
- dateFieldFrom: '2023-02-01',
646
- dateFieldTo: '2023-02-28',
647
- fields: [],
648
- },
649
- response: { data: [{ count: 12 }] },
650
- },
651
- ]);
612
+ );
652
613
 
653
614
  lapisRequestMocks.multipleMutations(
654
615
  [
@@ -656,51 +617,75 @@ describe('queryMutationsOverTime', () => {
656
617
  body: {
657
618
  ...lapisFilter,
658
619
  dateFieldFrom: '2023-01-01',
659
- dateFieldTo: '2023-01-31',
660
- minProportion: 0.001,
661
- },
662
- response: { data: [getSomeTestMutation(0.1, 1), getSomeOtherTestMutation(0.4, 4)] },
663
- },
664
- {
665
- body: {
666
- ...lapisFilter,
667
- dateFieldFrom: '2023-02-01',
668
620
  dateFieldTo: '2023-02-28',
669
621
  minProportion: 0.001,
670
622
  },
671
- response: { data: [getSomeTestMutation(0.2, 2)] },
623
+ response: {
624
+ data: [getSomeTestMutation(0.21, 6), getSomeOtherTestMutation(0.22, 4)],
625
+ },
672
626
  },
627
+ ],
628
+ 'nucleotide',
629
+ );
630
+
631
+ const dateRanges = [
632
+ {
633
+ dateFrom: '2023-01-01',
634
+ dateTo: '2023-01-31',
635
+ },
636
+ {
637
+ dateFrom: '2023-02-01',
638
+ dateTo: '2023-02-28',
639
+ },
640
+ ];
641
+
642
+ lapisRequestMocks.mutationsOverTime(
643
+ [
673
644
  {
674
645
  body: {
675
- ...lapisFilter,
676
- dateFieldFrom: '2023-01-01',
677
- dateFieldTo: '2023-02-28',
678
- minProportion: 0.001,
646
+ filters: lapisFilter,
647
+ dateRanges,
648
+ includeMutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
649
+ dateField,
679
650
  },
680
651
  response: {
681
- data: [getSomeTestMutation(0.21, 6), getSomeOtherTestMutation(0.22, 4)],
652
+ data: {
653
+ data: [
654
+ [
655
+ { count: 2, coverage: 10 },
656
+ { count: 3, coverage: 10 },
657
+ ],
658
+ [
659
+ { count: 4, coverage: 10 },
660
+ { count: 5, coverage: 10 },
661
+ ],
662
+ ],
663
+ dateRanges,
664
+ mutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
665
+ totalCountsByDateRange: [11, 12],
666
+ },
682
667
  },
683
668
  },
684
669
  ],
685
670
  'nucleotide',
686
671
  );
687
672
 
688
- const { mutationOverTimeData } = await queryMutationsOverTimeData({
673
+ const { mutationOverTimeData } = await queryMutationsOverTimeData(
689
674
  lapisFilter,
690
- sequenceType: 'nucleotide',
691
- lapis: DUMMY_LAPIS_URL,
692
- lapisDateField: dateField,
693
- granularity: 'month',
694
- });
675
+ 'nucleotide',
676
+ DUMMY_LAPIS_URL,
677
+ dateField,
678
+ 'month',
679
+ );
695
680
 
696
681
  expect(mutationOverTimeData.getAsArray()).to.deep.equal([
697
682
  [
698
- { type: 'value', proportion: 0.4, count: 4, totalCount: 11 },
699
- { type: 'belowThreshold', totalCount: 12 },
683
+ { type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 11 },
684
+ { type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 12 },
700
685
  ],
701
686
  [
702
- { type: 'value', proportion: 0.1, count: 1, totalCount: 11 },
703
- { type: 'value', proportion: 0.2, count: 2, totalCount: 12 },
687
+ { type: 'valueWithCoverage', count: 4, coverage: 10, totalCount: 11 },
688
+ { type: 'valueWithCoverage', count: 5, coverage: 10, totalCount: 12 },
704
689
  ],
705
690
  ]);
706
691
 
@@ -717,22 +702,42 @@ describe('queryMutationsOverTime', () => {
717
702
  const lapisFilter = { field1: 'value1', field2: 'value2' };
718
703
  const dateField = 'dateField';
719
704
 
720
- lapisRequestMocks.multipleAggregated([
705
+ lapisRequestMocks.aggregated(
706
+ { ...lapisFilter, fields: [dateField] },
721
707
  {
722
- body: { ...lapisFilter, fields: [dateField] },
723
- response: {
724
- data: [],
725
- },
708
+ data: [],
726
709
  },
727
- ]);
710
+ );
711
+
712
+ lapisRequestMocks.mutationsOverTime(
713
+ [
714
+ {
715
+ body: {
716
+ filters: lapisFilter,
717
+ dateRanges: [],
718
+ includeMutations: [],
719
+ dateField,
720
+ },
721
+ response: {
722
+ data: {
723
+ data: [],
724
+ dateRanges: [],
725
+ mutations: [],
726
+ totalCountsByDateRange: [],
727
+ },
728
+ },
729
+ },
730
+ ],
731
+ 'nucleotide',
732
+ );
728
733
 
729
- const { mutationOverTimeData } = await queryMutationsOverTimeData({
734
+ const { mutationOverTimeData } = await queryMutationsOverTimeData(
730
735
  lapisFilter,
731
- sequenceType: 'nucleotide',
732
- lapis: DUMMY_LAPIS_URL,
733
- lapisDateField: dateField,
734
- granularity: 'month',
735
- });
736
+ 'nucleotide',
737
+ DUMMY_LAPIS_URL,
738
+ dateField,
739
+ 'month',
740
+ );
736
741
 
737
742
  expect(mutationOverTimeData.getAsArray()).to.deep.equal([]);
738
743
 
@@ -743,39 +748,19 @@ describe('queryMutationsOverTime', () => {
743
748
  expect(dates.length).toBe(0);
744
749
  });
745
750
 
746
- it('should fill with "belowThreshold" if the mutation does not exist in a date range but count > 0', async () => {
751
+ it('should respect the includeMutations parameter', async () => {
747
752
  const lapisFilter = { field1: 'value1', field2: 'value2' };
748
753
  const dateField = 'dateField';
749
754
 
750
- lapisRequestMocks.multipleAggregated([
755
+ lapisRequestMocks.aggregated(
756
+ { ...lapisFilter, fields: [dateField] },
751
757
  {
752
- body: { ...lapisFilter, fields: [dateField] },
753
- response: {
754
- data: [
755
- { count: 1, [dateField]: '2023-01-01' },
756
- { count: 1, [dateField]: '2023-01-02' },
757
- ],
758
- },
759
- },
760
- {
761
- body: {
762
- ...lapisFilter,
763
- dateFieldFrom: '2023-01-01',
764
- dateFieldTo: '2023-01-01',
765
- fields: [],
766
- },
767
- response: { data: [{ count: 11 }] },
768
- },
769
- {
770
- body: {
771
- ...lapisFilter,
772
- dateFieldFrom: '2023-01-02',
773
- dateFieldTo: '2023-01-02',
774
- fields: [],
775
- },
776
- response: { data: [{ count: 11 }] },
758
+ data: [
759
+ { count: 1, [dateField]: '2023-01-05' },
760
+ { count: 2, [dateField]: '2023-02-15' },
761
+ ],
777
762
  },
778
- ]);
763
+ );
779
764
 
780
765
  lapisRequestMocks.multipleMutations(
781
766
  [
@@ -783,72 +768,101 @@ describe('queryMutationsOverTime', () => {
783
768
  body: {
784
769
  ...lapisFilter,
785
770
  dateFieldFrom: '2023-01-01',
786
- dateFieldTo: '2023-01-01',
771
+ dateFieldTo: '2023-02-28',
787
772
  minProportion: 0.001,
788
773
  },
789
- response: { data: [getSomeTestMutation(0.1, 1)] },
790
- },
791
- {
792
- body: {
793
- ...lapisFilter,
794
- dateFieldFrom: '2023-01-02',
795
- dateFieldTo: '2023-01-02',
796
- minProportion: 0.001,
774
+ response: {
775
+ data: [getSomeTestMutation(0.21, 6), getSomeOtherTestMutation(0.22, 4)],
797
776
  },
798
- response: { data: [] },
799
777
  },
778
+ ],
779
+ 'nucleotide',
780
+ );
781
+
782
+ const dateRanges = [
783
+ {
784
+ dateFrom: '2023-01-01',
785
+ dateTo: '2023-01-31',
786
+ },
787
+ {
788
+ dateFrom: '2023-02-01',
789
+ dateTo: '2023-02-28',
790
+ },
791
+ ];
792
+
793
+ lapisRequestMocks.mutationsOverTime(
794
+ [
800
795
  {
801
796
  body: {
802
- ...lapisFilter,
803
- dateFieldFrom: '2023-01-01',
804
- dateFieldTo: '2023-01-02',
805
- minProportion: 0.001,
797
+ filters: lapisFilter,
798
+ dateRanges,
799
+ includeMutations: ['A122T', 'otherSequenceName:G234C'],
800
+ dateField,
806
801
  },
807
802
  response: {
808
- data: [getSomeTestMutation(0.21, 6)],
803
+ data: {
804
+ data: [
805
+ [
806
+ { count: 0, coverage: 0 },
807
+ { count: 0, coverage: 0 },
808
+ ],
809
+ [
810
+ { count: 2, coverage: 10 },
811
+ { count: 3, coverage: 10 },
812
+ ],
813
+ ],
814
+ dateRanges,
815
+ mutations: ['A122T', 'otherSequenceName:G234C'],
816
+ totalCountsByDateRange: [11, 12],
817
+ },
809
818
  },
810
819
  },
811
820
  ],
812
821
  'nucleotide',
813
822
  );
814
823
 
815
- const { mutationOverTimeData } = await queryMutationsOverTimeData({
824
+ const { mutationOverTimeData } = await queryMutationsOverTimeData(
816
825
  lapisFilter,
817
- sequenceType: 'nucleotide',
818
- lapis: DUMMY_LAPIS_URL,
819
- lapisDateField: dateField,
820
- granularity: 'day',
821
- });
826
+ 'nucleotide',
827
+ DUMMY_LAPIS_URL,
828
+ dateField,
829
+ 'month',
830
+ ['otherSequenceName:G234C', 'A122T'],
831
+ );
822
832
 
823
833
  expect(mutationOverTimeData.getAsArray()).to.deep.equal([
824
834
  [
825
- { type: 'value', proportion: 0.1, count: 1, totalCount: 11 },
826
835
  { type: 'belowThreshold', totalCount: 11 },
836
+ { type: 'belowThreshold', totalCount: 12 },
837
+ ],
838
+ [
839
+ { type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 11 },
840
+ { type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 12 },
827
841
  ],
828
842
  ]);
843
+
844
+ const sequences = mutationOverTimeData.getFirstAxisKeys();
845
+ expect(sequences[0].code).toBe('A122T');
846
+ expect(sequences[1].code).toBe('otherSequenceName:G234C');
847
+
848
+ const dates = mutationOverTimeData.getSecondAxisKeys();
849
+ expect(dates[0].dateString).toBe('2023-01');
850
+ expect(dates[1].dateString).toBe('2023-02');
829
851
  });
830
852
 
831
- it('should return null if count in a date range is 0', async () => {
853
+ it('should return full mutation codes even if partial includeMutations are given', async () => {
832
854
  const lapisFilter = { field1: 'value1', field2: 'value2' };
833
855
  const dateField = 'dateField';
834
856
 
835
- lapisRequestMocks.multipleAggregated([
857
+ lapisRequestMocks.aggregated(
858
+ { ...lapisFilter, fields: [dateField] },
836
859
  {
837
- body: { ...lapisFilter, fields: [dateField] },
838
- response: {
839
- data: [{ count: 0, [dateField]: '2023-01-01' }],
840
- },
860
+ data: [
861
+ { count: 1, [dateField]: '2023-01-05' },
862
+ { count: 2, [dateField]: '2023-02-15' },
863
+ ],
841
864
  },
842
- {
843
- body: {
844
- ...lapisFilter,
845
- dateFieldFrom: '2023-01-01',
846
- dateFieldTo: '2023-01-01',
847
- fields: [],
848
- },
849
- response: { data: [{ count: 0 }] },
850
- },
851
- ]);
865
+ );
852
866
 
853
867
  lapisRequestMocks.multipleMutations(
854
868
  [
@@ -856,103 +870,67 @@ describe('queryMutationsOverTime', () => {
856
870
  body: {
857
871
  ...lapisFilter,
858
872
  dateFieldFrom: '2023-01-01',
859
- dateFieldTo: '2023-01-01',
873
+ dateFieldTo: '2023-02-28',
860
874
  minProportion: 0.001,
861
875
  },
862
- response: { data: [getSomeTestMutation(0.1, 1)] },
876
+ response: {
877
+ data: [getSomeTestMutation(0.21, 6), getSomeOtherTestMutation(0.22, 4)],
878
+ },
863
879
  },
864
880
  ],
865
881
  'nucleotide',
866
882
  );
867
883
 
868
- const { mutationOverTimeData } = await queryMutationsOverTimeData({
869
- lapisFilter,
870
- sequenceType: 'nucleotide',
871
- lapis: DUMMY_LAPIS_URL,
872
- lapisDateField: dateField,
873
- granularity: 'day',
874
- });
875
-
876
- expect(mutationOverTimeData.getAsArray()).to.deep.equal([[null]]);
877
- });
878
-
879
- it('should respect the includeMutations parameter', async () => {
880
- const lapisFilter = { field1: 'value1', field2: 'value2' };
881
- const dateField = 'dateField';
882
-
883
- lapisRequestMocks.multipleAggregated([
884
+ const dateRanges = [
884
885
  {
885
- body: { ...lapisFilter, fields: [dateField] },
886
- response: {
887
- data: [
888
- { count: 1, [dateField]: '2023-01-05' },
889
- { count: 2, [dateField]: '2023-02-15' },
890
- ],
891
- },
892
- },
893
- {
894
- body: {
895
- ...lapisFilter,
896
- dateFieldFrom: '2023-01-01',
897
- dateFieldTo: '2023-01-31',
898
- fields: [],
899
- },
900
- response: { data: [{ count: 11 }] },
886
+ dateFrom: '2023-01-01',
887
+ dateTo: '2023-01-31',
901
888
  },
902
889
  {
903
- body: {
904
- ...lapisFilter,
905
- dateFieldFrom: '2023-02-01',
906
- dateFieldTo: '2023-02-28',
907
- fields: [],
908
- },
909
- response: { data: [{ count: 12 }] },
890
+ dateFrom: '2023-02-01',
891
+ dateTo: '2023-02-28',
910
892
  },
911
- ]);
893
+ ];
912
894
 
913
- lapisRequestMocks.multipleMutations(
895
+ lapisRequestMocks.mutationsOverTime(
914
896
  [
915
897
  {
916
898
  body: {
917
- ...lapisFilter,
918
- dateFieldFrom: '2023-01-01',
919
- dateFieldTo: '2023-01-31',
920
- minProportion: 0.001,
921
- },
922
- response: { data: [getSomeTestMutation(0.1, 1), getSomeOtherTestMutation(0.4, 4)] },
923
- },
924
- {
925
- body: {
926
- ...lapisFilter,
927
- dateFieldFrom: '2023-02-01',
928
- dateFieldTo: '2023-02-28',
929
- minProportion: 0.001,
930
- },
931
- response: { data: [getSomeTestMutation(0.2, 2)] },
932
- },
933
- {
934
- body: {
935
- ...lapisFilter,
936
- dateFieldFrom: '2023-01-01',
937
- dateFieldTo: '2023-02-28',
938
- minProportion: 0.001,
899
+ filters: lapisFilter,
900
+ dateRanges,
901
+ includeMutations: ['122', 'otherSequenceName:G234C'],
902
+ dateField,
939
903
  },
940
904
  response: {
941
- data: [getSomeTestMutation(0.21, 6), getSomeOtherTestMutation(0.22, 4)],
905
+ data: {
906
+ data: [
907
+ [
908
+ { count: 0, coverage: 0 },
909
+ { count: 0, coverage: 0 },
910
+ ],
911
+ [
912
+ { count: 2, coverage: 10 },
913
+ { count: 3, coverage: 10 },
914
+ ],
915
+ ],
916
+ dateRanges,
917
+ mutations: ['A122T', 'otherSequenceName:G234C'],
918
+ totalCountsByDateRange: [11, 12],
919
+ },
942
920
  },
943
921
  },
944
922
  ],
945
923
  'nucleotide',
946
924
  );
947
925
 
948
- const { mutationOverTimeData } = await queryMutationsOverTimeData({
926
+ const { mutationOverTimeData } = await queryMutationsOverTimeData(
949
927
  lapisFilter,
950
- sequenceType: 'nucleotide',
951
- lapis: DUMMY_LAPIS_URL,
952
- lapisDateField: dateField,
953
- granularity: 'month',
954
- displayMutations: ['otherSequenceName:G234C', 'A44T'],
955
- });
928
+ 'nucleotide',
929
+ DUMMY_LAPIS_URL,
930
+ dateField,
931
+ 'month',
932
+ ['otherSequenceName:G234C', '122'],
933
+ );
956
934
 
957
935
  expect(mutationOverTimeData.getAsArray()).to.deep.equal([
958
936
  [
@@ -960,13 +938,13 @@ describe('queryMutationsOverTime', () => {
960
938
  { type: 'belowThreshold', totalCount: 12 },
961
939
  ],
962
940
  [
963
- { type: 'value', proportion: 0.4, count: 4, totalCount: 11 },
964
- { type: 'belowThreshold', totalCount: 12 },
941
+ { type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 11 },
942
+ { type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 12 },
965
943
  ],
966
944
  ]);
967
945
 
968
946
  const sequences = mutationOverTimeData.getFirstAxisKeys();
969
- expect(sequences[0].code).toBe('A44T');
947
+ expect(sequences[0].code).toBe('A122T');
970
948
  expect(sequences[1].code).toBe('otherSequenceName:G234C');
971
949
 
972
950
  const dates = mutationOverTimeData.getSecondAxisKeys();