Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Privacy experiences initial pages #3186

Merged
merged 10 commits into from
May 5, 2023
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The types of changes are:
- Access and erasure support for Amplitude [#2569](https://github.com/ethyca/fides/pull/2569)
- Access and erasure support for Gorgias [#2444](https://github.com/ethyca/fides/pull/2444)
- Privacy Experience Bulk Create, Bulk Update, and Detail Endpoints [#3185](https://github.com/ethyca/fides/pull/3185)
- Initial privacy experience UI [#3186](https://github.com/ethyca/fides/pull/3186)

### Changed

Expand Down
147 changes: 147 additions & 0 deletions clients/admin-ui/cypress/e2e/privacy-experiences.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import { stubPlus } from "cypress/support/stubs";

import { PRIVACY_EXPERIENCE_ROUTE } from "~/features/common/nav/v2/routes";
import { RoleRegistryEnum } from "~/types/api";

const OVERLAY_EXPERIENCE_ID = "pri_4076d6dd-a728-4f2d-9a5c-98f35d7a5a86";
const DISABLED_EXPERIENCE_ID = "pri_75d2b3dc-6f7c-4a36-95ee-3088bd1b4572";

describe("Privacy experiences", () => {
beforeEach(() => {
cy.login();
cy.intercept("GET", "/api/v1/privacy-experience*", {
fixture: "privacy-experiences/list.json",
}).as("getExperiences");
stubPlus(true);
});

describe("permissions", () => {
it("should not be viewable for approvers", () => {
cy.assumeRole(RoleRegistryEnum.APPROVER);
cy.visit(PRIVACY_EXPERIENCE_ROUTE);
// should be redirected to the home page
cy.getByTestId("home-content");
});

it("should be visible to everyone else", () => {
[
RoleRegistryEnum.CONTRIBUTOR,
RoleRegistryEnum.OWNER,
RoleRegistryEnum.VIEWER,
].forEach((role) => {
cy.assumeRole(role);
cy.visit(PRIVACY_EXPERIENCE_ROUTE);
cy.getByTestId("privacy-experience-page");
});
});

it("viewers and approvers cannot click into an experience to edit", () => {
[RoleRegistryEnum.VIEWER, RoleRegistryEnum.VIEWER_AND_APPROVER].forEach(
(role) => {
cy.assumeRole(role);
cy.visit(PRIVACY_EXPERIENCE_ROUTE);
cy.wait("@getExperiences");
cy.getByTestId(`row-${OVERLAY_EXPERIENCE_ID}`).click();
// we should still be on the same page
cy.getByTestId("privacy-experience-detail-page").should("not.exist");
cy.getByTestId("privacy-experience-page");
}
);
});

it("viewers and approvers cannot toggle the enable toggle", () => {
[RoleRegistryEnum.VIEWER, RoleRegistryEnum.VIEWER_AND_APPROVER].forEach(
(role) => {
cy.assumeRole(role);
cy.visit(PRIVACY_EXPERIENCE_ROUTE);
cy.wait("@getExperiences");
cy.getByTestId("toggle-Enable")
.first()
.within(() => {
cy.get("span").should("have.attr", "data-disabled");
});
}
);
});
});

it("can show an empty state", () => {
cy.intercept("GET", "/api/v1/privacy-experience*", {
body: { items: [], page: 1, size: 10, total: 0 },
}).as("getEmptyExperiences");
cy.visit(PRIVACY_EXPERIENCE_ROUTE);
cy.wait("@getEmptyExperiences");
cy.getByTestId("empty-state");
});

describe("table", () => {
beforeEach(() => {
cy.visit(PRIVACY_EXPERIENCE_ROUTE);
cy.wait("@getExperiences");
});

it("should render a row for each privacy experience", () => {
cy.fixture("privacy-experiences/list.json").then((data) => {
data.items
.map((item) => item.id)
.forEach((id) => {
cy.getByTestId(`row-${id}`);
});
});
});

it("can click a row to go to the experience page", () => {
cy.intercept("GET", "/api/v1/privacy-experience/pri*", {
fixture: "privacy-experiences/experience.json",
}).as("getExperienceDetail");
cy.getByTestId(`row-${OVERLAY_EXPERIENCE_ID}`).click();
cy.wait("@getExperienceDetail");
cy.getByTestId("privacy-experience-detail-page");
cy.url().should("contain", OVERLAY_EXPERIENCE_ID);
});

describe("enabling and disabling", () => {
beforeEach(() => {
cy.intercept("PATCH", "/api/v1/privacy-experience*", {
fixture: "privacy-experiences/list.json",
}).as("patchExperiences");
});

it("can enable an experience", () => {
cy.getByTestId(`row-${DISABLED_EXPERIENCE_ID}`).within(() => {
cy.getByTestId("toggle-Enable").within(() => {
cy.get("span").should("not.have.attr", "data-checked");
});
cy.getByTestId("toggle-Enable").click();
});

cy.wait("@patchExperiences").then((interception) => {
const { body } = interception.request;
expect(body).to.eql([
{ id: DISABLED_EXPERIENCE_ID, disabled: false },
]);
});
// redux should requery after invalidation
cy.wait("@getExperiences");
});

it("can disable an experience with a warning", () => {
cy.getByTestId(`row-${OVERLAY_EXPERIENCE_ID}`).within(() => {
cy.getByTestId("toggle-Enable").within(() => {
cy.get("span").should("have.attr", "data-checked");
});
cy.getByTestId("toggle-Enable").click();
});

cy.getByTestId("confirmation-modal");
cy.getByTestId("continue-btn").click();
cy.wait("@patchExperiences").then((interception) => {
const { body } = interception.request;
expect(body).to.eql([{ id: OVERLAY_EXPERIENCE_ID, disabled: true }]);
});
// redux should requery after invalidation
cy.wait("@getExperiences");
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"disabled": false,
"component": "overlay",
"delivery_mechanism": "link",
"regions": ["eu_de"],
"component_title": null,
"component_description": null,
"banner_title": null,
"banner_description": null,
"link_label": null,
"confirmation_button_label": null,
"reject_button_label": null,
"acknowledgement_button_label": null,
"id": "pri_4076d6dd-a728-4f2d-9a5c-98f35d7a5a86",
"created_at": "2023-05-02T15:32:41.253621+00:00",
"updated_at": "2023-05-02T15:32:41.253621+00:00",
"version": 1.0,
"privacy_experience_history_id": "pri_fa40ddc5-ba8d-4efe-b83f-643b2595b191",
"privacy_experience_template_id": null,
"privacy_notices": []
}
172 changes: 172 additions & 0 deletions clients/admin-ui/cypress/fixtures/privacy-experiences/list.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
{
"items": [
{
"disabled": false,
"component": "overlay",
"delivery_mechanism": "link",
"regions": ["eu_de"],
"component_title": null,
"component_description": null,
"banner_title": null,
"banner_description": null,
"link_label": null,
"confirmation_button_label": null,
"reject_button_label": null,
"acknowledgement_button_label": null,
"id": "pri_4076d6dd-a728-4f2d-9a5c-98f35d7a5a86",
"created_at": "2023-05-02T15:32:41.253621+00:00",
"updated_at": "2023-05-02T15:32:41.253621+00:00",
"version": 1.0,
"privacy_experience_history_id": "pri_fa40ddc5-ba8d-4efe-b83f-643b2595b191",
"privacy_experience_template_id": null,
"privacy_notices": []
},
{
"disabled": true,
"component": "privacy_center",
"delivery_mechanism": "link",
"regions": ["us_ca"],
"component_title": null,
"component_description": null,
"banner_title": null,
"banner_description": null,
"link_label": null,
"confirmation_button_label": null,
"reject_button_label": null,
"acknowledgement_button_label": null,
"id": "pri_75d2b3dc-6f7c-4a36-95ee-3088bd1b4572",
"created_at": "2023-05-02T15:32:41.237150+00:00",
"updated_at": "2023-05-02T15:32:41.237150+00:00",
"version": 1.0,
"privacy_experience_history_id": "pri_422201ba-59c6-48df-992a-f20af701e999",
"privacy_experience_template_id": null,
"privacy_notices": [
{
"name": "Data Sales",
"description": "Provide opt-out consent for the use of data in ways that may be considered “data sales” under US state privacy regulations.",
"internal_description": null,
"origin": null,
"regions": ["us_ca", "us_co"],
"consent_mechanism": "opt_out",
"data_uses": ["advertising.third_party.personalized"],
"enforcement_level": "frontend",
"disabled": false,
"has_gpc_flag": false,
"displayed_in_privacy_center": true,
"displayed_in_overlay": false,
"displayed_in_api": false,
"id": "pri_8ad94105-6142-4f20-bb56-9644a6f16917",
"created_at": "2023-05-02T15:19:36.733208+00:00",
"updated_at": "2023-05-02T15:19:36.733208+00:00",
"version": 1.0,
"privacy_notice_history_id": "pri_b524bbec-22e2-4364-9e39-5399208976d8"
}
]
},
{
"disabled": false,
"component": "overlay",
"delivery_mechanism": "banner",
"regions": ["eu_fr", "eu_ie"],
"component_title": null,
"component_description": null,
"banner_title": null,
"banner_description": null,
"link_label": null,
"confirmation_button_label": null,
"reject_button_label": null,
"acknowledgement_button_label": null,
"id": "pri_759df3b9-57c7-40aa-8252-0a12456d81cb",
"created_at": "2023-05-02T15:32:41.219842+00:00",
"updated_at": "2023-05-02T15:32:41.219842+00:00",
"version": 1.0,
"privacy_experience_history_id": "pri_438e7d81-0ad0-43e5-8c1e-2c45fe8d6177",
"privacy_experience_template_id": null,
"privacy_notices": [
{
"name": "Advertising",
"description": "Ensures you are correctly notifying the user about your advertising practices and for appropriate locations, collecting the users consent preferences.",
"internal_description": null,
"origin": null,
"regions": ["eu_fr", "eu_ie"],
"consent_mechanism": "opt_in",
"data_uses": ["advertising.first_party.contextual"],
"enforcement_level": "system_wide",
"disabled": false,
"has_gpc_flag": false,
"displayed_in_privacy_center": false,
"displayed_in_overlay": true,
"displayed_in_api": false,
"id": "pri_82efe831-b134-434f-90eb-e4b3204a5e97",
"created_at": "2023-05-02T15:19:36.730578+00:00",
"updated_at": "2023-05-02T15:19:36.730578+00:00",
"version": 1.0,
"privacy_notice_history_id": "pri_f19c3323-7281-4043-b964-a103835cab4b"
},
{
"name": "Analytics",
"description": "Ensures you are correctly notifying the user about your advertising practices and for appropriate locations, collecting the users consent preferences.",
"internal_description": null,
"origin": null,
"regions": ["eu_fr", "eu_ie"],
"consent_mechanism": "opt_in",
"data_uses": ["collect"],
"enforcement_level": "system_wide",
"disabled": false,
"has_gpc_flag": false,
"displayed_in_privacy_center": false,
"displayed_in_overlay": true,
"displayed_in_api": false,
"id": "pri_1e98649f-9294-4217-a51a-2d2781f19052",
"created_at": "2023-05-02T15:19:36.727792+00:00",
"updated_at": "2023-05-02T15:19:36.727792+00:00",
"version": 1.0,
"privacy_notice_history_id": "pri_18e70ccb-af22-4761-bf77-4095ee19118f"
},
{
"name": "Functional",
"description": "This is for data processing activities that enhance the capability or features of your site but may not be strictly necessary.",
"internal_description": null,
"origin": null,
"regions": ["eu_fr", "eu_ie"],
"consent_mechanism": "opt_in",
"data_uses": ["improve.system"],
"enforcement_level": "system_wide",
"disabled": false,
"has_gpc_flag": false,
"displayed_in_privacy_center": false,
"displayed_in_overlay": true,
"displayed_in_api": false,
"id": "pri_97f45baf-298e-4ea0-a22e-cf80543b573b",
"created_at": "2023-05-02T15:19:36.723747+00:00",
"updated_at": "2023-05-02T15:19:36.723747+00:00",
"version": 1.0,
"privacy_notice_history_id": "pri_595eef41-9848-4709-be5c-cf924d6e5968"
},
{
"name": "Essential",
"description": "Notify the user about data processing activities that are essential to your services functionality. Typically consent is not required for this.",
"internal_description": null,
"origin": null,
"regions": ["eu_fr", "eu_ie"],
"consent_mechanism": "notice_only",
"data_uses": ["provide.service"],
"enforcement_level": "system_wide",
"disabled": false,
"has_gpc_flag": false,
"displayed_in_privacy_center": false,
"displayed_in_overlay": true,
"displayed_in_api": false,
"id": "pri_e8d8c006-5753-4b13-afc6-4f26caf6eb61",
"created_at": "2023-05-02T15:19:36.703598+00:00",
"updated_at": "2023-05-02T15:19:36.703598+00:00",
"version": 1.0,
"privacy_notice_history_id": "pri_79eba2d7-d6f2-4bd4-94b9-f02dbc2f7621"
}
]
}
],
"total": 3,
"page": 1,
"size": 10
}
Loading