Skip to content

Commit

Permalink
Fix stale data when clicking back button to stateless app (#2565)
Browse files Browse the repository at this point in the history
* disabling cache of formdata when in a stateless app
  • Loading branch information
adamhaeger authored Oct 17, 2024
1 parent c830203 commit 530b0f3
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 116 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"gen": "node -r ts-node/register/transpile-only -r tsconfig-paths/register src/codegen/run.ts",
"gen:clean": "node -r ts-node/register/transpile-only -r tsconfig-paths/register src/codegen/clean-generated.ts --empty-only",
"gen:clean:all": "node -r ts-node/register/transpile-only -r tsconfig-paths/register src/codegen/clean-generated.ts",
"gen:restore": "yarn gen:clean:all && yarn gen",
"copy-schemas": "node -r ts-node/register/transpile-only -r tsconfig-paths/register scripts/copy-schemas.ts",
"start": "yarn gen && cross-env NODE_ENV=development webpack-dev-server --config webpack.config.development.js --mode development --progress",
"build": "yarn gen && yarn copy-schemas && cross-env NODE_ENV=production webpack --config webpack.config.production.js --progress",
Expand All @@ -36,7 +37,7 @@
"@babel/runtime-corejs3": "^7.21.0",
"@eslint/compat": "^1.1.1",
"@faker-js/faker": "^9.0.0",
"@percy/cli": "^1.26.0",
"@percy/cli": "^1.30.1",
"@percy/cypress": "^3.1.2",
"@pmmmwh/react-refresh-webpack-plugin": "0.5.15",
"@tanstack/react-query-devtools": "^5.25.0",
Expand Down
27 changes: 13 additions & 14 deletions src/features/formData/FormData.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -543,32 +543,31 @@ describe('FormData', () => {
const { mutations, queries } = await render();

await user.type(screen.getByTestId('obj2.prop1'), 'a');
await user.tab();
expect(screen.getByTestId('obj2.prop1')).toHaveValue('a');
expect(screen.getByTestId('hasUnsavedChanges')).toHaveTextContent('true');

expect(queries.fetchFormData).toHaveBeenCalledTimes(1);

// Pretending to handle the save operation
await waitFor(() => expect(mutations.doPostStatelessFormData.mock).toHaveBeenCalledTimes(1));
mutations.doPostStatelessFormData.resolve({ obj2: { prop1: 'a' } });

await waitFor(() => expect(screen.getByTestId('hasUnsavedChanges')).toHaveTextContent('false'));

await user.click(screen.getByRole('button', { name: 'Navigate to a different page' }));
await screen.findByText('something different');

// We have to resolve the save operation, as otherwise 'hasUnsavedChanges' will be 'true' when we navigate back
// as otherwise it would still be working on saving the form data (and form data is marked as unsaved until the
// save operation is finished).
expect(mutations.doPostStatelessFormData.mock).toHaveBeenCalledTimes(1);
mutations.doPostStatelessFormData.resolve();

await user.click(screen.getByRole('button', { name: 'Navigate back' }));
await screen.findByTestId('obj2.prop1');

// No need to re-fetch anymore, as the query cache is updated with the saved form data. This used to expect 2
// calls to fetchFormData, but now it's only 1.
expect(queries.fetchFormData).toHaveBeenCalledTimes(1);
// We tried to cache the form data, however that broke back button functionality for some apps.
// See this issue: https://github.com/Altinn/app-frontend-react/issues/2564
// Also see src/features/formData/useFormDataQuery.tsx where we prevent caching for statless apps
expect(queries.fetchFormData).toHaveBeenCalledTimes(2);

// No need to save the form data again, as it was already saved and nothing has changed since then.
expect(screen.getByTestId('obj2.prop1')).toHaveValue('a');
// Our mock fetchFormData returns an empty object, so the form data should be reset. Realistically, the form data
// would be restored when fetching it from the server, as we asserted that it was saved before navigating away.
expect(screen.getByTestId('obj2.prop1')).toHaveValue('');
expect(screen.getByTestId('hasUnsavedChanges')).toHaveTextContent('false');
expect(mutations.doPostStatelessFormData.mock).toHaveBeenCalledTimes(1);
});
});
});
17 changes: 15 additions & 2 deletions src/features/formData/useFormDataQuery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,23 @@ export function useFormDataQueryDef(url: string | undefined): QueryDefinition<un
const { fetchFormData } = useAppQueries();
const queryKey = useFormDataQueryKey(url);
const options = useFormDataQueryOptions();
const isStateless = useApplicationMetadata().isStatelessApp;

const queryFn = url ? () => fetchFormData(url, options) : skipToken;

