@genspectrum/dashboard-components 1.11.1 → 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 (58) hide show
  1. package/README.md +0 -7
  2. package/custom-elements.json +6 -25
  3. package/dist/components.d.ts +24 -30
  4. package/dist/components.js +929 -742
  5. package/dist/components.js.map +1 -1
  6. package/dist/util.d.ts +40 -24
  7. package/package.json +1 -5
  8. package/src/lapisApi/lapisApi.ts +21 -1
  9. package/src/lapisApi/lapisTypes.ts +37 -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 +22 -245
  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-mutation-comparison.tsx +2 -2
  38. package/src/web-components/visualization/gs-mutations-over-time.spec-d.ts +0 -3
  39. package/src/web-components/visualization/gs-mutations-over-time.stories.ts +283 -17
  40. package/src/web-components/visualization/gs-mutations-over-time.tsx +0 -9
  41. package/standalone-bundle/dashboard-components.js +8935 -8780
  42. package/standalone-bundle/dashboard-components.js.map +1 -1
  43. package/dist/assets/mutationOverTimeWorker-CQQFRoK4.js.map +0 -1
  44. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay.ts +0 -47170
  45. package/src/preact/mutationsOverTime/__mockData__/byWeek.ts +0 -54026
  46. package/src/preact/mutationsOverTime/__mockData__/defaultMockData.ts +0 -108385
  47. package/src/preact/mutationsOverTime/__mockData__/mockConversion.ts +0 -54
  48. package/src/preact/mutationsOverTime/__mockData__/noDataWhenNoMutationsAreInFilter.ts +0 -23
  49. package/src/preact/mutationsOverTime/__mockData__/noDataWhenThereAreNoDatesInFilter.ts +0 -23
  50. package/src/preact/mutationsOverTime/__mockData__/showsMessageWhenTooManyMutations.ts +0 -65527
  51. package/src/preact/mutationsOverTime/__mockData__/withDisplayMutations.ts +0 -352
  52. package/src/preact/mutationsOverTime/__mockData__/withGaps.ts +0 -298
  53. package/src/preact/mutationsOverTime/mutationOverTimeWorker.mock.ts +0 -33
  54. package/src/preact/mutationsOverTime/mutationOverTimeWorker.ts +0 -29
  55. package/src/preact/webWorkers/useWebWorker.ts +0 -74
  56. package/src/preact/webWorkers/workerFunction.ts +0 -30
  57. package/src/query/queryMutationsOverTimeNewEndpoint.spec.ts +0 -1179
  58. package/standalone-bundle/assets/mutationOverTimeWorker-DIpJukJC.js.map +0 -1
