From 89296bb260c5903b6d95f8a69f352aebe3bc0e57 Mon Sep 17 00:00:00 2001 From: Allison King Date: Thu, 22 Jun 2023 18:16:15 -0400 Subject: [PATCH 1/4] Subscribe to individual system query in manual create --- .../src/features/system/SystemFormTabs.tsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/clients/admin-ui/src/features/system/SystemFormTabs.tsx b/clients/admin-ui/src/features/system/SystemFormTabs.tsx index 64171f0a84e..8cd711f0aac 100644 --- a/clients/admin-ui/src/features/system/SystemFormTabs.tsx +++ b/clients/admin-ui/src/features/system/SystemFormTabs.tsx @@ -12,7 +12,11 @@ import ConnectionForm from "~/features/datastore-connections/system_portal_confi import PrivacyDeclarationStep from "~/features/system/privacy-declarations/PrivacyDeclarationStep"; import { System, SystemResponse } from "~/types/api"; -import { selectActiveSystem, setActiveSystem } from "./system.slice"; +import { + selectActiveSystem, + setActiveSystem, + useGetSystemByFidesKeyQuery, +} from "./system.slice"; import SystemInformationForm from "./SystemInformationForm"; import UnmountWarning from "./UnmountWarning"; @@ -79,6 +83,17 @@ const SystemFormTabs = ({ const dispatch = useAppDispatch(); const activeSystem = useAppSelector(selectActiveSystem) as SystemResponse; + // Once we have saved the system basics, subscribe to the query so that activeSystem + // stays up to date when redux invalidates the cache (for example, when we patch a connection config) + const { data: systemFromApi } = useGetSystemByFidesKeyQuery( + activeSystem?.fides_key, + { skip: !activeSystem } + ); + + useEffect(() => { + dispatch(setActiveSystem(systemFromApi)); + }, [systemFromApi, dispatch]); + const handleSuccess = (system: System) => { // show a save message if this is the first time the system was saved if (activeSystem === undefined) { From d177b960222cb52edfe1c8c1931157b35c978760 Mon Sep 17 00:00:00 2001 From: Allison King Date: Thu, 22 Jun 2023 18:19:18 -0400 Subject: [PATCH 2/4] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81aaf751fc2..65f92e4db4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,6 +69,7 @@ The types of changes are: - Update to latest asyncpg dependency to avoid build error [#3614](https://github.com/ethyca/fides/pull/3614) - Fix bug where editing a data use on a system could delete existing data uses [#3627](https://github.com/ethyca/fides/pull/3627) - Restrict Privacy Center debug logging to development-only [#3638](https://github.com/ethyca/fides/pull/3638) +- Fix bug where linking an integration would not update the tab when creating a new system [#3662](https://github.com/ethyca/fides/pull/3662) ### Changed From d7dac47a9849e4ab6e1ce3a2f9474bcb92bf4b11 Mon Sep 17 00:00:00 2001 From: Allison King Date: Fri, 23 Jun 2023 11:46:07 -0400 Subject: [PATCH 3/4] Remove setting active system in privacy declaration SystemFormTabs will handle this now --- .../privacy-declarations/PrivacyDeclarationStep.tsx | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/clients/admin-ui/src/features/system/privacy-declarations/PrivacyDeclarationStep.tsx b/clients/admin-ui/src/features/system/privacy-declarations/PrivacyDeclarationStep.tsx index 7634e8aaf1e..5f0d2604ead 100644 --- a/clients/admin-ui/src/features/system/privacy-declarations/PrivacyDeclarationStep.tsx +++ b/clients/admin-ui/src/features/system/privacy-declarations/PrivacyDeclarationStep.tsx @@ -1,9 +1,7 @@ import { Heading, Spinner, Stack, Text } from "@fidesui/react"; import NextLink from "next/link"; -import { useAppDispatch } from "~/app/hooks"; -import { setActiveSystem } from "~/features/system"; -import { System, SystemResponse } from "~/types/api"; +import { SystemResponse } from "~/types/api"; import { usePrivacyDeclarationData } from "./hooks"; import PrivacyDeclarationManager from "./PrivacyDeclarationManager"; @@ -13,16 +11,10 @@ interface Props { } const PrivacyDeclarationStep = ({ system }: Props) => { - const dispatch = useAppDispatch(); - const { isLoading, ...dataProps } = usePrivacyDeclarationData({ includeDatasets: true, }); - const onSave = (savedSystem: System) => { - dispatch(setActiveSystem(savedSystem)); - }; - return ( @@ -46,7 +38,6 @@ const PrivacyDeclarationStep = ({ system }: Props) => { ) : ( Date: Fri, 23 Jun 2023 11:47:54 -0400 Subject: [PATCH 4/4] Update cypress tests now that we invalidate the cache Redux invalidates the cache resulting in a new call to get the updated system. Cypress tests were skirting by but now we need to be more strict about their intercepts --- clients/admin-ui/cypress/e2e/systems.cy.ts | 68 +++++++++++++--------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/clients/admin-ui/cypress/e2e/systems.cy.ts b/clients/admin-ui/cypress/e2e/systems.cy.ts index 2361b15a395..a3f9c03e1d8 100644 --- a/clients/admin-ui/cypress/e2e/systems.cy.ts +++ b/clients/admin-ui/cypress/e2e/systems.cy.ts @@ -111,6 +111,9 @@ describe("System management page", () => { it("Can step through the flow", () => { cy.fixture("systems/system.json").then((system) => { + cy.intercept("GET", "/api/v1/system/*", { + body: { ...system, privacy_declarations: [] }, + }).as("getDemoSystem"); // Fill in the describe form based on fixture data cy.visit(ADD_SYSTEMS_ROUTE); cy.getByTestId("manual-btn").click(); @@ -145,6 +148,7 @@ describe("System management page", () => { "@getDataSubjects", "@getDataUses", "@getFilteredDatasets", + "@getDemoSystem", ]); cy.getByTestId("new-declaration-form"); const declaration = system.privacy_declarations[0]; @@ -180,32 +184,41 @@ describe("System management page", () => { }); it("can render a warning when there is unsaved data", () => { - cy.visit(ADD_SYSTEMS_MANUAL_ROUTE); - cy.wait("@getSystems"); - cy.wait("@getConnectionTypes"); - cy.getByTestId("create-system-btn").click(); - cy.getByTestId("input-name").type("test"); - cy.getByTestId("input-fides_key").type("test"); - cy.getByTestId("save-btn").click(); - cy.wait("@postSystem"); + cy.fixture("systems/system.json").then((system) => { + cy.intercept("GET", "/api/v1/system/*", { + body: { ...system, privacy_declarations: [] }, + }).as("getDemoSystem"); + cy.visit(ADD_SYSTEMS_MANUAL_ROUTE); + cy.wait("@getSystems"); + cy.wait("@getConnectionTypes"); + cy.getByTestId("create-system-btn").click(); + cy.getByTestId("input-name").type(system.name); + cy.getByTestId("input-fides_key").type(system.fides_key); + cy.getByTestId("input-description").type(system.description); + cy.getByTestId("save-btn").click(); + cy.wait("@postSystem"); - // start typing a description - const description = "half formed thought"; - cy.getByTestId("input-description").type(description); - // then try navigating to the privacy declarations tab - cy.getByTestId("tab-Data uses").click(); - cy.getByTestId("confirmation-modal"); - // make sure canceling works - cy.getByTestId("cancel-btn").click(); - cy.getByTestId("input-description").should("have.value", description); - // now actually discard - cy.getByTestId("tab-Data uses").click(); - cy.getByTestId("continue-btn").click(); - // should load the privacy declarations page - cy.getByTestId("privacy-declaration-step"); - // navigate back - cy.getByTestId("tab-System information").click(); - cy.getByTestId("input-description").should("have.value", ""); + // start typing a description + const description = "half formed thought"; + cy.getByTestId("input-description").clear().type(description); + // then try navigating to the privacy declarations tab + cy.getByTestId("tab-Data uses").click(); + cy.getByTestId("confirmation-modal"); + // make sure canceling works + cy.getByTestId("cancel-btn").click(); + cy.getByTestId("input-description").should("have.value", description); + // now actually discard + cy.getByTestId("tab-Data uses").click(); + cy.getByTestId("continue-btn").click(); + // should load the privacy declarations page + cy.getByTestId("privacy-declaration-step"); + // navigate back and make sure description has the original description + cy.getByTestId("tab-System information").click(); + cy.getByTestId("input-description").should( + "have.value", + system.description + ); + }); }); }); }); @@ -311,6 +324,7 @@ describe("System management page", () => { const { body } = interception.request; expect(body.joint_controller.name).to.eql(controllerName); }); + cy.wait("@getFidesctlSystem"); // Switch to the Data Uses tab cy.getByTestId("tab-Data uses").click(); @@ -336,15 +350,15 @@ describe("System management page", () => { // edit the existing declaration cy.getByTestId("accordion-header-improve.system").click(); cy.getByTestId("improve.system-form").within(() => { - cy.getByTestId("input-data_subjects").type(`anonymous{enter}`); + cy.getByTestId("input-data_subjects").type(`customer{enter}`); cy.getByTestId("save-btn").click(); }); cy.wait("@putSystem").then((interception) => { const { body } = interception.request; expect(body.privacy_declarations.length).to.eql(1); expect(body.privacy_declarations[0].data_subjects).to.eql([ - "customer", "anonymous_user", + "customer", ]); }); cy.getByTestId("saved-indicator");