if (isStateless) {
// We need to refetch for stateless apps as caching will break some apps.
// See this issue: https://github.com/Altinn/app-frontend-react/issues/2564
return {
queryKey,
queryFn,
gcTime: 0,
};
}

return {
queryKey,
queryFn: url ? () => fetchFormData(url, options) : skipToken,
enabled: !!url,
queryFn,
refetchInterval: false,
};
}
Expand Down
5 changes: 2 additions & 3 deletions test/e2e/integration/stateless-app/stateless.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,8 @@ describe('Stateless', () => {
cy.get(appFrontend.stateless.number).clear();
cy.get(appFrontend.stateless.number).type('6789');
cy.get(appFrontend.instantiationButton).click();
cy.findByRole('textbox', { name: /id/i }).should('have.value', '1364'); // Make sure we are on the correct page
cy.get('#sendInButton').should('exist');
cy.window().then((win) => win.history.back());
cy.get(appFrontend.stateless.name).should('have.value', 'hello world');
cy.get(appFrontend.stateless.number).should('have.value', '6789');
cy.get(appFrontend.instantiationButton).should('exist');
});
});
192 changes: 96 additions & 96 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2883,131 +2883,131 @@ __metadata:
languageName: node
linkType: hard

"@percy/cli-app@npm:1.30.0":
version: 1.30.0
resolution: "@percy/cli-app@npm:1.30.0"
"@percy/cli-app@npm:1.30.1":
version: 1.30.1
resolution: "@percy/cli-app@npm:1.30.1"
dependencies:
"@percy/cli-command": "npm:1.30.0"
"@percy/cli-exec": "npm:1.30.0"
checksum: 10c0/52f7d4fcda47f7aef73d71725c5473318d1b3a81ee03610aa7590df161e486f43416f516d740761260ef6a341c384a960263e9f845de84b589050dfed5b644d1
"@percy/cli-command": "npm:1.30.1"
"@percy/cli-exec": "npm:1.30.1"
checksum: 10c0/6c71352d840e17ea3123af37a935a3623e5f8fe4ca26e793902c959298f16f8e0107664b833d60a2acc9858726c3aaf811a50ccf772cbb22675663ad8b908604
languageName: node
linkType: hard

"@percy/cli-build@npm:1.30.0":
version: 1.30.0
resolution: "@percy/cli-build@npm:1.30.0"
"@percy/cli-build@npm:1.30.1":
version: 1.30.1
resolution: "@percy/cli-build@npm:1.30.1"
dependencies:
"@percy/cli-command": "npm:1.30.0"
checksum: 10c0/63379e31fb17b78a29d8d4e515a03ef54d2e83d2bfc5b4f1d73bdf3afa5b7f8ed7a42ea4f8be8b530aaf0164fc6c62668838204c9f7a8929e922c7024ff839f3
"@percy/cli-command": "npm:1.30.1"
checksum: 10c0/98dea7dbce5938be459a4336d72c7992f54143e5c6caa21d4954d445780b34fce29e4f166a6966f2a9aba1d9042dca4a6195dc110d1b7bf612e270f514724b9f
languageName: node
linkType: hard

"@percy/cli-command@npm:1.30.0":
version: 1.30.0
resolution: "@percy/cli-command@npm:1.30.0"
"@percy/cli-command@npm:1.30.1":
version: 1.30.1
resolution: "@percy/cli-command@npm:1.30.1"
dependencies:
"@percy/config": "npm:1.30.0"
"@percy/core": "npm:1.30.0"
"@percy/logger": "npm:1.30.0"
"@percy/config": "npm:1.30.1"
"@percy/core": "npm:1.30.1"
"@percy/logger": "npm:1.30.1"
bin:
percy-cli-readme: bin/readme.js
checksum: 10c0/a3d5e758e2ba7f52ae960d62d129a790f788426739c0ab607612ee37f7b24dd7a2bf8a6b7e7b1ea9da60cb4501b2791cedb9c0ea32a368d415d4d0389ffa27fd
checksum: 10c0/7965dbe9d1f103e49908776934955f25f8f150e5e87553f78253a5116d2c8ad949c67c3c37fb8af984baa5115e9d7025d938c8190d9b13ca212cea5d3dfcf1aa
languageName: node
linkType: hard

