@genspectrum/dashboard-components 1.15.0 → 1.17.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.
- package/custom-elements.json +5 -5
- package/dist/components.d.ts +66 -67
- package/dist/components.js +457 -256
- package/dist/components.js.map +1 -1
- package/dist/util.d.ts +69 -66
- package/package.json +2 -9
- package/src/preact/MutationAnnotationsContext.tsx +1 -1
- package/src/preact/components/csv-download-button.tsx +22 -14
- package/src/preact/components/features-over-time-grid.tsx +189 -43
- package/src/preact/components/mutations-over-time-mutations-filter.stories.tsx +1 -1
- package/src/preact/components/mutations-over-time-mutations-filter.tsx +1 -1
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay/aminoAcidMutationsOverTimePage1.json +52 -0
- package/src/preact/mutationsOverTime/__mockData__/byWeek/mutationsOverTimePage1.json +76 -0
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData/mockDefaultMutationsOverTimeWithFilter.json +43 -0
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData/mutationsOverTimePage1.json +126 -0
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData/mutationsOverTimePage2.json +116 -0
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData/mutationsOverTimePageSize20.json +216 -0
- package/src/preact/mutationsOverTime/getFilteredMutationCodes.spec.ts +236 -0
- package/src/preact/mutationsOverTime/{getFilteredMutationsOverTimeData.ts → getFilteredMutationCodes.ts} +32 -45
- package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +128 -23
- package/src/preact/mutationsOverTime/mutations-over-time.tsx +139 -74
- package/src/preact/mutationsOverTime/useMutationsOverTimePageData.ts +111 -0
- package/src/preact/queriesOverTime/queries-over-time-row-label-tooltip.stories.tsx +8 -10
- package/src/preact/queriesOverTime/queries-over-time-row-label-tooltip.tsx +7 -17
- package/src/preact/queriesOverTime/queries-over-time.tsx +1 -1
- package/src/preact/shared/tanstackTable/pagination-context.tsx +5 -2
- package/src/preact/shared/tanstackTable/pagination.tsx +11 -9
- package/src/preact/shared/tanstackTable/tanstackTable.tsx +7 -4
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.tsx +1 -1
- package/src/query/queryMutationsOverTime.spec.ts +187 -662
- package/src/query/queryMutationsOverTime.ts +46 -33
- package/src/utilEntrypoint.ts +1 -1
- package/src/utils/useControlledState.ts +15 -0
- package/src/web-components/gs-app.ts +2 -3
- package/src/web-components/input/gs-date-range-filter.tsx +2 -3
- package/src/web-components/input/gs-lineage-filter.tsx +2 -3
- package/src/web-components/input/gs-location-filter.tsx +2 -3
- package/src/web-components/input/gs-mutation-filter.tsx +3 -4
- package/src/web-components/input/gs-number-range-filter.tsx +2 -3
- package/src/web-components/input/gs-text-filter.tsx +2 -3
- package/src/web-components/mutation-annotations-context.ts +3 -1
- package/src/web-components/visualization/gs-aggregate.tsx +2 -3
- package/src/web-components/visualization/gs-genome-data-viewer.tsx +2 -3
- package/src/web-components/visualization/gs-mutation-comparison.tsx +2 -3
- package/src/web-components/visualization/gs-mutations-over-time.stories.ts +78 -22
- package/src/web-components/visualization/gs-mutations-over-time.tsx +2 -3
- package/src/web-components/visualization/gs-mutations.tsx +7 -8
- package/src/web-components/visualization/gs-number-sequences-over-time.tsx +2 -3
- package/src/web-components/visualization/gs-prevalence-over-time.tsx +2 -3
- package/src/web-components/visualization/gs-queries-over-time.tsx +2 -3
- package/src/web-components/visualization/gs-relative-growth-advantage.tsx +2 -3
- package/src/web-components/visualization/gs-sequences-by-location.tsx +2 -3
- package/src/web-components/visualization/gs-statistics.tsx +2 -3
- package/src/web-components/wastewaterVisualization/gs-wastewater-mutations-over-time.tsx +2 -3
- package/standalone-bundle/dashboard-components.js +6877 -6697
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay/aminoAcidMutationsOverTime.json +0 -5496
- package/src/preact/mutationsOverTime/__mockData__/byWeek/mutationsOverTime.json +0 -7100
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData/mutationsOverTime.json +0 -12646
- package/src/preact/mutationsOverTime/getFilteredMutationsOverTime.spec.ts +0 -417
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { queryMutationsOverTimeMetadata, queryMutationsOverTimePage } from './queryMutationsOverTime';
|
|
4
4
|
import { DUMMY_LAPIS_URL, lapisRequestMocks } from '../../vitest.setup';
|
|
5
|
+
import { yearMonthDay } from '../utils/temporalTestHelpers';
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const lapisFilter = { field1: 'value1', field2: 'value2' };
|
|
9
|
-
const dateField = 'dateField';
|
|
7
|
+
const lapisFilter = { field1: 'value1', field2: 'value2' };
|
|
8
|
+
const dateField = 'dateField';
|
|
10
9
|
|
|
10
|
+
describe('queryMutationsOverTimeMetadata', () => {
|
|
11
|
+
it('should fetch overall mutation data and sort by mutation code', async () => {
|
|
11
12
|
lapisRequestMocks.aggregated(
|
|
12
13
|
{ ...lapisFilter, fields: [dateField] },
|
|
13
14
|
{
|
|
@@ -33,54 +34,8 @@ describe('queryMutationsOverTimeNewEndpoint', () => {
|
|
|
33
34
|
],
|
|
34
35
|
'nucleotide',
|
|
35
36
|
);
|
|
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
|
-
[
|
|
52
|
-
{
|
|
53
|
-
body: {
|
|
54
|
-
filters: lapisFilter,
|
|
55
|
-
dateRanges,
|
|
56
|
-
includeMutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
|
|
57
|
-
dateField,
|
|
58
|
-
},
|
|
59
|
-
response: {
|
|
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
|
-
},
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
],
|
|
80
|
-
'nucleotide',
|
|
81
|
-
);
|
|
82
37
|
|
|
83
|
-
const {
|
|
38
|
+
const { overallMutationData, requestedDateRanges } = await queryMutationsOverTimeMetadata(
|
|
84
39
|
lapisFilter,
|
|
85
40
|
'nucleotide',
|
|
86
41
|
DUMMY_LAPIS_URL,
|
|
@@ -88,29 +43,6 @@ describe('queryMutationsOverTimeNewEndpoint', () => {
|
|
|
88
43
|
'day',
|
|
89
44
|
);
|
|
90
45
|
|
|
91
|
-
const expectedData = [
|
|
92
|
-
[
|
|
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 },
|
|
96
|
-
],
|
|
97
|
-
[
|
|
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 },
|
|
101
|
-
],
|
|
102
|
-
];
|
|
103
|
-
expect(mutationOverTimeData.getAsArray()).to.deep.equal(expectedData);
|
|
104
|
-
|
|
105
|
-
const sequences = mutationOverTimeData.getFirstAxisKeys();
|
|
106
|
-
expect(sequences[0].code).toBe('otherSequenceName:G234C');
|
|
107
|
-
expect(sequences[1].code).toBe('sequenceName:A123T');
|
|
108
|
-
|
|
109
|
-
const dates = mutationOverTimeData.getSecondAxisKeys();
|
|
110
|
-
expect(dates[0].dateString).toBe('2023-01-01');
|
|
111
|
-
expect(dates[1].dateString).toBe('2023-01-02');
|
|
112
|
-
expect(dates[2].dateString).toBe('2023-01-03');
|
|
113
|
-
|
|
114
46
|
expect(overallMutationData).to.deep.equal([
|
|
115
47
|
{
|
|
116
48
|
type: 'substitution',
|
|
@@ -139,124 +71,51 @@ describe('queryMutationsOverTimeNewEndpoint', () => {
|
|
|
139
71
|
proportion: 0.21,
|
|
140
72
|
},
|
|
141
73
|
]);
|
|
142
|
-
});
|
|
143
74
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const dateField = 'dateField';
|
|
75
|
+
expect(requestedDateRanges.map((d) => d.dateString)).to.deep.equal(['2023-01-01', '2023-01-02', '2023-01-03']);
|
|
76
|
+
});
|
|
147
77
|
|
|
78
|
+
it('should expand date ranges to cover first and last day of the granularity', async () => {
|
|
148
79
|
lapisRequestMocks.aggregated(
|
|
149
80
|
{ ...lapisFilter, fields: [dateField] },
|
|
150
81
|
{
|
|
151
82
|
data: [
|
|
152
|
-
{ count: 1, [dateField]: '2023-01-
|
|
153
|
-
{ count: 2, [dateField]: '2023-
|
|
83
|
+
{ count: 1, [dateField]: '2023-01-05' },
|
|
84
|
+
{ count: 2, [dateField]: '2023-02-15' },
|
|
154
85
|
],
|
|
155
86
|
},
|
|
156
87
|
);
|
|
157
|
-
|
|
158
88
|
lapisRequestMocks.multipleMutations(
|
|
159
89
|
[
|
|
160
90
|
{
|
|
161
91
|
body: {
|
|
162
92
|
...lapisFilter,
|
|
163
93
|
dateFieldFrom: '2023-01-01',
|
|
164
|
-
dateFieldTo: '2023-
|
|
94
|
+
dateFieldTo: '2023-02-28',
|
|
165
95
|
minProportion: 0.001,
|
|
166
96
|
},
|
|
167
|
-
response: {
|
|
168
|
-
data: [getSomeTestMutation(0.2, 4), getSomeOtherTestMutation(0.4, 4)],
|
|
169
|
-
},
|
|
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
|
-
[
|
|
192
|
-
{
|
|
193
|
-
body: {
|
|
194
|
-
filters: lapisFilter,
|
|
195
|
-
dateRanges,
|
|
196
|
-
includeMutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
|
|
197
|
-
dateField,
|
|
198
|
-
},
|
|
199
|
-
response: {
|
|
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
|
-
},
|
|
217
|
-
},
|
|
97
|
+
response: { data: [getSomeTestMutation(0.21, 6)] },
|
|
218
98
|
},
|
|
219
99
|
],
|
|
220
100
|
'nucleotide',
|
|
221
101
|
);
|
|
222
102
|
|
|
223
|
-
const {
|
|
103
|
+
const { requestedDateRanges } = await queryMutationsOverTimeMetadata(
|
|
224
104
|
lapisFilter,
|
|
225
105
|
'nucleotide',
|
|
226
106
|
DUMMY_LAPIS_URL,
|
|
227
107
|
dateField,
|
|
228
|
-
'
|
|
108
|
+
'month',
|
|
229
109
|
);
|
|
230
110
|
|
|
231
|
-
expect(
|
|
232
|
-
[
|
|
233
|
-
{ type: 'valueWithCoverage', count: 4, coverage: 10, totalCount: 11 },
|
|
234
|
-
null,
|
|
235
|
-
{ type: 'valueWithCoverage', count: 0, coverage: 10, totalCount: 13 },
|
|
236
|
-
],
|
|
237
|
-
[
|
|
238
|
-
{ type: 'valueWithCoverage', count: 1, coverage: 10, totalCount: 11 },
|
|
239
|
-
null,
|
|
240
|
-
{ type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 13 },
|
|
241
|
-
],
|
|
242
|
-
]);
|
|
243
|
-
|
|
244
|
-
const sequences = mutationOverTimeData.getFirstAxisKeys();
|
|
245
|
-
expect(sequences[0].code).toBe('otherSequenceName:G234C');
|
|
246
|
-
expect(sequences[1].code).toBe('sequenceName:A123T');
|
|
247
|
-
|
|
248
|
-
const dates = mutationOverTimeData.getSecondAxisKeys();
|
|
249
|
-
expect(dates[0].dateString).toBe('2023-01-01');
|
|
250
|
-
expect(dates[1].dateString).toBe('2023-01-02');
|
|
251
|
-
expect(dates[2].dateString).toBe('2023-01-03');
|
|
111
|
+
expect(requestedDateRanges.map((d) => d.dateString)).to.deep.equal(['2023-01', '2023-02']);
|
|
252
112
|
});
|
|
253
113
|
|
|
254
|
-
it('should
|
|
255
|
-
const
|
|
256
|
-
const dateField = 'dateField';
|
|
114
|
+
it('should restrict date range when dateFrom is in the filter', async () => {
|
|
115
|
+
const filterWithDateFrom = { ...lapisFilter, [`${dateField}From`]: '2023-01-02' };
|
|
257
116
|
|
|
258
117
|
lapisRequestMocks.aggregated(
|
|
259
|
-
{ ...
|
|
118
|
+
{ ...filterWithDateFrom, fields: [dateField] },
|
|
260
119
|
{
|
|
261
120
|
data: [
|
|
262
121
|
{ count: 1, [dateField]: '2023-01-01' },
|
|
@@ -264,84 +123,37 @@ describe('queryMutationsOverTimeNewEndpoint', () => {
|
|
|
264
123
|
],
|
|
265
124
|
},
|
|
266
125
|
);
|
|
267
|
-
|
|
268
126
|
lapisRequestMocks.multipleMutations(
|
|
269
127
|
[
|
|
270
128
|
{
|
|
271
129
|
body: {
|
|
272
|
-
...
|
|
273
|
-
dateFieldFrom: '2023-01-
|
|
130
|
+
...filterWithDateFrom,
|
|
131
|
+
dateFieldFrom: '2023-01-02',
|
|
274
132
|
dateFieldTo: '2023-01-03',
|
|
275
133
|
minProportion: 0.001,
|
|
276
134
|
},
|
|
277
|
-
response: {
|
|
278
|
-
data: [],
|
|
279
|
-
},
|
|
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
|
-
[
|
|
302
|
-
{
|
|
303
|
-
body: {
|
|
304
|
-
filters: lapisFilter,
|
|
305
|
-
dateRanges,
|
|
306
|
-
includeMutations: [],
|
|
307
|
-
dateField,
|
|
308
|
-
},
|
|
309
|
-
response: {
|
|
310
|
-
data: {
|
|
311
|
-
data: [],
|
|
312
|
-
dateRanges,
|
|
313
|
-
mutations: [],
|
|
314
|
-
totalCountsByDateRange: [],
|
|
315
|
-
},
|
|
316
|
-
},
|
|
135
|
+
response: { data: [getSomeTestMutation(0.25, 5)] },
|
|
317
136
|
},
|
|
318
137
|
],
|
|
319
138
|
'nucleotide',
|
|
320
139
|
);
|
|
321
140
|
|
|
322
|
-
const {
|
|
323
|
-
|
|
141
|
+
const { requestedDateRanges } = await queryMutationsOverTimeMetadata(
|
|
142
|
+
filterWithDateFrom,
|
|
324
143
|
'nucleotide',
|
|
325
144
|
DUMMY_LAPIS_URL,
|
|
326
145
|
dateField,
|
|
327
146
|
'day',
|
|
328
147
|
);
|
|
329
148
|
|
|
330
|
-
expect(
|
|
331
|
-
expect(mutationOverTimeData.getFirstAxisKeys()).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');
|
|
149
|
+
expect(requestedDateRanges.map((d) => d.dateString)).to.deep.equal(['2023-01-02', '2023-01-03']);
|
|
337
150
|
});
|
|
338
151
|
|
|
339
|
-
it('should
|
|
340
|
-
const
|
|
341
|
-
const lapisFilter = { field1: 'value1', field2: 'value2', [`${dateField}From`]: '2023-01-02' };
|
|
152
|
+
it('should restrict date range when dateTo is in the filter', async () => {
|
|
153
|
+
const filterWithDateTo = { ...lapisFilter, [`${dateField}To`]: '2023-01-02' };
|
|
342
154
|
|
|
343
155
|
lapisRequestMocks.aggregated(
|
|
344
|
-
{ ...
|
|
156
|
+
{ ...filterWithDateTo, fields: [dateField] },
|
|
345
157
|
{
|
|
346
158
|
data: [
|
|
347
159
|
{ count: 1, [dateField]: '2023-01-01' },
|
|
@@ -349,91 +161,37 @@ describe('queryMutationsOverTimeNewEndpoint', () => {
|
|
|
349
161
|
],
|
|
350
162
|
},
|
|
351
163
|
);
|
|
352
|
-
|
|
353
164
|
lapisRequestMocks.multipleMutations(
|
|
354
165
|
[
|
|
355
166
|
{
|
|
356
167
|
body: {
|
|
357
|
-
...
|
|
358
|
-
dateFieldFrom: '2023-01-
|
|
359
|
-
dateFieldTo: '2023-01-
|
|
168
|
+
...filterWithDateTo,
|
|
169
|
+
dateFieldFrom: '2023-01-01',
|
|
170
|
+
dateFieldTo: '2023-01-02',
|
|
360
171
|
minProportion: 0.001,
|
|
361
172
|
},
|
|
362
|
-
response: {
|
|
363
|
-
data: [getSomeTestMutation(0.25, 5)],
|
|
364
|
-
},
|
|
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
|
-
[
|
|
383
|
-
{
|
|
384
|
-
body: {
|
|
385
|
-
filters: lapisFilter,
|
|
386
|
-
dateRanges,
|
|
387
|
-
includeMutations: ['sequenceName:A123T'],
|
|
388
|
-
dateField,
|
|
389
|
-
},
|
|
390
|
-
response: {
|
|
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
|
-
},
|
|
402
|
-
},
|
|
173
|
+
response: { data: [getSomeTestMutation(0.15, 3)] },
|
|
403
174
|
},
|
|
404
175
|
],
|
|
405
176
|
'nucleotide',
|
|
406
177
|
);
|
|
407
178
|
|
|
408
|
-
const {
|
|
409
|
-
|
|
179
|
+
const { requestedDateRanges } = await queryMutationsOverTimeMetadata(
|
|
180
|
+
filterWithDateTo,
|
|
410
181
|
'nucleotide',
|
|
411
182
|
DUMMY_LAPIS_URL,
|
|
412
183
|
dateField,
|
|
413
184
|
'day',
|
|
414
185
|
);
|
|
415
186
|
|
|
416
|
-
expect(
|
|
417
|
-
[
|
|
418
|
-
{ type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 11 },
|
|
419
|
-
{ type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 12 },
|
|
420
|
-
],
|
|
421
|
-
]);
|
|
422
|
-
|
|
423
|
-
const sequences = mutationOverTimeData.getFirstAxisKeys();
|
|
424
|
-
expect(sequences[0].code).toBe('sequenceName:A123T');
|
|
425
|
-
|
|
426
|
-
const dates = mutationOverTimeData.getSecondAxisKeys();
|
|
427
|
-
expect(dates[0].dateString).toBe('2023-01-02');
|
|
428
|
-
expect(dates[1].dateString).toBe('2023-01-03');
|
|
187
|
+
expect(requestedDateRanges.map((d) => d.dateString)).to.deep.equal(['2023-01-01', '2023-01-02']);
|
|
429
188
|
});
|
|
430
189
|
|
|
431
|
-
it('should
|
|
432
|
-
const
|
|
433
|
-
const lapisFilter = { field1: 'value1', field2: 'value2', [`${dateField}To`]: '2023-01-02' };
|
|
190
|
+
it('should restrict date range when an exact date is in the filter', async () => {
|
|
191
|
+
const filterWithDate = { ...lapisFilter, [dateField]: '2023-01-02' };
|
|
434
192
|
|
|
435
193
|
lapisRequestMocks.aggregated(
|
|
436
|
-
{ ...
|
|
194
|
+
{ ...filterWithDate, fields: [dateField] },
|
|
437
195
|
{
|
|
438
196
|
data: [
|
|
439
197
|
{ count: 1, [dateField]: '2023-01-01' },
|
|
@@ -441,210 +199,118 @@ describe('queryMutationsOverTimeNewEndpoint', () => {
|
|
|
441
199
|
],
|
|
442
200
|
},
|
|
443
201
|
);
|
|
444
|
-
|
|
445
202
|
lapisRequestMocks.multipleMutations(
|
|
446
203
|
[
|
|
447
204
|
{
|
|
448
205
|
body: {
|
|
449
|
-
...
|
|
450
|
-
dateFieldFrom: '2023-01-
|
|
206
|
+
...filterWithDate,
|
|
207
|
+
dateFieldFrom: '2023-01-02',
|
|
451
208
|
dateFieldTo: '2023-01-02',
|
|
452
209
|
minProportion: 0.001,
|
|
453
210
|
},
|
|
454
|
-
response: {
|
|
455
|
-
data: [getSomeTestMutation(0.15, 3)],
|
|
456
|
-
},
|
|
211
|
+
response: { data: [getSomeTestMutation(0.2, 2)] },
|
|
457
212
|
},
|
|
458
213
|
],
|
|
459
214
|
'nucleotide',
|
|
460
215
|
);
|
|
461
216
|
|
|
462
|
-
const
|
|
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
|
-
[
|
|
475
|
-
{
|
|
476
|
-
body: {
|
|
477
|
-
filters: lapisFilter,
|
|
478
|
-
dateRanges,
|
|
479
|
-
includeMutations: ['sequenceName:A123T'],
|
|
480
|
-
dateField,
|
|
481
|
-
},
|
|
482
|
-
response: {
|
|
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
|
-
},
|
|
494
|
-
},
|
|
495
|
-
},
|
|
496
|
-
],
|
|
217
|
+
const { requestedDateRanges } = await queryMutationsOverTimeMetadata(
|
|
218
|
+
filterWithDate,
|
|
497
219
|
'nucleotide',
|
|
220
|
+
DUMMY_LAPIS_URL,
|
|
221
|
+
dateField,
|
|
222
|
+
'day',
|
|
498
223
|
);
|
|
499
224
|
|
|
500
|
-
|
|
225
|
+
expect(requestedDateRanges.map((d) => d.dateString)).to.deep.equal(['2023-01-02']);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it('should return empty data when there are no dates in the dataset', async () => {
|
|
229
|
+
lapisRequestMocks.aggregated({ ...lapisFilter, fields: [dateField] }, { data: [] });
|
|
230
|
+
|
|
231
|
+
const { overallMutationData, requestedDateRanges } = await queryMutationsOverTimeMetadata(
|
|
501
232
|
lapisFilter,
|
|
502
233
|
'nucleotide',
|
|
503
234
|
DUMMY_LAPIS_URL,
|
|
504
235
|
dateField,
|
|
505
|
-
'
|
|
236
|
+
'month',
|
|
506
237
|
);
|
|
507
238
|
|
|
508
|
-
expect(
|
|
509
|
-
|
|
510
|
-
{ type: 'valueWithCoverage', count: 1, coverage: 10, totalCount: 11 },
|
|
511
|
-
{ type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 12 },
|
|
512
|
-
],
|
|
513
|
-
]);
|
|
514
|
-
|
|
515
|
-
const sequences = mutationOverTimeData.getFirstAxisKeys();
|
|
516
|
-
expect(sequences[0].code).toBe('sequenceName:A123T');
|
|
517
|
-
|
|
518
|
-
const dates = mutationOverTimeData.getSecondAxisKeys();
|
|
519
|
-
expect(dates[0].dateString).toBe('2023-01-01');
|
|
520
|
-
expect(dates[1].dateString).toBe('2023-01-02');
|
|
239
|
+
expect(overallMutationData).to.deep.equal([]);
|
|
240
|
+
expect(requestedDateRanges).to.deep.equal([]);
|
|
521
241
|
});
|
|
522
242
|
|
|
523
|
-
it('should
|
|
524
|
-
const dateField = 'dateField';
|
|
525
|
-
const lapisFilter = { field1: 'value1', field2: 'value2', [dateField]: '2023-01-02' };
|
|
526
|
-
|
|
243
|
+
it('should filter overall mutations by includeMutations', async () => {
|
|
527
244
|
lapisRequestMocks.aggregated(
|
|
528
245
|
{ ...lapisFilter, fields: [dateField] },
|
|
529
246
|
{
|
|
530
247
|
data: [
|
|
531
|
-
{ count: 1, [dateField]: '2023-01-
|
|
532
|
-
{ count: 2, [dateField]: '2023-
|
|
248
|
+
{ count: 1, [dateField]: '2023-01-05' },
|
|
249
|
+
{ count: 2, [dateField]: '2023-02-15' },
|
|
533
250
|
],
|
|
534
251
|
},
|
|
535
252
|
);
|
|
536
|
-
|
|
537
253
|
lapisRequestMocks.multipleMutations(
|
|
538
254
|
[
|
|
539
255
|
{
|
|
540
256
|
body: {
|
|
541
257
|
...lapisFilter,
|
|
542
|
-
dateFieldFrom: '2023-01-
|
|
543
|
-
dateFieldTo: '2023-
|
|
258
|
+
dateFieldFrom: '2023-01-01',
|
|
259
|
+
dateFieldTo: '2023-02-28',
|
|
544
260
|
minProportion: 0.001,
|
|
545
261
|
},
|
|
546
|
-
response: { data: [getSomeTestMutation(0.2, 2)] },
|
|
547
|
-
},
|
|
548
|
-
],
|
|
549
|
-
'nucleotide',
|
|
550
|
-
);
|
|
551
|
-
|
|
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
262
|
response: {
|
|
569
|
-
data:
|
|
570
|
-
data: [[{ count: 2, coverage: 10 }]],
|
|
571
|
-
dateRanges,
|
|
572
|
-
mutations: ['sequenceName:A123T'],
|
|
573
|
-
totalCountsByDateRange: [11],
|
|
574
|
-
},
|
|
263
|
+
data: [getSomeTestMutation(0.21, 6), getSomeOtherTestMutation(0.22, 4)],
|
|
575
264
|
},
|
|
576
265
|
},
|
|
577
266
|
],
|
|
578
267
|
'nucleotide',
|
|
579
268
|
);
|
|
580
269
|
|
|
581
|
-
const {
|
|
270
|
+
const { overallMutationData } = await queryMutationsOverTimeMetadata(
|
|
582
271
|
lapisFilter,
|
|
583
272
|
'nucleotide',
|
|
584
273
|
DUMMY_LAPIS_URL,
|
|
585
274
|
dateField,
|
|
586
|
-
'
|
|
275
|
+
'month',
|
|
276
|
+
['otherSequenceName:G234C', 'A122T'],
|
|
587
277
|
);
|
|
588
278
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
const sequences = mutationOverTimeData.getFirstAxisKeys();
|
|
594
|
-
expect(sequences[0].code).toBe('sequenceName:A123T');
|
|
595
|
-
|
|
596
|
-
const dates = mutationOverTimeData.getSecondAxisKeys();
|
|
597
|
-
expect(dates[0].dateString).toBe('2023-01-02');
|
|
279
|
+
// Only otherSequenceName:G234C was in the dataset; A122T gets count/proportion 0
|
|
280
|
+
expect(overallMutationData.map((m) => m.mutation.code)).to.deep.equal(['A122T', 'otherSequenceName:G234C']);
|
|
281
|
+
expect(overallMutationData.find((m) => m.mutation.code === 'A122T')?.proportion).toBe(0);
|
|
282
|
+
expect(overallMutationData.find((m) => m.mutation.code === 'otherSequenceName:G234C')?.proportion).toBe(0.22);
|
|
598
283
|
});
|
|
284
|
+
});
|
|
599
285
|
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
286
|
+
describe('queryMutationsOverTimePage', () => {
|
|
287
|
+
const threeDays = [yearMonthDay('2023-01-01'), yearMonthDay('2023-01-02'), yearMonthDay('2023-01-03')];
|
|
288
|
+
const twoDays = [yearMonthDay('2023-01-01'), yearMonthDay('2023-01-02')];
|
|
603
289
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
{ count: 2, [dateField]: '2023-02-15' },
|
|
610
|
-
],
|
|
611
|
-
},
|
|
612
|
-
);
|
|
290
|
+
const threeDayDateRanges = threeDays.map((d) => ({
|
|
291
|
+
dateFrom: d.firstDay.toString(),
|
|
292
|
+
dateTo: d.lastDay.toString(),
|
|
293
|
+
}));
|
|
294
|
+
const twoDayDateRanges = twoDays.map((d) => ({ dateFrom: d.firstDay.toString(), dateTo: d.lastDay.toString() }));
|
|
613
295
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
dateFieldFrom: '2023-01-01',
|
|
620
|
-
dateFieldTo: '2023-02-28',
|
|
621
|
-
minProportion: 0.001,
|
|
622
|
-
},
|
|
623
|
-
response: {
|
|
624
|
-
data: [getSomeTestMutation(0.21, 6), getSomeOtherTestMutation(0.22, 4)],
|
|
625
|
-
},
|
|
626
|
-
},
|
|
627
|
-
],
|
|
296
|
+
function callQueryMutationsOverTimePage(requestedDateRanges: typeof threeDays, includeMutations: string[]) {
|
|
297
|
+
return queryMutationsOverTimePage(
|
|
298
|
+
lapisFilter,
|
|
299
|
+
DUMMY_LAPIS_URL,
|
|
300
|
+
dateField,
|
|
628
301
|
'nucleotide',
|
|
302
|
+
requestedDateRanges,
|
|
303
|
+
includeMutations,
|
|
629
304
|
);
|
|
305
|
+
}
|
|
630
306
|
|
|
631
|
-
|
|
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
|
-
|
|
307
|
+
it('should build the data map with valueWithCoverage entries', async () => {
|
|
642
308
|
lapisRequestMocks.mutationsOverTime(
|
|
643
309
|
[
|
|
644
310
|
{
|
|
645
311
|
body: {
|
|
646
312
|
filters: lapisFilter,
|
|
647
|
-
dateRanges,
|
|
313
|
+
dateRanges: threeDayDateRanges,
|
|
648
314
|
includeMutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
|
|
649
315
|
dateField,
|
|
650
316
|
},
|
|
@@ -652,17 +318,19 @@ describe('queryMutationsOverTimeNewEndpoint', () => {
|
|
|
652
318
|
data: {
|
|
653
319
|
data: [
|
|
654
320
|
[
|
|
655
|
-
{ count:
|
|
656
|
-
{ count:
|
|
321
|
+
{ count: 4, coverage: 10 },
|
|
322
|
+
{ count: 0, coverage: 10 },
|
|
323
|
+
{ count: 0, coverage: 10 },
|
|
657
324
|
],
|
|
658
325
|
[
|
|
659
|
-
{ count:
|
|
660
|
-
{ count:
|
|
326
|
+
{ count: 1, coverage: 10 },
|
|
327
|
+
{ count: 2, coverage: 10 },
|
|
328
|
+
{ count: 3, coverage: 10 },
|
|
661
329
|
],
|
|
662
330
|
],
|
|
663
|
-
dateRanges,
|
|
331
|
+
dateRanges: threeDayDateRanges,
|
|
664
332
|
mutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
|
|
665
|
-
totalCountsByDateRange: [11, 12],
|
|
333
|
+
totalCountsByDateRange: [11, 12, 13],
|
|
666
334
|
},
|
|
667
335
|
},
|
|
668
336
|
},
|
|
@@ -670,150 +338,61 @@ describe('queryMutationsOverTimeNewEndpoint', () => {
|
|
|
670
338
|
'nucleotide',
|
|
671
339
|
);
|
|
672
340
|
|
|
673
|
-
const
|
|
674
|
-
|
|
675
|
-
'
|
|
676
|
-
|
|
677
|
-
dateField,
|
|
678
|
-
'month',
|
|
679
|
-
);
|
|
341
|
+
const result = await callQueryMutationsOverTimePage(threeDays, [
|
|
342
|
+
'otherSequenceName:G234C',
|
|
343
|
+
'sequenceName:A123T',
|
|
344
|
+
]);
|
|
680
345
|
|
|
681
|
-
expect(
|
|
682
|
-
[
|
|
683
|
-
{ type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 11 },
|
|
684
|
-
{ type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 12 },
|
|
685
|
-
],
|
|
346
|
+
expect(result.getAsArray()).to.deep.equal([
|
|
686
347
|
[
|
|
687
348
|
{ type: 'valueWithCoverage', count: 4, coverage: 10, totalCount: 11 },
|
|
688
|
-
{ type: 'valueWithCoverage', count:
|
|
349
|
+
{ type: 'valueWithCoverage', count: 0, coverage: 10, totalCount: 12 },
|
|
350
|
+
{ type: 'valueWithCoverage', count: 0, coverage: 10, totalCount: 13 },
|
|
689
351
|
],
|
|
690
|
-
]);
|
|
691
|
-
|
|
692
|
-
const sequences = mutationOverTimeData.getFirstAxisKeys();
|
|
693
|
-
expect(sequences[0].code).toBe('otherSequenceName:G234C');
|
|
694
|
-
expect(sequences[1].code).toBe('sequenceName:A123T');
|
|
695
|
-
|
|
696
|
-
const dates = mutationOverTimeData.getSecondAxisKeys();
|
|
697
|
-
expect(dates[0].dateString).toBe('2023-01');
|
|
698
|
-
expect(dates[1].dateString).toBe('2023-02');
|
|
699
|
-
});
|
|
700
|
-
|
|
701
|
-
it('should return empty data when there are no dates in filter', async () => {
|
|
702
|
-
const lapisFilter = { field1: 'value1', field2: 'value2' };
|
|
703
|
-
const dateField = 'dateField';
|
|
704
|
-
|
|
705
|
-
lapisRequestMocks.aggregated(
|
|
706
|
-
{ ...lapisFilter, fields: [dateField] },
|
|
707
|
-
{
|
|
708
|
-
data: [],
|
|
709
|
-
},
|
|
710
|
-
);
|
|
711
|
-
|
|
712
|
-
lapisRequestMocks.mutationsOverTime(
|
|
713
352
|
[
|
|
714
|
-
{
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
dateRanges: [],
|
|
718
|
-
includeMutations: [],
|
|
719
|
-
dateField,
|
|
720
|
-
},
|
|
721
|
-
response: {
|
|
722
|
-
data: {
|
|
723
|
-
data: [],
|
|
724
|
-
dateRanges: [],
|
|
725
|
-
mutations: [],
|
|
726
|
-
totalCountsByDateRange: [],
|
|
727
|
-
},
|
|
728
|
-
},
|
|
729
|
-
},
|
|
353
|
+
{ type: 'valueWithCoverage', count: 1, coverage: 10, totalCount: 11 },
|
|
354
|
+
{ type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 12 },
|
|
355
|
+
{ type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 13 },
|
|
730
356
|
],
|
|
731
|
-
|
|
732
|
-
)
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
'
|
|
740
|
-
);
|
|
741
|
-
|
|
742
|
-
expect(mutationOverTimeData.getAsArray()).to.deep.equal([]);
|
|
743
|
-
|
|
744
|
-
const sequences = mutationOverTimeData.getFirstAxisKeys();
|
|
745
|
-
expect(sequences.length).toBe(0);
|
|
746
|
-
|
|
747
|
-
const dates = mutationOverTimeData.getSecondAxisKeys();
|
|
748
|
-
expect(dates.length).toBe(0);
|
|
357
|
+
]);
|
|
358
|
+
expect(result.getFirstAxisKeys().map((m) => m.code)).to.deep.equal([
|
|
359
|
+
'otherSequenceName:G234C',
|
|
360
|
+
'sequenceName:A123T',
|
|
361
|
+
]);
|
|
362
|
+
expect(result.getSecondAxisKeys().map((d) => d.dateString)).to.deep.equal([
|
|
363
|
+
'2023-01-01',
|
|
364
|
+
'2023-01-02',
|
|
365
|
+
'2023-01-03',
|
|
366
|
+
]);
|
|
749
367
|
});
|
|
750
368
|
|
|
751
|
-
it('should
|
|
752
|
-
const lapisFilter = { field1: 'value1', field2: 'value2' };
|
|
753
|
-
const dateField = 'dateField';
|
|
754
|
-
|
|
755
|
-
lapisRequestMocks.aggregated(
|
|
756
|
-
{ ...lapisFilter, fields: [dateField] },
|
|
757
|
-
{
|
|
758
|
-
data: [
|
|
759
|
-
{ count: 1, [dateField]: '2023-01-05' },
|
|
760
|
-
{ count: 2, [dateField]: '2023-02-15' },
|
|
761
|
-
],
|
|
762
|
-
},
|
|
763
|
-
);
|
|
764
|
-
|
|
765
|
-
lapisRequestMocks.multipleMutations(
|
|
766
|
-
[
|
|
767
|
-
{
|
|
768
|
-
body: {
|
|
769
|
-
...lapisFilter,
|
|
770
|
-
dateFieldFrom: '2023-01-01',
|
|
771
|
-
dateFieldTo: '2023-02-28',
|
|
772
|
-
minProportion: 0.001,
|
|
773
|
-
},
|
|
774
|
-
response: {
|
|
775
|
-
data: [getSomeTestMutation(0.21, 6), getSomeOtherTestMutation(0.22, 4)],
|
|
776
|
-
},
|
|
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
|
-
|
|
369
|
+
it('should set cell to null when totalCount for a date range is zero', async () => {
|
|
793
370
|
lapisRequestMocks.mutationsOverTime(
|
|
794
371
|
[
|
|
795
372
|
{
|
|
796
373
|
body: {
|
|
797
374
|
filters: lapisFilter,
|
|
798
|
-
dateRanges,
|
|
799
|
-
includeMutations: ['
|
|
375
|
+
dateRanges: threeDayDateRanges,
|
|
376
|
+
includeMutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
|
|
800
377
|
dateField,
|
|
801
378
|
},
|
|
802
379
|
response: {
|
|
803
380
|
data: {
|
|
804
381
|
data: [
|
|
805
382
|
[
|
|
806
|
-
{ count:
|
|
807
|
-
{ count: 0, coverage:
|
|
383
|
+
{ count: 4, coverage: 10 },
|
|
384
|
+
{ count: 0, coverage: 10 },
|
|
385
|
+
{ count: 0, coverage: 10 },
|
|
808
386
|
],
|
|
809
387
|
[
|
|
810
|
-
{ count:
|
|
388
|
+
{ count: 1, coverage: 10 },
|
|
389
|
+
{ count: 0, coverage: 10 },
|
|
811
390
|
{ count: 3, coverage: 10 },
|
|
812
391
|
],
|
|
813
392
|
],
|
|
814
|
-
dateRanges,
|
|
815
|
-
mutations: ['
|
|
816
|
-
totalCountsByDateRange: [11,
|
|
393
|
+
dateRanges: threeDayDateRanges,
|
|
394
|
+
mutations: ['otherSequenceName:G234C', 'sequenceName:A123T'],
|
|
395
|
+
totalCountsByDateRange: [11, 0, 13],
|
|
817
396
|
},
|
|
818
397
|
},
|
|
819
398
|
},
|
|
@@ -821,84 +400,33 @@ describe('queryMutationsOverTimeNewEndpoint', () => {
|
|
|
821
400
|
'nucleotide',
|
|
822
401
|
);
|
|
823
402
|
|
|
824
|
-
const
|
|
825
|
-
|
|
826
|
-
'
|
|
827
|
-
|
|
828
|
-
dateField,
|
|
829
|
-
'month',
|
|
830
|
-
['otherSequenceName:G234C', 'A122T'],
|
|
831
|
-
);
|
|
403
|
+
const result = await callQueryMutationsOverTimePage(threeDays, [
|
|
404
|
+
'otherSequenceName:G234C',
|
|
405
|
+
'sequenceName:A123T',
|
|
406
|
+
]);
|
|
832
407
|
|
|
833
|
-
expect(
|
|
408
|
+
expect(result.getAsArray()).to.deep.equal([
|
|
834
409
|
[
|
|
835
|
-
{ type: '
|
|
836
|
-
|
|
410
|
+
{ type: 'valueWithCoverage', count: 4, coverage: 10, totalCount: 11 },
|
|
411
|
+
null,
|
|
412
|
+
{ type: 'valueWithCoverage', count: 0, coverage: 10, totalCount: 13 },
|
|
837
413
|
],
|
|
838
414
|
[
|
|
839
|
-
{ type: 'valueWithCoverage', count:
|
|
840
|
-
|
|
415
|
+
{ type: 'valueWithCoverage', count: 1, coverage: 10, totalCount: 11 },
|
|
416
|
+
null,
|
|
417
|
+
{ type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 13 },
|
|
841
418
|
],
|
|
842
419
|
]);
|
|
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');
|
|
851
420
|
});
|
|
852
421
|
|
|
853
|
-
it('should
|
|
854
|
-
const lapisFilter = { field1: 'value1', field2: 'value2' };
|
|
855
|
-
const dateField = 'dateField';
|
|
856
|
-
|
|
857
|
-
lapisRequestMocks.aggregated(
|
|
858
|
-
{ ...lapisFilter, fields: [dateField] },
|
|
859
|
-
{
|
|
860
|
-
data: [
|
|
861
|
-
{ count: 1, [dateField]: '2023-01-05' },
|
|
862
|
-
{ count: 2, [dateField]: '2023-02-15' },
|
|
863
|
-
],
|
|
864
|
-
},
|
|
865
|
-
);
|
|
866
|
-
|
|
867
|
-
lapisRequestMocks.multipleMutations(
|
|
868
|
-
[
|
|
869
|
-
{
|
|
870
|
-
body: {
|
|
871
|
-
...lapisFilter,
|
|
872
|
-
dateFieldFrom: '2023-01-01',
|
|
873
|
-
dateFieldTo: '2023-02-28',
|
|
874
|
-
minProportion: 0.001,
|
|
875
|
-
},
|
|
876
|
-
response: {
|
|
877
|
-
data: [getSomeTestMutation(0.21, 6), getSomeOtherTestMutation(0.22, 4)],
|
|
878
|
-
},
|
|
879
|
-
},
|
|
880
|
-
],
|
|
881
|
-
'nucleotide',
|
|
882
|
-
);
|
|
883
|
-
|
|
884
|
-
const dateRanges = [
|
|
885
|
-
{
|
|
886
|
-
dateFrom: '2023-01-01',
|
|
887
|
-
dateTo: '2023-01-31',
|
|
888
|
-
},
|
|
889
|
-
{
|
|
890
|
-
dateFrom: '2023-02-01',
|
|
891
|
-
dateTo: '2023-02-28',
|
|
892
|
-
},
|
|
893
|
-
];
|
|
894
|
-
|
|
422
|
+
it('should set cell to belowThreshold when coverage is zero', async () => {
|
|
895
423
|
lapisRequestMocks.mutationsOverTime(
|
|
896
424
|
[
|
|
897
425
|
{
|
|
898
426
|
body: {
|
|
899
427
|
filters: lapisFilter,
|
|
900
|
-
dateRanges,
|
|
901
|
-
includeMutations: ['
|
|
428
|
+
dateRanges: twoDayDateRanges,
|
|
429
|
+
includeMutations: ['sequenceName:A123T'],
|
|
902
430
|
dateField,
|
|
903
431
|
},
|
|
904
432
|
response: {
|
|
@@ -906,15 +434,11 @@ describe('queryMutationsOverTimeNewEndpoint', () => {
|
|
|
906
434
|
data: [
|
|
907
435
|
[
|
|
908
436
|
{ count: 0, coverage: 0 },
|
|
909
|
-
{ count: 0, coverage: 0 },
|
|
910
|
-
],
|
|
911
|
-
[
|
|
912
437
|
{ count: 2, coverage: 10 },
|
|
913
|
-
{ count: 3, coverage: 10 },
|
|
914
438
|
],
|
|
915
439
|
],
|
|
916
|
-
dateRanges,
|
|
917
|
-
mutations: ['
|
|
440
|
+
dateRanges: twoDayDateRanges,
|
|
441
|
+
mutations: ['sequenceName:A123T'],
|
|
918
442
|
totalCountsByDateRange: [11, 12],
|
|
919
443
|
},
|
|
920
444
|
},
|
|
@@ -923,56 +447,57 @@ describe('queryMutationsOverTimeNewEndpoint', () => {
|
|
|
923
447
|
'nucleotide',
|
|
924
448
|
);
|
|
925
449
|
|
|
926
|
-
const
|
|
927
|
-
lapisFilter,
|
|
928
|
-
'nucleotide',
|
|
929
|
-
DUMMY_LAPIS_URL,
|
|
930
|
-
dateField,
|
|
931
|
-
'month',
|
|
932
|
-
['otherSequenceName:G234C', '122'],
|
|
933
|
-
);
|
|
450
|
+
const result = await callQueryMutationsOverTimePage(twoDays, ['sequenceName:A123T']);
|
|
934
451
|
|
|
935
|
-
expect(
|
|
452
|
+
expect(result.getAsArray()).to.deep.equal([
|
|
936
453
|
[
|
|
937
454
|
{ type: 'belowThreshold', totalCount: 11 },
|
|
938
|
-
{ type: '
|
|
939
|
-
],
|
|
940
|
-
[
|
|
941
|
-
{ type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 11 },
|
|
942
|
-
{ type: 'valueWithCoverage', count: 3, coverage: 10, totalCount: 12 },
|
|
455
|
+
{ type: 'valueWithCoverage', count: 2, coverage: 10, totalCount: 12 },
|
|
943
456
|
],
|
|
944
457
|
]);
|
|
458
|
+
});
|
|
945
459
|
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
expect(sequences[1].code).toBe('otherSequenceName:G234C');
|
|
460
|
+
it('should return an empty map with date columns when no mutations are requested', async () => {
|
|
461
|
+
const result = await callQueryMutationsOverTimePage(threeDays, []);
|
|
949
462
|
|
|
950
|
-
|
|
951
|
-
expect(
|
|
952
|
-
expect(
|
|
463
|
+
expect(result.getAsArray()).to.deep.equal([]);
|
|
464
|
+
expect(result.getFirstAxisKeys()).to.deep.equal([]);
|
|
465
|
+
expect(result.getSecondAxisKeys().map((d) => d.dateString)).to.deep.equal([
|
|
466
|
+
'2023-01-01',
|
|
467
|
+
'2023-01-02',
|
|
468
|
+
'2023-01-03',
|
|
469
|
+
]);
|
|
953
470
|
});
|
|
954
471
|
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
mutation: 'sequenceName:A123T',
|
|
958
|
-
proportion,
|
|
959
|
-
count,
|
|
960
|
-
sequenceName: 'sequenceName',
|
|
961
|
-
mutationFrom: 'A',
|
|
962
|
-
mutationTo: 'T',
|
|
963
|
-
position: 123,
|
|
964
|
-
};
|
|
965
|
-
}
|
|
472
|
+
it('should return an empty map when requestedDateRanges is empty', async () => {
|
|
473
|
+
const result = await callQueryMutationsOverTimePage([], ['sequenceName:A123T']);
|
|
966
474
|
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
count,
|
|
972
|
-
sequenceName: 'otherSequenceName',
|
|
973
|
-
mutationFrom: 'G',
|
|
974
|
-
mutationTo: 'C',
|
|
975
|
-
position: 234,
|
|
976
|
-
};
|
|
977
|
-
}
|
|
475
|
+
expect(result.getAsArray()).to.deep.equal([]);
|
|
476
|
+
expect(result.getFirstAxisKeys()).to.deep.equal([]);
|
|
477
|
+
expect(result.getSecondAxisKeys()).to.deep.equal([]);
|
|
478
|
+
});
|
|
978
479
|
});
|
|
480
|
+
|
|
481
|
+
function getSomeTestMutation(proportion: number, count: number) {
|
|
482
|
+
return {
|
|
483
|
+
mutation: 'sequenceName:A123T',
|
|
484
|
+
proportion,
|
|
485
|
+
count,
|
|
486
|
+
sequenceName: 'sequenceName',
|
|
487
|
+
mutationFrom: 'A',
|
|
488
|
+
mutationTo: 'T',
|
|
489
|
+
position: 123,
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
function getSomeOtherTestMutation(proportion: number, count: number) {
|
|
494
|
+
return {
|
|
495
|
+
mutation: 'otherSequenceName:G234C',
|
|
496
|
+
proportion,
|
|
497
|
+
count,
|
|
498
|
+
sequenceName: 'otherSequenceName',
|
|
499
|
+
mutationFrom: 'G',
|
|
500
|
+
mutationTo: 'C',
|
|
501
|
+
position: 234,
|
|
502
|
+
};
|
|
503
|
+
}
|