Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 84 additions & 37 deletions app/views/EditTutorial/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ describe('getValidReferenceValues', () => {
it('skips options without a value along with their sub-options', () => {
expect(getValidReferenceValues([
{ subOptions: [{ value: 5 }] },
])).toBeUndefined();
])).toEqual([]);
});

it('returns undefined for missing or empty options', () => {
expect(getValidReferenceValues(undefined)).toBeUndefined();
expect(getValidReferenceValues(null)).toBeUndefined();
expect(getValidReferenceValues([])).toBeUndefined();
it('returns an empty array for missing or empty options', () => {
expect(getValidReferenceValues(undefined)).toEqual([]);
expect(getValidReferenceValues(null)).toEqual([]);
expect(getValidReferenceValues([])).toEqual([]);
});
});

Expand Down Expand Up @@ -236,7 +236,7 @@ describe('transformFindGeoJson', () => {
return;
}

expect(result.error).toContain('expected to have 6 instances');
expect(result.error).toContain('expected to have 6 instance(s)');
});

it('rejects non-serial screens', () => {
Expand Down Expand Up @@ -306,20 +306,20 @@ describe('transformStreetGeoJson', () => {
});

describe('transformCompareGeoJson', () => {
it('accepts repeated screens and maps compare specifics', () => {
it('maps each feature to its own scenario page, sorted by screen', () => {
const result = transformCompareGeoJson(createFeatureCollection([
{
screen: 1,
reference: 0,
tile_x: 1,
tile_y: 2,
screen: 2,
reference: 1,
tile_x: 3,
tile_y: 4,
tile_z: 18,
},
{
screen: 1,
reference: 1,
tile_x: 3,
tile_y: 4,
reference: 0,
tile_x: 1,
tile_y: 2,
tile_z: 18,
},
]));
Expand All @@ -329,8 +329,11 @@ describe('transformCompareGeoJson', () => {
return;
}

expect(result.scenarioPages).toHaveLength(1);
expect(result.scenarioPages[0].tasks).toHaveLength(2);
expect(result.scenarioPages.map(
(page) => page.scenarioPageNumber,
)).toEqual([1, 2]);
expect(result.scenarioPages[0].tasks).toHaveLength(1);
expect(result.scenarioPages[1].tasks).toHaveLength(1);

const [task] = result.scenarioPages[0].tasks ?? [];
expect(task.projectTypeSpecifics?.compare).toEqual({
Expand All @@ -340,66 +343,95 @@ describe('transformCompareGeoJson', () => {
});
});

it('rejects non-serial screens', () => {
it('rejects screens with more than one feature', () => {
const result = transformCompareGeoJson(createFeatureCollection([
{
screen: 2,
screen: 1,
reference: 0,
tile_x: 1,
tile_y: 2,
tile_z: 18,
},
{
screen: 1,
reference: 1,
tile_x: 3,
tile_y: 4,
tile_z: 18,
},
]));

expect(result.ok).toBe(false);
if (result.ok) {
return;
}

expect(result.error).toContain('screens must be serial');
expect(result.error).toContain('expected to have 1 instance(s)');
});
});

describe('transformCompletenessGeoJson', () => {
it('accepts repeated screens and maps completeness specifics', () => {
const result = transformCompletenessGeoJson(createFeatureCollection([
it('rejects non-serial screens', () => {
const result = transformCompareGeoJson(createFeatureCollection([
{
screen: 1,
screen: 2,
reference: 0,
tile_x: 1,
tile_y: 2,
tile_z: 18,
},
{
screen: 1,
reference: 1,
tile_x: 3,
tile_y: 4,
tile_z: 18,
},
]));

expect(result.ok).toBe(false);
if (result.ok) {
return;
}

expect(result.error).toContain('screens must be serial');
});
});

describe('transformCompletenessGeoJson', () => {
// tile_x encodes the screen so mis-grouped tasks are detectable
const makeScreen = (screen: number) => Array.from(
new Array(6).keys(),
).map((i) => ({
screen,
reference: i % 2,
tile_x: screen * 100 + i,
tile_y: 20 + i,
tile_z: 18,
}));

it('groups features by screen into sorted scenario pages', () => {
const result = transformCompletenessGeoJson(createFeatureCollection([
...makeScreen(2),
...makeScreen(1),
]));

expect(result.ok).toBe(true);
if (!result.ok) {
return;
}

expect(result.scenarioPages).toHaveLength(1);
expect(result.scenarioPages[0].tasks).toHaveLength(2);
expect(result.scenarioPages.map(
(page) => page.scenarioPageNumber,
)).toEqual([1, 2]);

expect(result.scenarioPages[0].tasks).toHaveLength(6);
expect(result.scenarioPages[1].tasks).toHaveLength(6);

const [task] = result.scenarioPages[0].tasks ?? [];
expect(task.projectTypeSpecifics?.completeness).toEqual({
tileX: 1,
tileY: 2,
tileX: 100,
tileY: 20,
tileZ: 18,
});
});

it('rejects reference values outside the tile options', () => {
it('rejects screens without exactly 6 features', () => {
const result = transformCompletenessGeoJson(createFeatureCollection([
{
screen: 1,
reference: 9,
reference: 0,
tile_x: 1,
tile_y: 2,
tile_z: 18,
Expand All @@ -411,6 +443,21 @@ describe('transformCompletenessGeoJson', () => {
return;
}

expect(result.error).toContain('expected to have 6 instance(s)');
});

it('rejects reference values outside the tile options', () => {
const [first, ...others] = makeScreen(1);
const result = transformCompletenessGeoJson(createFeatureCollection([
{ ...first, reference: 9 },
...others,
]));

expect(result.ok).toBe(false);
if (result.ok) {
return;
}

expect(result.error).toContain('invalid reference value(s): 9 for screen 1');
});
});
Expand Down
2 changes: 1 addition & 1 deletion app/views/EditTutorial/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ export function transformCompletenessGeoJson(
return { ok: false, error: result.summary };
}

const problems = checkTileGroupedFeatures(result.features, 1);
const problems = checkTileGroupedFeatures(result.features, 6);
if (problems.length > 0) {
return { ok: false, error: problems.join('\n') };
}
Expand Down
Loading