"@percy/cli-config@npm:1.30.0":
version: 1.30.0
resolution: "@percy/cli-config@npm:1.30.0"
"@percy/cli-config@npm:1.30.1":
version: 1.30.1
resolution: "@percy/cli-config@npm:1.30.1"
dependencies:
"@percy/cli-command": "npm:1.30.0"
checksum: 10c0/4f68f4e87e9efd3b473f9f1f908352554843f010850e03450d097d974876c782d6a5a4745298cffc82d3fe522e760ff060501c6a5c2e6633ae63f2f8cd52073e
"@percy/cli-command": "npm:1.30.1"
checksum: 10c0/d0958d7e0a348405e729ed471ecbf193bac7f9f7f6bbeeccdee8d48b71d0919a9936ab12bc6387f5d4ff058343c8cb1c37362f229e5e4a79162e78d06327cd67
languageName: node
linkType: hard

"@percy/cli-exec@npm:1.30.0":
version: 1.30.0
resolution: "@percy/cli-exec@npm:1.30.0"
"@percy/cli-exec@npm:1.30.1":
version: 1.30.1
resolution: "@percy/cli-exec@npm:1.30.1"
dependencies:
"@percy/cli-command": "npm:1.30.0"
"@percy/logger": "npm:1.30.0"
"@percy/cli-command": "npm:1.30.1"
"@percy/logger": "npm:1.30.1"
cross-spawn: "npm:^7.0.3"
which: "npm:^2.0.2"
checksum: 10c0/1b3e45fc51285f47d2cab3c2e43b6de0a9188a9a0030f30ea523d7aa331080dadfecb69c96fd3d15f365e1f692e85fa4951ed33b3e14075edbe5c7d783976780
checksum: 10c0/f6111a197ed3ab154f52a6d2bf827913d45c06120f88d650d65f198feeb6271ccbe8b95a5c301af820c7120f2203ab8ac6f106c9c8c680cb4d74314f83f152a0
languageName: node
linkType: hard

"@percy/cli-snapshot@npm:1.30.0":
version: 1.30.0
resolution: "@percy/cli-snapshot@npm:1.30.0"
"@percy/cli-snapshot@npm:1.30.1":
version: 1.30.1
resolution: "@percy/cli-snapshot@npm:1.30.1"
dependencies:
"@percy/cli-command": "npm:1.30.0"
"@percy/cli-command": "npm:1.30.1"
yaml: "npm:^2.0.0"
checksum: 10c0/408c9b64e661f8308031d7117a2afd7e3cac1ee85a88313dd01b7613e435495172f90c924b993b33914d08699c39f8e573e675624bd52227e12c3a5a276337d6
checksum: 10c0/40f2f884f10973471be7d153ea43b8cb0b86d3a4860daa448df1f8e5af053091fd75d5f49b15c385e0ea60746f57f4071d9290c1b6cebe9e120a832be502f1c0
languageName: node
linkType: hard

"@percy/cli-upload@npm:1.30.0":
version: 1.30.0
resolution: "@percy/cli-upload@npm:1.30.0"
"@percy/cli-upload@npm:1.30.1":
version: 1.30.1
resolution: "@percy/cli-upload@npm:1.30.1"
dependencies:
"@percy/cli-command": "npm:1.30.0"
"@percy/cli-command": "npm:1.30.1"
fast-glob: "npm:^3.2.11"
image-size: "npm:^1.0.0"
checksum: 10c0/12e5d198f5b8e3a0f2d665c72cde498523499cb2f52de79850fa0bcd07f8471c0f7a888f3b4e347682a75463cb77531980c87b029737caeb982b2caf48bacd14
checksum: 10c0/2540bd785fc74e65f7020c365fee72cb73331338f6042b08ca703804fceadcec9d9d1de316b2d5130fbeca006de5547972ce1fbad12e0899d0e6887e78ec2fb1
languageName: node
linkType: hard

"@percy/cli@npm:^1.26.0":
version: 1.30.0
resolution: "@percy/cli@npm:1.30.0"
"@percy/cli@npm:^1.30.1":
version: 1.30.1
resolution: "@percy/cli@npm:1.30.1"
dependencies:
"@percy/cli-app": "npm:1.30.0"
"@percy/cli-build": "npm:1.30.0"
"@percy/cli-command": "npm:1.30.0"
"@percy/cli-config": "npm:1.30.0"
"@percy/cli-exec": "npm:1.30.0"
"@percy/cli-snapshot": "npm:1.30.0"
"@percy/cli-upload": "npm:1.30.0"
"@percy/client": "npm:1.30.0"
"@percy/logger": "npm:1.30.0"
"@percy/cli-app": "npm:1.30.1"
"@percy/cli-build": "npm:1.30.1"
"@percy/cli-command": "npm:1.30.1"
"@percy/cli-config": "npm:1.30.1"
"@percy/cli-exec": "npm:1.30.1"
"@percy/cli-snapshot": "npm:1.30.1"
"@percy/cli-upload": "npm:1.30.1"
"@percy/client": "npm:1.30.1"
"@percy/logger": "npm:1.30.1"
bin:
percy: bin/run.cjs
checksum: 10c0/52369cc5c590baf537596551d1fe74c57bfa8d3b868442f56a415d44359e72a2883fab8e2abb825b60a1c4fd3ae99ae6b83171a2e98a7356cea67132f8ab342f
checksum: 10c0/b5b7fe6a547c93895e31904deba0b52866c4276b9a8bc57f14c92e6adaf5b47f1fd71a509de64c1feaf23af172a7cbe2ea536753a02989cba437912af11665e8
languageName: node
linkType: hard