@@ -1,1179 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
-
3
- import { queryMutationsOverTimeData } from './queryMutationsOverTime';
4
- import { DUMMY_LAPIS_URL, lapisRequestMocks } from '../../vitest.setup';
5
-
6
- describe('queryMutationsOverTimeNewEndpoint', () => {
7
- it('should fetch for a filter without date and sort by mutation and date', async () => {
8
- const lapisFilter = { field1: 'value1', field2: 'value2' };
9
- const dateField = 'dateField';
10
-
11
- lapisRequestMocks.multipleAggregated([
12
- // this request is expected to get 'all dates in dataset' - since the user hasn't provided a date range
13
- {
14
- body: { ...lapisFilter, fields: [dateField] },
15
- response: {
16
- data: [
17
- { count: 1, [dateField]: '2023-01-01' },
18
- { count: 2, [dateField]: '2023-01-03' },
19
- ],
20
- },
21
- },
22
- {
23
- body: {
24
- ...lapisFilter,
25
- dateFieldFrom: '2023-01-01',
26
- dateFieldTo: '2023-01-01',
27
- fields: [],
28
- },
29
- response: { data: [{ count: 11 }] },
30
- },
31
- {
32
- body: {
33
- ...lapisFilter,
34
- dateFieldFrom: '2023-01-02',
35
- dateFieldTo: '2023-01-02',
36
- fields: [],
37
- },
38
- response: { data: [{ count: 12 }] },
39
- },
40
- {
41
- body: {
42
- ...lapisFilter,
43
- dateFieldFrom: '2023-01-03',
44
- dateFieldTo: '2023-01-03',
45
- fields: [],
46
- },
47
- response: { data: [{ count: 13 }] },
48
- },
49
- ]);
50
- lapisRequestMocks.multipleMutations(
51
- [
52
- {
53
- body: {
54
- ...lapisFilter,
55
- dateFieldFrom: '2023-01-01',
56
- dateFieldTo: '2023-01-03',
57
- minProportion: 0.001,
58
- },
59
- response: {
60
- data: [getSomeTestMutation(0.21, 6), getSomeOtherTestMutation(0.22, 4)],
61
- },
62
- },
63
- ],
64
- 'nucleotide',
65
- );
66
- const dateRanges = [
67
- {
68
- dateFrom: '2023-01-01',
69
- dateTo: '2023-01-01',
70
- },
71
- {
72
- dateFrom: '2023-01-02',
73
- dateTo: '2023-01-02',
74
- },
75
- {
76
- dateFrom: '2023-01-03',
77
- dateTo: '2023-01-03',
78
- },
79
- ];
80
- lapisRequestMocks.mutationsOverTime(
81
- [
82
- {
83
- body: {
84
- filters: lapisFilter,
85
- dateRanges,
86
- includeMutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
87
- dateField,
88
- },
89
- response: {
90
- data: {
91
- data: [
92
- [
93
- { count: 4, coverage: 10 },
94
- { count: 0, coverage: 10 },
95
- { count: 0, coverage: 10 },
96
- ],
97
- [
98
- { count: 1, coverage: 10 },
99
- { count: 2, coverage: 10 },
100
- { count: 3, coverage: 10 },
101
- ],
102
- ],
103
- dateRanges,
104
- mutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
105
- },
106
- },
107
- },
108
- ],
109
- 'nucleotide',
110
- );
111
-
112
- const { mutationOverTimeData, overallMutationData } = await queryMutationsOverTimeData({
113
- lapisFilter,
114
- sequenceType: 'nucleotide',
115
- lapis: DUMMY_LAPIS_URL,
116
- lapisDateField: dateField,
117
- granularity: 'day',
118
- useNewEndpoint: true,
119
- });
120
-
121
- const expectedData = [
122
- [
123
- { type: 'valueWithCoverage', count: 4, coverage: 10, totalCount: 11 },
124
- { type: 'valueWithCoverage', count: 0, coverage: 10, totalCount: 12 },
125
- { type: 'valueWithCoverage', count: 0, coverage: 10, totalCount: 13 },
126
- ],
127
- [
128
- { type: 'valueWithCoverage', count: 1, coverage: 10, totalCount: 11 },
129
- { type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 12 },
130
- { type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 13 },
131
- ],
132
- ];
133
- expect(mutationOverTimeData.getAsArray()).to.deep.equal(expectedData);
134
-
135
- const sequences = mutationOverTimeData.getFirstAxisKeys();
136
- expect(sequences[0].code).toBe('otherSequenceName:G234C');
137
- expect(sequences[1].code).toBe('sequenceName:A123T');
138
-
139
- const dates = mutationOverTimeData.getSecondAxisKeys();
140
- expect(dates[0].dateString).toBe('2023-01-01');
141
- expect(dates[1].dateString).toBe('2023-01-02');
142
- expect(dates[2].dateString).toBe('2023-01-03');
143
-
144
- expect(overallMutationData).to.deep.equal([
145
- {
146
- type: 'substitution',
147
- mutation: {
148
- valueAtReference: 'G',
149
- substitutionValue: 'C',
150
- position: 234,
151
- segment: 'otherSequenceName',
152
- code: 'otherSequenceName:G234C',
153
- type: 'substitution',
154
- },
155
- count: 4,
156
- proportion: 0.22,
157
- },
158
- {
159
- type: 'substitution',
160
- mutation: {
161
- valueAtReference: 'A',
162
- substitutionValue: 'T',
163
- position: 123,
164
- segment: 'sequenceName',
165
- code: 'sequenceName:A123T',
166
- type: 'substitution',
167
- },
168
- count: 6,
169
- proportion: 0.21,
170
- },
171
- ]);
172
- });
173
-
174
- it('should fetch for dates with no mutations', async () => {
175
- const lapisFilter = { field1: 'value1', field2: 'value2' };
176
- const dateField = 'dateField';
177
-
178
- lapisRequestMocks.multipleAggregated([
179
- {
180
- body: { ...lapisFilter, fields: [dateField] },
181
- response: {
182
- data: [
183
- { count: 1, [dateField]: '2023-01-01' },
184
- { count: 2, [dateField]: '2023-01-03' },
185
- ],
186
- },
187
- },
188
- {
189
- body: {
190
- ...lapisFilter,
191
- dateFieldFrom: '2023-01-01',
192
- dateFieldTo: '2023-01-01',
193
- fields: [],
194
- },
195
- response: { data: [{ count: 11 }] },
196
- },
197
- {
198
- body: {
199
- ...lapisFilter,
200
- dateFieldFrom: '2023-01-02',
201
- dateFieldTo: '2023-01-02',
202
- fields: [],
203
- },
204
- response: { data: [{ count: 0 }] },
205
- },
206
- {
207
- body: {
208
- ...lapisFilter,
209
- dateFieldFrom: '2023-01-03',
210
- dateFieldTo: '2023-01-03',
211
- fields: [],
212
- },
213
- response: { data: [{ count: 13 }] },
214
- },
215
- ]);
216
-
217
- lapisRequestMocks.multipleMutations(
218
- [
219
- {
220
- body: {
221
- ...lapisFilter,
222
- dateFieldFrom: '2023-01-01',
223
- dateFieldTo: '2023-01-03',
224
- minProportion: 0.001,
225
- },
226
- response: {
227
- data: [getSomeTestMutation(0.2, 4), getSomeOtherTestMutation(0.4, 4)],
228
- },
229
- },
230
- ],
231
- 'nucleotide',
232
- );
233
-
234
- const dateRanges = [
235
- {
236
- dateFrom: '2023-01-01',
237
- dateTo: '2023-01-01',
238
- },
239
- {
240
- dateFrom: '2023-01-02',
241
- dateTo: '2023-01-02',
242
- },
243
- {
244
- dateFrom: '2023-01-03',
245
- dateTo: '2023-01-03',
246
- },
247
- ];
248
-
249
- lapisRequestMocks.mutationsOverTime(
250
- [
251
- {
252
- body: {
253
- filters: lapisFilter,
254
- dateRanges,
255
- includeMutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
256
- dateField,
257
- },
258
- response: {
259
- data: {
260
- data: [
261
- [
262
- { count: 4, coverage: 10 },
263
- { count: 0, coverage: 10 },
264
- { count: 0, coverage: 10 },
265
- ],
266
- [
267
- { count: 1, coverage: 10 },
268
- { count: 0, coverage: 10 },
269
- { count: 3, coverage: 10 },
270
- ],
271
- ],
272
- dateRanges,
273
- mutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
274
- },
275
- },
276
- },
277
- ],
278
- 'nucleotide',
279
- );
280
-
281
- const { mutationOverTimeData } = await queryMutationsOverTimeData({
282
- lapisFilter,
283
- sequenceType: 'nucleotide',
284
- lapis: DUMMY_LAPIS_URL,
285
- lapisDateField: dateField,
286
- granularity: 'day',
287
- useNewEndpoint: true,
288
- });
289
-
290
- expect(mutationOverTimeData.getAsArray()).to.deep.equal([
291
- [
292
- { type: 'valueWithCoverage', count: 4, coverage: 10, totalCount: 11 },
293
- null,
294
- { type: 'valueWithCoverage', count: 0, coverage: 10, totalCount: 13 },
295
- ],
296
- [
297
- { type: 'valueWithCoverage', count: 1, coverage: 10, totalCount: 11 },
298
- null,
299
- { type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 13 },
300
- ],
301
- ]);
302
-
303
- const sequences = mutationOverTimeData.getFirstAxisKeys();
304
- expect(sequences[0].code).toBe('otherSequenceName:G234C');
305
- expect(sequences[1].code).toBe('sequenceName:A123T');
306
-
307
- const dates = mutationOverTimeData.getSecondAxisKeys();
308
- expect(dates[0].dateString).toBe('2023-01-01');
309
- expect(dates[1].dateString).toBe('2023-01-02');
310
- expect(dates[2].dateString).toBe('2023-01-03');
311
- });
312
-
313
- it('should return empty map when no mutations are found', async () => {
314
- const lapisFilter = { field1: 'value1', field2: 'value2' };
315
- const dateField = 'dateField';
316
-
317
- lapisRequestMocks.multipleAggregated([
318
- {
319
- body: { ...lapisFilter, fields: [dateField] },
320
- response: {
321
- data: [
322
- { count: 1, [dateField]: '2023-01-01' },
323
- { count: 2, [dateField]: '2023-01-03' },
324
- ],
325
- },
326
- },
327
- {
328
- body: {
329
- ...lapisFilter,
330
- dateFieldFrom: '2023-01-01',
331
- dateFieldTo: '2023-01-01',
332
- fields: [],
333
- },
334
- response: { data: [{ count: 11 }] },
335
- },
336
- {
337
- body: {
338
- ...lapisFilter,
339
- dateFieldFrom: '2023-01-02',
340
- dateFieldTo: '2023-01-02',
341
- fields: [],
342
- },
343
- response: { data: [{ count: 12 }] },
344
- },
345
- {
346
- body: {
347
- ...lapisFilter,
348
- dateFieldFrom: '2023-01-03',
349
- dateFieldTo: '2023-01-03',
350
- fields: [],
351
- },
352
- response: { data: [{ count: 13 }] },
353
- },
354
- ]);
355
-
356
- lapisRequestMocks.multipleMutations(
357
- [
358
- {
359
- body: {
360
- ...lapisFilter,
361
- dateFieldFrom: '2023-01-01',
362
- dateFieldTo: '2023-01-03',
363
- minProportion: 0.001,
364
- },
365
- response: {
366
- data: [],
367
- },
368
- },
369
- ],
370
- 'nucleotide',
371
- );
372
-
373
- const dateRanges = [
374
- {
375
- dateFrom: '2023-01-01',
376
- dateTo: '2023-01-01',
377
- },
378
- {
379
- dateFrom: '2023-01-02',
380
- dateTo: '2023-01-02',
381
- },
382
- {
383
- dateFrom: '2023-01-03',
384
- dateTo: '2023-01-03',
385
- },
386
- ];
387
-
388
- lapisRequestMocks.mutationsOverTime(
389
- [
390
- {
391
- body: {
392
- filters: lapisFilter,
393
- dateRanges,
394
- includeMutations: [],
395
- dateField,
396
- },
397
- response: {
398
- data: {
399
- data: [],
400
- dateRanges,
401
- mutations: [],
402
- },
403
- },
404
- },
405
- ],
406
- 'nucleotide',
407
- );
408
-
409
- const { mutationOverTimeData } = await queryMutationsOverTimeData({
410
- lapisFilter,
411
- sequenceType: 'nucleotide',
412
- lapis: DUMMY_LAPIS_URL,
413
- lapisDateField: dateField,
414
- granularity: 'day',
415
- useNewEndpoint: true,
416
- });
417
-
418
- expect(mutationOverTimeData.getAsArray()).to.deep.equal([]);
419
- expect(mutationOverTimeData.getFirstAxisKeys()).to.deep.equal([]);
420
- const dates = mutationOverTimeData.getSecondAxisKeys();
421
- expect(dates.length).toBe(3);
422
- expect(dates[0].dateString).toBe('2023-01-01');
423
- expect(dates[1].dateString).toBe('2023-01-02');
424
- expect(dates[2].dateString).toBe('2023-01-03');
425
- });
426
-
427
- it('should use dateFrom from filter', async () => {
428
- const dateField = 'dateField';
429
- const lapisFilter = { field1: 'value1', field2: 'value2', [`${dateField}From`]: '2023-01-02' };
430
-
431
- lapisRequestMocks.multipleAggregated([
432
- {
433
- body: { ...lapisFilter, fields: [dateField] },
434
- response: {
435
- data: [
436
- { count: 1, [dateField]: '2023-01-01' },
437
- { count: 2, [dateField]: '2023-01-03' },
438
- ],
439
- },
440
- },
441
- {
442
- body: {
443
- ...lapisFilter,
444
- dateFieldFrom: '2023-01-02',
445
- dateFieldTo: '2023-01-02',
446
- fields: [],
447
- },
448
- response: { data: [{ count: 11 }] },
449
- },
450
- {
451
- body: {
452
- ...lapisFilter,
453
- dateFieldFrom: '2023-01-03',
454
- dateFieldTo: '2023-01-03',
455
- fields: [],
456
- },
457
- response: { data: [{ count: 12 }] },
458
- },
459
- ]);
460
-
461
- lapisRequestMocks.multipleMutations(
462
- [
463
- {
464
- body: {
465
- ...lapisFilter,
466
- dateFieldFrom: '2023-01-02',
467
- dateFieldTo: '2023-01-03',
468
- minProportion: 0.001,
469
- },
470
- response: {
471
- data: [getSomeTestMutation(0.25, 5)],
472
- },
473
- },
474
- ],
475
- 'nucleotide',
476
- );
477
-
478
- const dateRanges = [
479
- {
480
- dateFrom: '2023-01-02',
481
- dateTo: '2023-01-02',
482
- },
483
- {
484
- dateFrom: '2023-01-03',
485
- dateTo: '2023-01-03',
486
- },
487
- ];
488
-
489
- lapisRequestMocks.mutationsOverTime(
490
- [
491
- {
492
- body: {
493
- filters: lapisFilter,
494
- dateRanges,
495
- includeMutations: ['sequenceName:A123T'],
496
- dateField,
497
- },
498
- response: {
499
- data: {
500
- data: [
501
- [
502
- { count: 2, coverage: 10 },
503
- { count: 3, coverage: 10 },
504
- ],
505
- ],
506
- dateRanges,
507
- mutations: ['sequenceName:A123T'],
508
- },
509
- },
510
- },
511
- ],
512
- 'nucleotide',
513
- );
514
-
515
- const { mutationOverTimeData } = await queryMutationsOverTimeData({
516
- lapisFilter,
517
- sequenceType: 'nucleotide',
518
- lapis: DUMMY_LAPIS_URL,
519
- lapisDateField: dateField,
520
- granularity: 'day',
521
- useNewEndpoint: true,
522
- });
523
-
524
- expect(mutationOverTimeData.getAsArray()).to.deep.equal([
525
- [
526
- { type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 11 },
527
- { type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 12 },
528
- ],
529
- ]);
530
-
531
- const sequences = mutationOverTimeData.getFirstAxisKeys();
532
- expect(sequences[0].code).toBe('sequenceName:A123T');
533
-
534
- const dates = mutationOverTimeData.getSecondAxisKeys();
535
- expect(dates[0].dateString).toBe('2023-01-02');
536
- expect(dates[1].dateString).toBe('2023-01-03');
537
- });
538
-
539
- it('should use dateTo from filter', async () => {
540
- const dateField = 'dateField';
541
- const lapisFilter = { field1: 'value1', field2: 'value2', [`${dateField}To`]: '2023-01-02' };
542
-
543
- lapisRequestMocks.multipleAggregated([
544
- {
545
- body: { ...lapisFilter, fields: [dateField] },
546
- response: {
547
- data: [
548
- { count: 1, [dateField]: '2023-01-01' },
549
- { count: 2, [dateField]: '2023-01-03' },
550
- ],
551
- },
552
- },
553
- {
554
- body: {
555
- ...lapisFilter,
556
- dateFieldFrom: '2023-01-01',
557
- dateFieldTo: '2023-01-01',
558
- fields: [],
559
- },
560
- response: { data: [{ count: 11 }] },
561
- },
562
- {
563
- body: {
564
- ...lapisFilter,
565
- dateFieldFrom: '2023-01-02',
566
- dateFieldTo: '2023-01-02',
567
- fields: [],
568
- },
569
- response: { data: [{ count: 12 }] },
570
- },
571
- ]);
572
-
573
- lapisRequestMocks.multipleMutations(
574
- [
575
- {
576
- body: {
577
- ...lapisFilter,
578
- dateFieldFrom: '2023-01-01',
579
- dateFieldTo: '2023-01-02',
580
- minProportion: 0.001,
581
- },
582
- response: {
583
- data: [getSomeTestMutation(0.15, 3)],
584
- },
585
- },
586
- ],
587
- 'nucleotide',
588
- );
589
-
590
- const dateRanges = [
591
- {
592
- dateFrom: '2023-01-01',
593
- dateTo: '2023-01-01',
594
- },
595
- {
596
- dateFrom: '2023-01-02',
597
- dateTo: '2023-01-02',
598
- },
599
- ];
600
-
601
- lapisRequestMocks.mutationsOverTime(
602
- [
603
- {
604
- body: {
605
- filters: lapisFilter,
606
- dateRanges,
607
- includeMutations: ['sequenceName:A123T'],
608
- dateField,
609
- },
610
- response: {
611
- data: {
612
- data: [
613
- [
614
- { count: 1, coverage: 10 },
615
- { count: 2, coverage: 10 },
616
- ],
617
- ],
618
- dateRanges,
619
- mutations: ['sequenceName:A123T'],
620
- },
621
- },
622
- },
623
- ],
624
- 'nucleotide',
625
- );
626
-
627
- const { mutationOverTimeData } = await queryMutationsOverTimeData({
628
- lapisFilter,
629
- sequenceType: 'nucleotide',
630
- lapis: DUMMY_LAPIS_URL,
631
- lapisDateField: dateField,
632
- granularity: 'day',
633
- useNewEndpoint: true,
634
- });
635
-
636
- expect(mutationOverTimeData.getAsArray()).to.deep.equal([
637
- [
638
- { type: 'valueWithCoverage', count: 1, coverage: 10, totalCount: 11 },
639
- { type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 12 },
640
- ],
641
- ]);
642
-
643
- const sequences = mutationOverTimeData.getFirstAxisKeys();
644
- expect(sequences[0].code).toBe('sequenceName:A123T');
645
-
646
- const dates = mutationOverTimeData.getSecondAxisKeys();
647
- expect(dates[0].dateString).toBe('2023-01-01');
648
- expect(dates[1].dateString).toBe('2023-01-02');
649
- });
650
-
651
- it('should use date from filter', async () => {
652
- const dateField = 'dateField';
653
- const lapisFilter = { field1: 'value1', field2: 'value2', [dateField]: '2023-01-02' };
654
-
655
- lapisRequestMocks.multipleAggregated([
656
- {
657
- body: { ...lapisFilter, fields: [dateField] },
658
- response: {
659
- data: [
660
- { count: 1, [dateField]: '2023-01-01' },
661
- { count: 2, [dateField]: '2023-01-03' },
662
- ],
663
- },
664
- },
665
- {
666
- body: {
667
- ...lapisFilter,
668
- dateFieldFrom: '2023-01-02',
669
- dateFieldTo: '2023-01-02',
670
- fields: [],
671
- },
672
- response: { data: [{ count: 11 }] },
673
- },
674
- ]);
675
-
676
- lapisRequestMocks.multipleMutations(
677
- [
678
- {
679
- body: {
680
- ...lapisFilter,
681
- dateFieldFrom: '2023-01-02',
682
- dateFieldTo: '2023-01-02',
683
- minProportion: 0.001,
684
- },
685
- response: { data: [getSomeTestMutation(0.2, 2)] },
686
- },
687
- ],
688
- 'nucleotide',
689
- );
690
-
691
- const dateRanges = [
692
- {
693
- dateFrom: '2023-01-02',
694
- dateTo: '2023-01-02',
695
- },
696
- ];
697
-
698
- lapisRequestMocks.mutationsOverTime(
699
- [
700
- {
701
- body: {
702
- filters: lapisFilter,
703
- dateRanges,
704
- includeMutations: ['sequenceName:A123T'],
705
- dateField,
706
- },
707
- response: {
708
- data: {
709
- data: [[{ count: 2, coverage: 10 }]],
710
- dateRanges,
711
- mutations: ['sequenceName:A123T'],
712
- },
713
- },
714
- },
715
- ],
716
- 'nucleotide',
717
- );
718
-
719
- const { mutationOverTimeData } = await queryMutationsOverTimeData({
720
- lapisFilter,
721
- sequenceType: 'nucleotide',
722
- lapis: DUMMY_LAPIS_URL,
723
- lapisDateField: dateField,
724
- granularity: 'day',
725
- useNewEndpoint: true,
726
- });
727
-
728
- expect(mutationOverTimeData.getAsArray()).to.deep.equal([
729
- [{ type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 11 }],
730
- ]);
731
-
732
- const sequences = mutationOverTimeData.getFirstAxisKeys();
733
- expect(sequences[0].code).toBe('sequenceName:A123T');
734
-
735
- const dates = mutationOverTimeData.getSecondAxisKeys();
736
- expect(dates[0].dateString).toBe('2023-01-02');
737
- });
738
-
739
- it('should fetch data including the first and last day of the granularity', async () => {
740
- const lapisFilter = { field1: 'value1', field2: 'value2' };
741
- const dateField = 'dateField';
742
-
743
- lapisRequestMocks.multipleAggregated([
744
- {
745
- body: { ...lapisFilter, fields: [dateField] },
746
- response: {
747
- data: [
748
- { count: 1, [dateField]: '2023-01-05' },
749
- { count: 2, [dateField]: '2023-02-15' },
750
- ],
751
- },
752
- },
753
- {
754
- body: {
755
- ...lapisFilter,
756
- dateFieldFrom: '2023-01-01',
757
- dateFieldTo: '2023-01-31',
758
- fields: [],
759
- },
760
- response: { data: [{ count: 11 }] },
761
- },
762
- {
763
- body: {
764
- ...lapisFilter,
765
- dateFieldFrom: '2023-02-01',
766
- dateFieldTo: '2023-02-28',
767
- fields: [],
768
- },
769
- response: { data: [{ count: 12 }] },
770
- },
771
- ]);
772
-
773
- lapisRequestMocks.multipleMutations(
774
- [
775
- {
776
- body: {
777
- ...lapisFilter,
778
- dateFieldFrom: '2023-01-01',
779
- dateFieldTo: '2023-02-28',
780
- minProportion: 0.001,
781
- },
782
- response: {
783
- data: [getSomeTestMutation(0.21, 6), getSomeOtherTestMutation(0.22, 4)],
784
- },
785
- },
786
- ],
787
- 'nucleotide',
788
- );
789
-
790
- const dateRanges = [
791
- {
792
- dateFrom: '2023-01-01',
793
- dateTo: '2023-01-31',
794
- },
795
- {
796
- dateFrom: '2023-02-01',
797
- dateTo: '2023-02-28',
798
- },
799
- ];
800
-
801
- lapisRequestMocks.mutationsOverTime(
802
- [
803
- {
804
- body: {
805
- filters: lapisFilter,
806
- dateRanges,
807
- includeMutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
808
- dateField,
809
- },
810
- response: {
811
- data: {
812
- data: [
813
- [
814
- { count: 2, coverage: 10 },
815
- { count: 3, coverage: 10 },
816
- ],
817
- [
818
- { count: 4, coverage: 10 },
819
- { count: 5, coverage: 10 },
820
- ],
821
- ],
822
- dateRanges,
823
- mutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
824
- },
825
- },
826
- },
827
- ],
828
- 'nucleotide',
829
- );
830
-
831
- const { mutationOverTimeData } = await queryMutationsOverTimeData({
832
- lapisFilter,
833
- sequenceType: 'nucleotide',
834
- lapis: DUMMY_LAPIS_URL,
835
- lapisDateField: dateField,
836
- granularity: 'month',
837
- useNewEndpoint: true,
838
- });
839
-
840
- expect(mutationOverTimeData.getAsArray()).to.deep.equal([
841
- [
842
- { type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 11 },
843
- { type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 12 },
844
- ],
845
- [
846
- { type: 'valueWithCoverage', count: 4, coverage: 10, totalCount: 11 },
847
- { type: 'valueWithCoverage', count: 5, coverage: 10, totalCount: 12 },
848
- ],
849
- ]);
850
-
851
- const sequences = mutationOverTimeData.getFirstAxisKeys();
852
- expect(sequences[0].code).toBe('otherSequenceName:G234C');
853
- expect(sequences[1].code).toBe('sequenceName:A123T');
854
-
855
- const dates = mutationOverTimeData.getSecondAxisKeys();
856
- expect(dates[0].dateString).toBe('2023-01');
857
- expect(dates[1].dateString).toBe('2023-02');
858
- });
859
-
860
- it('should return empty data when there are no dates in filter', async () => {
861
- const lapisFilter = { field1: 'value1', field2: 'value2' };
862
- const dateField = 'dateField';
863
-
864
- lapisRequestMocks.multipleAggregated([
865
- {
866
- body: { ...lapisFilter, fields: [dateField] },
867
- response: {
868
- data: [],
869
- },
870
- },
871
- ]);
872
-
873
- lapisRequestMocks.mutationsOverTime(
874
- [
875
- {
876
- body: {
877
- filters: lapisFilter,
878
- dateRanges: [],
879
- includeMutations: [],
880
- dateField,
881
- },
882
- response: {
883
- data: {
884
- data: [],
885
- dateRanges: [],
886
- mutations: [],
887
- },
888
- },
889
- },
890
- ],
891
- 'nucleotide',
892
- );
893
-
894
- const { mutationOverTimeData } = await queryMutationsOverTimeData({
895
- lapisFilter,
896
- sequenceType: 'nucleotide',
897
- lapis: DUMMY_LAPIS_URL,
898
- lapisDateField: dateField,
899
- granularity: 'month',
900
- useNewEndpoint: true,
901
- });
902
-
903
- expect(mutationOverTimeData.getAsArray()).to.deep.equal([]);
904
-
905
- const sequences = mutationOverTimeData.getFirstAxisKeys();
906
- expect(sequences.length).toBe(0);
907
-
908
- const dates = mutationOverTimeData.getSecondAxisKeys();
909
- expect(dates.length).toBe(0);
910
- });
911
-
912
- it('should respect the includeMutations parameter', async () => {
913
- const lapisFilter = { field1: 'value1', field2: 'value2' };
914
- const dateField = 'dateField';
915
-
916
- lapisRequestMocks.multipleAggregated([
917
- {
918
- body: { ...lapisFilter, fields: [dateField] },
919
- response: {
920
- data: [
921
- { count: 1, [dateField]: '2023-01-05' },
922
- { count: 2, [dateField]: '2023-02-15' },
923
- ],
924
- },
925
- },
926
- {
927
- body: {
928
- ...lapisFilter,
929
- dateFieldFrom: '2023-01-01',
930
- dateFieldTo: '2023-01-31',
931
- fields: [],
932
- },
933
- response: { data: [{ count: 11 }] },
934
- },
935
- {
936
- body: {
937
- ...lapisFilter,
938
- dateFieldFrom: '2023-02-01',
939
- dateFieldTo: '2023-02-28',
940
- fields: [],
941
- },
942
- response: { data: [{ count: 12 }] },
943
- },
944
- ]);
945
-
946
- lapisRequestMocks.multipleMutations(
947
- [
948
- {
949
- body: {
950
- ...lapisFilter,
951
- dateFieldFrom: '2023-01-01',
952
- dateFieldTo: '2023-02-28',
953
- minProportion: 0.001,
954
- },
955
- response: {
956
- data: [getSomeTestMutation(0.21, 6), getSomeOtherTestMutation(0.22, 4)],
957
- },
958
- },
959
- ],
960
- 'nucleotide',
961
- );
962
-
963
- const dateRanges = [
964
- {
965
- dateFrom: '2023-01-01',
966
- dateTo: '2023-01-31',
967
- },
968
- {
969
- dateFrom: '2023-02-01',
970
- dateTo: '2023-02-28',
971
- },
972
- ];
973
-
974
- lapisRequestMocks.mutationsOverTime(
975
- [
976
- {
977
- body: {
978
- filters: lapisFilter,
979
- dateRanges,
980
- includeMutations: ['A122T', 'otherSequenceName:G234C'],
981
- dateField,
982
- },
983
- response: {
984
- data: {
985
- data: [
986
- [
987
- { count: 0, coverage: 0 },
988
- { count: 0, coverage: 0 },
989
- ],
990
- [
991
- { count: 2, coverage: 10 },
992
- { count: 3, coverage: 10 },
993
- ],
994
- ],
995
- dateRanges,
996
- mutations: ['A122T', 'otherSequenceName:G234C'],
997
- },
998
- },
999
- },
1000
- ],
1001
- 'nucleotide',
1002
- );
1003
-
1004
- const { mutationOverTimeData } = await queryMutationsOverTimeData({
1005
- lapisFilter,
1006
- sequenceType: 'nucleotide',
1007
- lapis: DUMMY_LAPIS_URL,
1008
- lapisDateField: dateField,
1009
- granularity: 'month',
1010
- useNewEndpoint: true,
1011
- displayMutations: ['otherSequenceName:G234C', 'A122T'],
1012
- });
1013
-
1014
- expect(mutationOverTimeData.getAsArray()).to.deep.equal([
1015
- [
1016
- { type: 'belowThreshold', totalCount: 11 },
1017
- { type: 'belowThreshold', totalCount: 12 },
1018
- ],
1019
- [
1020
- { type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 11 },
1021
- { type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 12 },
1022
- ],
1023
- ]);
1024
-
1025
- const sequences = mutationOverTimeData.getFirstAxisKeys();
1026
- expect(sequences[0].code).toBe('A122T');
1027
- expect(sequences[1].code).toBe('otherSequenceName:G234C');
1028
-
1029
- const dates = mutationOverTimeData.getSecondAxisKeys();
1030
- expect(dates[0].dateString).toBe('2023-01');
1031
- expect(dates[1].dateString).toBe('2023-02');
1032
- });
1033
-
1034
- it('should return full mutation codes even if partial includeMutations are given', async () => {
1035
- const lapisFilter = { field1: 'value1', field2: 'value2' };
1036
- const dateField = 'dateField';
1037
-
1038
- lapisRequestMocks.multipleAggregated([
1039
- {
1040
- body: { ...lapisFilter, fields: [dateField] },
1041
- response: {
1042
- data: [
1043
- { count: 1, [dateField]: '2023-01-05' },
1044
- { count: 2, [dateField]: '2023-02-15' },
1045
- ],
1046
- },
1047
- },
1048
- {
1049
- body: {
1050
- ...lapisFilter,
1051
- dateFieldFrom: '2023-01-01',
1052
- dateFieldTo: '2023-01-31',
1053
- fields: [],
1054
- },
1055
- response: { data: [{ count: 11 }] },
1056
- },
1057
- {
1058
- body: {
1059
- ...lapisFilter,
1060
- dateFieldFrom: '2023-02-01',
1061
- dateFieldTo: '2023-02-28',
1062
- fields: [],
1063
- },
1064
- response: { data: [{ count: 12 }] },
1065
- },
1066
- ]);
1067
-
1068
- lapisRequestMocks.multipleMutations(
1069
- [
1070
- {
1071
- body: {
1072
- ...lapisFilter,
1073
- dateFieldFrom: '2023-01-01',
1074
- dateFieldTo: '2023-02-28',
1075
- minProportion: 0.001,
1076
- },
1077
- response: {
1078
- data: [getSomeTestMutation(0.21, 6), getSomeOtherTestMutation(0.22, 4)],
1079
- },
1080
- },
1081
- ],
1082
- 'nucleotide',
1083
- );
1084
-
1085
- const dateRanges = [
1086
- {
1087
- dateFrom: '2023-01-01',
1088
- dateTo: '2023-01-31',
1089
- },
1090
- {
1091
- dateFrom: '2023-02-01',
1092
- dateTo: '2023-02-28',
1093
- },
1094
- ];
1095
-
1096
- lapisRequestMocks.mutationsOverTime(
1097
- [
1098
- {
1099
- body: {
1100
- filters: lapisFilter,
1101
- dateRanges,
1102
- includeMutations: ['122', 'otherSequenceName:G234C'],
1103
- dateField,
1104
- },
1105
- response: {
1106
- data: {
1107
- data: [
1108
- [
1109
- { count: 0, coverage: 0 },
1110
- { count: 0, coverage: 0 },
1111
- ],
1112
- [
1113
- { count: 2, coverage: 10 },
1114
- { count: 3, coverage: 10 },
1115
- ],
1116
- ],
1117
- dateRanges,
1118
- mutations: ['A122T', 'otherSequenceName:G234C'],
1119
- },
1120
- },
1121
- },
1122
- ],
1123
- 'nucleotide',
1124
- );
1125
-
1126
- const { mutationOverTimeData } = await queryMutationsOverTimeData({
1127
- lapisFilter,
1128
- sequenceType: 'nucleotide',
1129
- lapis: DUMMY_LAPIS_URL,
1130
- lapisDateField: dateField,
1131
- granularity: 'month',
1132
- useNewEndpoint: true,
1133
- displayMutations: ['otherSequenceName:G234C', '122'],
1134
- });
1135
-
1136
- expect(mutationOverTimeData.getAsArray()).to.deep.equal([
1137
- [
1138
- { type: 'belowThreshold', totalCount: 11 },
1139
- { type: 'belowThreshold', totalCount: 12 },
1140
- ],
1141
- [
1142
- { type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 11 },
1143
- { type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 12 },
1144
- ],
1145
- ]);
1146
-
1147
- const sequences = mutationOverTimeData.getFirstAxisKeys();
1148
- expect(sequences[0].code).toBe('A122T');
1149
- expect(sequences[1].code).toBe('otherSequenceName:G234C');
1150
-
1151
- const dates = mutationOverTimeData.getSecondAxisKeys();
1152
- expect(dates[0].dateString).toBe('2023-01');
1153
- expect(dates[1].dateString).toBe('2023-02');
1154
- });
1155
-
1156
- function getSomeTestMutation(proportion: number, count: number) {
1157
- return {
1158
- mutation: 'sequenceName:A123T',
1159
- proportion,
1160
- count,
1161
- sequenceName: 'sequenceName',
1162
- mutationFrom: 'A',
1163
- mutationTo: 'T',
1164
- position: 123,
1165
- };
1166
- }
1167
-
1168
- function getSomeOtherTestMutation(proportion: number, count: number) {
1169
- return {
1170
- mutation: 'otherSequenceName:G234C',
1171
- proportion,
1172
- count,
1173
- sequenceName: 'otherSequenceName',
1174
- mutationFrom: 'G',
1175
- mutationTo: 'C',
1176
- position: 234,
1177
- };
1178
- }
1179
- });