diff --git a/lib/importer/package-lock.json b/lib/importer/package-lock.json index ea07d061..c79a0919 100644 --- a/lib/importer/package-lock.json +++ b/lib/importer/package-lock.json @@ -2702,16 +2702,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/@eslint/js": { - "version": "9.23.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.23.0.tgz", - "integrity": "sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", diff --git a/lib/importer/src/config.js b/lib/importer/src/config.js index b723fa40..ff4fa9e7 100644 --- a/lib/importer/src/config.js +++ b/lib/importer/src/config.js @@ -31,6 +31,11 @@ exports.PluginConfig = class { this.uploadPath = config.uploadPath; this.uploadPathDefault = false; + // Should we auto-select a sheet when there is only one sheet? + // manual - No, always select a sheet even if there is only one. + // automatic - Yes, always use the single sheet when there is only one. + this.sheetSelection = config.sheetSelection || "automatic"; + // If the config fields are in the old format (just names) then move them to // the new structure with default values of text for the type, and not required. if (this.fields.find(Boolean)) { @@ -77,10 +82,18 @@ exports.PluginConfig = class { } }; + setSheetSelection = (mode) => { + if (!["manual", "automatic"].includes(mode)) { + throw (`'${mode}' is not a valid sheet selection mode`) + } + this.sheetSelection = mode + } + as_object = () => { return { uploadPath: this.uploadPathDefault ? TEMP_DIRECTORY_LABEL : this.uploadPath, - fields: this.fields + fields: this.fields, + sheetSelection: this.sheetSelection } } @@ -95,6 +108,7 @@ exports.PluginConfig = class { let current = fse.readJsonSync(configFilePath); current.fields = this.fields; + current.sheetSelection = this.sheetSelection fse.writeJsonSync(configFilePath, current); }; diff --git a/lib/importer/src/config.test.js b/lib/importer/src/config.test.js index 8679bfe9..75e3ee18 100644 --- a/lib/importer/src/config.test.js +++ b/lib/importer/src/config.test.js @@ -35,6 +35,9 @@ describe("Configuration tests", () => { expect(original.uploadPath).not.toBeNull() expect(updated.uploadPath).not.toBeNull() expect(c.uploadPath).not.toBeNull() + + expect(updated.sheetSelection).not.toBeNull() + expect(updated.sheetSelection).toStrictEqual("automatic") } ); @@ -132,6 +135,68 @@ describe("Configuration tests", () => { mock_files.restore(); }); + test('manual sheet selection', () => { + mock_files({ + './fields/app/config.json': '{"fields": [{"name":"A"}, {"name": "B"}, {"name": "C"}]}', + }) + + withCurrent( + "./fields", + new cfg.PluginConfig(), + (c) => { + c.setSheetSelection("manual") + c.persistConfig() + }, + (original, updated) => { + expect(updated.sheetSelection).toStrictEqual("manual") + } + ); + + mock_files.restore(); + }); + + test('default sheet selection', () => { + mock_files({ + './fields/app/config.json': '{"fields": [{"name":"A"}, {"name": "B"}, {"name": "C"}]}', + }) + + withCurrent( + "./fields", + new cfg.PluginConfig(), + (c) => { + c.persistConfig() + }, + (original, updated) => { + expect(updated.sheetSelection).toStrictEqual("automatic") + } + ); + + mock_files.restore(); + }); + + + test('invalid sheet selection', () => { + mock_files({ + './fields/app/config.json': '{"fields": [{"name":"A"}, {"name": "B"}, {"name": "C"}]}', + }) + + withCurrent( + "./fields", + new cfg.PluginConfig(), + (c) => { + expect(() => { + c.setSheetSelection("invalid") + } + ).toThrow("'invalid' is not a valid sheet selection mode") + c.persistConfig() + }, + (original, updated) => { + expect(updated.sheetSelection).toStrictEqual("automatic") + } + ); + + mock_files.restore(); + }); }) diff --git a/lib/importer/src/index.js b/lib/importer/src/index.js index 70732529..254ebfd5 100644 --- a/lib/importer/src/index.js +++ b/lib/importer/src/index.js @@ -99,7 +99,11 @@ exports.Initialise = (config, router, prototypeKit) => { prototypeKit.views.addFunction( k, - (next) => { + (next, other = null) => { + if (next && other) { + return `${v}?next=${encodeURIComponent(next)}&other=${encodeURIComponent(other)}`; + } + return `${v}?next=${encodeURIComponent(next)}`; }, {}, @@ -164,8 +168,15 @@ exports.Initialise = (config, router, prototypeKit) => { if (session.sheets.length == 1) { session.sheet = session.sheets[0]; - } + // When there is only a single sheet, and if the prototype is configured to + // automatically progress, then this will do so if the 'other' url is + // specified. + if (plugin_config.sheetSelection.toLowerCase() == "automatic" && "other" in request.query) { + const otherPage = decodeURIComponent(request.query.other) + if (otherPage) { request.query.next = request.query.other } + } + } // Ensure the session is persisted. Currently in session, eventually another way request.session.data[IMPORTER_SESSION_KEY] = session; redirectOnwards(request, response); diff --git a/lib/importer/templates/upload.html b/lib/importer/templates/upload.html index b442b36c..4947f9bd 100644 --- a/lib/importer/templates/upload.html +++ b/lib/importer/templates/upload.html @@ -12,7 +12,7 @@