"@percy/client@npm:1.30.0":
version: 1.30.0
resolution: "@percy/client@npm:1.30.0"
"@percy/client@npm:1.30.1":
version: 1.30.1
resolution: "@percy/client@npm:1.30.1"
dependencies:
"@percy/env": "npm:1.30.0"
"@percy/logger": "npm:1.30.0"
"@percy/env": "npm:1.30.1"
"@percy/logger": "npm:1.30.1"
pako: "npm:^2.1.0"
checksum: 10c0/2670b39e76b2352d9a2cd6f42b332447107d56d8eba923e80ce07845811ff8b4322a849b679d4dac47fe6031ea47687e9a86675c50c56029e12a42883123ff16
checksum: 10c0/32d3b8e6bcaff2afbc7a3fda1838894f891421436bcb65e7efc40520aedce2becfb71e3132218dd515e520e18637f2db0bef6efd9044a730ce1d9d21eca64b0c
languageName: node
linkType: hard

"@percy/config@npm:1.30.0":
version: 1.30.0
resolution: "@percy/config@npm:1.30.0"
"@percy/config@npm:1.30.1":
version: 1.30.1
resolution: "@percy/config@npm:1.30.1"
dependencies:
"@percy/logger": "npm:1.30.0"
"@percy/logger": "npm:1.30.1"
ajv: "npm:^8.6.2"
cosmiconfig: "npm:^8.0.0"
yaml: "npm:^2.0.0"
checksum: 10c0/e60ad177344c3755a4ae9d14859aa5676836d75724277607cd6088251c5e8cbe7912c718f5a6b793fd5d05960b55356c930456857bfbb5e526d82319ebd8f22e
checksum: 10c0/c582cd147c6f919ece50fc788a4272158a1c33c971f3c1721cf9b951200b70156230aadb3940d786e0c8d5bfd0bbdd8918cd8ea727e10008acaf6749a21cd56b
languageName: node
linkType: hard

"@percy/core@npm:1.30.0":
version: 1.30.0
resolution: "@percy/core@npm:1.30.0"
"@percy/core@npm:1.30.1":
version: 1.30.1
resolution: "@percy/core@npm:1.30.1"
dependencies:
"@percy/client": "npm:1.30.0"
"@percy/config": "npm:1.30.0"
"@percy/dom": "npm:1.30.0"
"@percy/logger": "npm:1.30.0"
"@percy/webdriver-utils": "npm:1.30.0"
"@percy/client": "npm:1.30.1"
"@percy/config": "npm:1.30.1"
"@percy/dom": "npm:1.30.1"
"@percy/logger": "npm:1.30.1"
"@percy/webdriver-utils": "npm:1.30.1"
content-disposition: "npm:^0.5.4"
cross-spawn: "npm:^7.0.3"
extract-zip: "npm:^2.0.1"
Expand All @@ -3019,7 +3019,7 @@ __metadata:
rimraf: "npm:^3.0.2"
ws: "npm:^8.17.1"
yaml: "npm:^2.4.1"
checksum: 10c0/0d3bb2c2fb7a58369345347f986b4d9c332ff5b39bedad30657e0d710229e97d9d37fc7d35cbbc42c26d6c0856fdc6fe81e0748e90ca162f9a37d270080bfe80
checksum: 10c0/708bb41e12b278626b748f415a12171e5711b1a9e5da432f0554de9fdc1b8d8db42b85b305e7272fe154a74b3005f8af4207a0452eba38907d7cf1a057d2f702
languageName: node
linkType: hard

Expand All @@ -3034,33 +3034,33 @@ __metadata:
languageName: node
linkType: hard

