Skip to content

Commit f2b7633

Browse files
authored
Merge pull request #263 from commonknowledge/fix/migrantdemo-fixes
fix: add import data test and ignore spaces in numeric data
2 parents 9c3a8b8 + c073082 commit f2b7633

File tree

6 files changed

+144
-39
lines changed

6 files changed

+144
-39
lines changed

src/server/jobs/importDataSource.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,10 @@ const parseNumber = (value: unknown): number => {
207207
};
208208

209209
/**
210-
* Replace terminating % and commas
210+
* Replace terminating % and all commas and spaces
211211
*/
212212
const cleanNumber = (value: string): string => {
213-
return value.trim().replace(/%$/, "").replace(/,/g, "");
213+
return value.trim().replace(/%$/, "").replace(/,/g, "").replace(/ /g, "");
214214
};
215215

216216
const addColumnDefs = (

tests/feature/importDataSource.test.ts

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
1-
import { describe, expect, test } from "vitest";
1+
import { afterAll, describe, expect, test } from "vitest";
22
import importDataSource from "@/server/jobs/importDataSource";
33
import { AreaSetCode } from "@/server/models/AreaSet";
44
import {
5+
ColumnType,
56
DataSourceRecordType,
67
DataSourceType,
78
GeocodingType,
89
} from "@/server/models/DataSource";
9-
import { FilterType } from "@/server/models/MapView";
10+
import { CalculationType, FilterType } from "@/server/models/MapView";
1011
import { streamDataRecordsByDataSource } from "@/server/repositories/DataRecord";
1112
import {
1213
createDataSource,
1314
deleteDataSource,
15+
findDataSourceById,
1416
} from "@/server/repositories/DataSource";
1517
import { upsertOrganisation } from "@/server/repositories/Organisation";
18+
import { getAreaStats } from "@/server/stats";
1619

1720
describe("importDataSource tests", () => {
21+
const toRemove: string[] = [];
22+
1823
test("importDataSource imports records from CSV", async () => {
1924
// 1. Create test organisation
2025
const org = await upsertOrganisation({
@@ -26,7 +31,7 @@ describe("importDataSource tests", () => {
2631
name: "Test Import CSV Source",
2732
autoEnrich: false,
2833
autoImport: false,
29-
recordType: DataSourceRecordType.Data,
34+
recordType: DataSourceRecordType.Members,
3035
config: {
3136
type: DataSourceType.CSV,
3237
url: "file://tests/resources/members.csv",
@@ -43,6 +48,8 @@ describe("importDataSource tests", () => {
4348
public: false,
4449
});
4550

51+
toRemove.push(dataSource.id);
52+
4653
// 3. Call importDataSource
4754
await importDataSource({ dataSourceId: dataSource.id });
4855

@@ -126,4 +133,86 @@ describe("importDataSource tests", () => {
126133
},
127134
]);
128135
});
136+
137+
test("importDataSource imports stats from CSV", async () => {
138+
// 1. Create test organisation
139+
const org = await upsertOrganisation({
140+
name: "Test Import Org",
141+
});
142+
143+
// 2. Create test data source with CSV file
144+
const dataSource = await createDataSource({
145+
name: "Test Import Stats CSV Source",
146+
autoEnrich: false,
147+
autoImport: false,
148+
recordType: DataSourceRecordType.Data,
149+
config: {
150+
type: DataSourceType.CSV,
151+
url: "file://tests/resources/stats.csv",
152+
},
153+
columnDefs: [],
154+
columnRoles: { nameColumns: [] },
155+
enrichments: [],
156+
geocodingConfig: {
157+
type: GeocodingType.Code,
158+
column: "Code",
159+
areaSetCode: AreaSetCode.WMC24,
160+
},
161+
organisationId: org.id,
162+
public: false,
163+
});
164+
165+
toRemove.push(dataSource.id);
166+
167+
// 3. Call importDataSource
168+
await importDataSource({ dataSourceId: dataSource.id });
169+
170+
const importedDataSource = await findDataSourceById(dataSource.id);
171+
const columnDefs = importedDataSource?.columnDefs;
172+
columnDefs?.sort((a, b) => (a.name < b.name ? -1 : 1));
173+
174+
expect(columnDefs).toEqual([
175+
{ name: "Code", type: ColumnType.String },
176+
{ name: "Electorate", type: ColumnType.Number },
177+
{ name: "Name", type: ColumnType.String },
178+
]);
179+
180+
const areaStats = await getAreaStats({
181+
areaSetCode: AreaSetCode.WMC24,
182+
dataSourceId: dataSource.id,
183+
calculationType: CalculationType.Sum,
184+
column: "Electorate",
185+
excludeColumns: [],
186+
});
187+
188+
const stats = areaStats.primary?.stats;
189+
stats?.sort((a, b) => (a.areaCode < b.areaCode ? -1 : 1));
190+
191+
// Remove stats array from main equality check
192+
areaStats.primary = undefined;
193+
194+
expect(areaStats).toEqual({
195+
areaSetCode: AreaSetCode.WMC24,
196+
calculationType: CalculationType.Sum,
197+
dataSourceId: dataSource.id,
198+
primary: undefined,
199+
});
200+
201+
expect(stats).toEqual([
202+
{
203+
areaCode: "E14001070",
204+
value: 71002,
205+
},
206+
{
207+
areaCode: "E14001071",
208+
value: 79169,
209+
},
210+
]);
211+
});
212+
213+
afterAll(async () => {
214+
for (const id of toRemove) {
215+
await deleteDataSource(id);
216+
}
217+
});
129218
}, 10000);

0 commit comments

Comments
 (0)