Upload your data

-
+
{{ govukFileUpload({ id: "file-upload", diff --git a/prototypes/basic/app/config.json b/prototypes/basic/app/config.json index fa79cfcb..90c4e9f6 100644 --- a/prototypes/basic/app/config.json +++ b/prototypes/basic/app/config.json @@ -1,45 +1,46 @@ { - "serviceName": "Upload monthly pension return", - "fields": [ - { - "name": "Title", - "required": false, - "type": "text" - }, - { - "name": "First name", - "required": false, - "type": "text" - }, - { - "name": "Surname", - "required": false, - "type": "text" - }, - { - "name": "Employee number", - "required": false, - "type": "text" - }, - { - "name": "Employment start date", - "required": false, - "type": "text" - }, - { - "name": "Salary", - "required": false, - "type": "number" - }, - { - "name": "Contribution percentage", - "required": false, - "type": "text" - }, - { - "name": "Payment date", - "required": false, - "type": "text" - } - ] + "serviceName": "Upload monthly pension return", + "sheetSelection": "manual", + "fields": [ + { + "name": "Title", + "type": "text", + "required": false + }, + { + "name": "First name", + "type": "text", + "required": false + }, + { + "name": "Surname", + "type": "text", + "required": false + }, + { + "name": "Employee number", + "type": "text", + "required": false + }, + { + "name": "Employment start date", + "type": "text", + "required": false + }, + { + "name": "Salary", + "type": "number", + "required": false + }, + { + "name": "Contribution percentage", + "type": "text", + "required": false + }, + { + "name": "Payment date", + "type": "text", + "required": false + } + ] } diff --git a/prototypes/basic/app/views/upload.html b/prototypes/basic/app/views/upload.html index b5f2ce8e..1921d508 100644 --- a/prototypes/basic/app/views/upload.html +++ b/prototypes/basic/app/views/upload.html @@ -56,7 +56,7 @@

Check your dates

- +
{{ govukFileUpload({ id: "file-upload", diff --git a/prototypes/basic/playwright.config.js b/prototypes/basic/playwright.config.js index 1538f82d..58e1fd31 100644 --- a/prototypes/basic/playwright.config.js +++ b/prototypes/basic/playwright.config.js @@ -3,15 +3,38 @@ import { defineConfig, devices } from '@playwright/test'; export default defineConfig({ workers: 1, testDir: './tests', - reporter: process.env.CI ? [['github'], ['junit', {outputFile: "./test-results/results.xml"}]] : 'line', - use: { - baseURL: 'http://127.0.0.1:3000', - }, + reporter: process.env.CI ? [['github'], ['junit', { outputFile: "./test-results/results.xml" }]] : 'line', + // use: { + // baseURL: 'http://127.0.0.1:3000', + // }, + projects: [ + { + name: 'simple-tests', + use: { + baseURL: 'http://localhost:3000', + }, + testDir: './tests/simple', + }, + { + name: 'sheet-selection-auto', + use: { + baseURL: 'http://localhost:3000', + }, + testDir: './tests/sheet-selection-auto', + }, + { + name: 'sheet-selection-manual', + use: { + baseURL: 'http://localhost:3000', + }, + testDir: './tests/sheet-selection-manual', + }, + ], webServer: { command: 'npm run dev', url: 'http://127.0.0.1:3000', reuseExistingServer: !process.env.CI, stdout: 'pipe', stderr: 'pipe', - } + } }); diff --git a/prototypes/basic/tests/sheet-selection-auto/.gitkeep b/prototypes/basic/tests/sheet-selection-auto/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/prototypes/basic/tests/sheet-selection-manual/.gitkeep b/prototypes/basic/tests/sheet-selection-manual/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/prototypes/basic/tests/simple.spec.js b/prototypes/basic/tests/simple/simple.spec.js similarity index 100% rename from prototypes/basic/tests/simple.spec.js rename to prototypes/basic/tests/simple/simple.spec.js diff --git a/prototypes/basic/tests/small-file.spec.js b/prototypes/basic/tests/simple/small-file.spec.js similarity index 89% rename from prototypes/basic/tests/small-file.spec.js rename to prototypes/basic/tests/simple/small-file.spec.js index 358585b9..f993b4cc 100644 --- a/prototypes/basic/tests/small-file.spec.js +++ b/prototypes/basic/tests/simple/small-file.spec.js @@ -1,12 +1,12 @@ import { test, expect } from '@playwright/test'; -import * as fixtures from "./helpers/fixtures"; +import * as fixtures from "../helpers/fixtures"; -import { UploadPage } from './helpers/upload_page'; -import { SheetSelectorPage } from './helpers/sheet_selector_page'; -import { HeaderSelectorPage } from './helpers/header_selector_page'; -import { FooterSelectorPage } from './helpers/footer_selector_page' -import { MappingPage } from './helpers/mapping_page' +import { UploadPage } from '../helpers/upload_page'; +import { SheetSelectorPage } from '../helpers/sheet_selector_page'; +import { HeaderSelectorPage } from '../helpers/header_selector_page'; +import { FooterSelectorPage } from '../helpers/footer_selector_page' +import { MappingPage } from '../helpers/mapping_page' const path = require('node:path'); diff --git a/prototypes/basic/tests/tribbles.spec.js b/prototypes/basic/tests/simple/tribbles.spec.js similarity index 91% rename from prototypes/basic/tests/tribbles.spec.js rename to prototypes/basic/tests/simple/tribbles.spec.js index 777d28f0..8f4d362e 100644 --- a/prototypes/basic/tests/tribbles.spec.js +++ b/prototypes/basic/tests/simple/tribbles.spec.js @@ -1,12 +1,12 @@ import { test, expect } from '@playwright/test'; -import * as fixtures from "./helpers/fixtures"; +import * as fixtures from "../helpers/fixtures"; -import { UploadPage } from './helpers/upload_page'; -import { SheetSelectorPage } from './helpers/sheet_selector_page'; -import { HeaderSelectorPage } from './helpers/header_selector_page'; -import { FooterSelectorPage } from './helpers/footer_selector_page' -import { MappingPage } from './helpers/mapping_page' +import { UploadPage } from '../helpers/upload_page'; +import { SheetSelectorPage } from '../helpers/sheet_selector_page'; +import { HeaderSelectorPage } from '../helpers/header_selector_page'; +import { FooterSelectorPage } from '../helpers/footer_selector_page' +import { MappingPage } from '../helpers/mapping_page' const path = require('node:path');