"@percy/dom@npm:1.30.0":
version: 1.30.0
resolution: "@percy/dom@npm:1.30.0"
checksum: 10c0/015a40631a783f1e4ef6ad3b605ead352d8a9483f5d0806faa450c4f2898b2bf4ad3e650d2e7b8b07ed6261c2078a0990cc0fb80600fcb83f4712e2f7fe21922
"@percy/dom@npm:1.30.1":
version: 1.30.1
resolution: "@percy/dom@npm:1.30.1"
checksum: 10c0/5e0ffd2e8aa7c3604ee0dfba3d94f96869edc730522e2b85d94a626452300724c7ce49bbd1822c68f3c6cd1c435513acf2fa5bd8a006d415d0a8ec9bdc72c25e
languageName: node
linkType: hard

"@percy/env@npm:1.30.0":
version: 1.30.0
resolution: "@percy/env@npm:1.30.0"
"@percy/env@npm:1.30.1":
version: 1.30.1
resolution: "@percy/env@npm:1.30.1"
dependencies:
"@percy/logger": "npm:1.30.0"
checksum: 10c0/a6a4ab81c3ca96cb96d91f0104bca7ce52092a776300ce84617ca8342faa8aef9f5b38e1fee6aecadfe93d03f472d7dbbac6e7d2cfbfeb459f51a2cc4893f219
"@percy/logger": "npm:1.30.1"
checksum: 10c0/c8fd3f83db449eac77a464aa2b6459380496fff897e319f8e94aa4627ceb6a5cb921d092594fff38011ff9a0403be379831e6297f40f9c610b187f78deddda81
languageName: node
linkType: hard

"@percy/logger@npm:1.30.0":
version: 1.30.0
resolution: "@percy/logger@npm:1.30.0"
checksum: 10c0/ae64225db6907d9b73c7e5b1119d077be453f5e0d5ec4784a19f83221f19058a0c4470051de17e897581c683a9150b72c06c4acf84eebb497036e962f9192363
"@percy/logger@npm:1.30.1":
version: 1.30.1
resolution: "@percy/logger@npm:1.30.1"
checksum: 10c0/939c9a247b5c36268577185c30c3b348179be2231a94e0bd3c338c9a281ba7e7e3c4d4119bcb8e10c82f079623e7b445c7e5ae177ec0e7e84d8cebfad8580904
languageName: node
linkType: hard

"@percy/sdk-utils@npm:1.30.0":
version: 1.30.0
resolution: "@percy/sdk-utils@npm:1.30.0"
checksum: 10c0/8cf552c8dc3065a108d217fa9353695399f7e3476c55ca5681f1e27a64db98472f57568de0f27bc96bdec779d19d830c01633e61e5fb1059aee26751f1e2dcd5
"@percy/sdk-utils@npm:1.30.1":
version: 1.30.1
resolution: "@percy/sdk-utils@npm:1.30.1"
checksum: 10c0/ac60345a45fa8b8fb6f6f74d9a9f2530e4feeb2b3149f4d87cdb09f56e422cd44fae6b92e88e947e88587ce39a07a1215e63731f47d950a56ecf1595883fd124
languageName: node
linkType: hard

Expand All @@ -3071,13 +3071,13 @@ __metadata:
languageName: node
linkType: hard

"@percy/webdriver-utils@npm:1.30.0":
version: 1.30.0
resolution: "@percy/webdriver-utils@npm:1.30.0"
"@percy/webdriver-utils@npm:1.30.1":
version: 1.30.1
resolution: "@percy/webdriver-utils@npm:1.30.1"
dependencies:
"@percy/config": "npm:1.30.0"
"@percy/sdk-utils": "npm:1.30.0"
checksum: 10c0/db92a2c38b0a9644d0e5a2b8b257bb656b363501928c2ed734273d31a772514f0dfad0990a81db18b48a61ae9698b815c2952141935533398419ab7540af71c2
"@percy/config": "npm:1.30.1"
"@percy/sdk-utils": "npm:1.30.1"
checksum: 10c0/40ef45d3ffdc77238ced38f31a62bd71d650d8b075b79a29597689c6899dfc2ed59d63e1e04daa56f84c8f08fe33bf799952ddb0da2e48516ee1867ca87378bb
languageName: node
linkType: hard

Expand Down Expand Up @@ -5416,7 +5416,7 @@ __metadata:
"@material-ui/core": "npm:4.12.4"
"@material-ui/pickers": "npm:3.3.11"
"@navikt/aksel-icons": "npm:^7.0.0"
"@percy/cli": "npm:^1.26.0"
"@percy/cli": "npm:^1.30.1"
"@percy/cypress": "npm:^3.1.2"
"@pmmmwh/react-refresh-webpack-plugin": "npm:0.5.15"
"@tanstack/react-query": "npm:^5.25.0"
Expand Down

0 comments on commit 530b0f3

Please sign in to comment.