Skip to content

Commit 4656e86

Browse files
Merge pull request #2254 from AletheiaFact/cypress/creating-new-tests-for-verification-request-lifecycle
Test: Verification Request Lifecycle Coverage with Cypress
2 parents a1042f2 + 5d96f8b commit 4656e86

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+447
-100
lines changed

cypress/e2e/tests/image.cy.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import locators from "../../support/locators";
44
import claim from "../../fixtures/claim";
5+
import { today } from "../../utils/dateUtils";
56

67
describe("Create image claim", () => {
78
beforeEach("login", () => cy.login());
@@ -15,7 +16,7 @@ describe("Create image claim", () => {
1516
.type(claim.imageTitle);
1617

1718
cy.get(locators.claim.INPUT_DATA).should("be.visible").click();
18-
cy.get(locators.claim.INPUT_DATA_TODAY).should("be.visible").click();
19+
cy.contains('[role="gridcell"]', today.format("D")).click();
1920

2021
cy.get(locators.claim.INPUT_SOURCE)
2122
.should("be.visible")

cypress/e2e/tests/personality.cy.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import locators from "../../support/locators";
44
import claim from "../../fixtures/claim";
55
import personality from "../../fixtures/personality";
6+
import { today } from "../../utils/dateUtils";
67

78
describe("Create personality and claim", () => {
89
beforeEach("login", () => cy.login());
@@ -47,7 +48,7 @@ describe("Create personality and claim", () => {
4748
.type(claim.content);
4849

4950
cy.get(locators.claim.INPUT_DATA).should("be.visible").click();
50-
cy.get(locators.claim.INPUT_DATA_TODAY).should("be.visible").click();
51+
cy.contains('[role="gridcell"]', today.format("D")).click();
5152

5253
cy.get(locators.claim.INPUT_SOURCE)
5354
.should("be.visible")
@@ -78,7 +79,7 @@ describe("Create personality and claim", () => {
7879
.should("be.visible")
7980
.type(claim.imageTitle);
8081
cy.get(locators.claim.INPUT_DATA).should("be.visible").click();
81-
cy.get(locators.claim.INPUT_DATA_TODAY).should("be.visible").click();
82+
cy.contains('[role="gridcell"]', today.format("D")).click();
8283
cy.get(locators.claim.INPUT_SOURCE)
8384
.should("be.visible")
8485
.type(claim.source);
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
2+
/// <reference types="cypress" />
3+
4+
import { fullVerificationRequest, regexVerificationRequestPage, updatedSource, minimumContent } from "../../fixtures/verificationRequest";
5+
import locators from "../../support/locators";
6+
import { Dayjs } from "dayjs"
7+
import { getPastDay, today } from "../../utils/dateUtils";
8+
9+
describe("Test verification request", () => {
10+
const getHashFromUrl = (interception) => interception.request.url.split("/").pop();
11+
12+
const openCreateVerificationRequestForm = () => {
13+
cy.get(locators.floatButton.FLOAT_BUTTON).click();
14+
cy.get(locators.floatButton.ADD_VERIFICATION_REQUEST).click();
15+
cy.url().should("contain", "/verification-request/create");
16+
};
17+
18+
const selectPublicationDate = (date: Dayjs) => {
19+
cy.get(locators.verificationRequest.FORM_PUBLICATION_DATE).click();
20+
cy.contains('[role="gridcell"]', date.format("D")).click();
21+
};
22+
23+
const saveVerificationRequest = () => {
24+
cy.checkRecaptcha();
25+
cy.get(locators.verificationRequest.SAVE_BUTTON).click();
26+
};
27+
28+
const assertDetailFields = (fields: Array<[string, string]>) => {
29+
fields.forEach(([selector, expected]) => {
30+
cy.get(selector).should("be.visible").and("contain", expected);
31+
});
32+
};
33+
34+
const goToVerificationRequest = (data_hash: string) => {
35+
cy.intercept("GET", "**/verification-request/**").as("getVerification");
36+
cy.visit(`/verification-request/${data_hash}`);
37+
cy.wait("@getVerification");
38+
}
39+
40+
describe("lifecycle verification request", () => {
41+
beforeEach("login", () => cy.login());
42+
43+
it("should prevent submission when required fields are missing", () => {
44+
openCreateVerificationRequestForm();
45+
saveVerificationRequest();
46+
cy.get(locators.verificationRequest.ERROR_VALIDATION_CONTENT).should("be.visible")
47+
cy.get(locators.verificationRequest.ERROR_VALIDATION_PUBLICATION_DATE).should("be.visible")
48+
cy.url().should("contain", "/verification-request/create");
49+
});
50+
51+
describe("Full verification request flow", () => {
52+
let fullRequestHash: string;
53+
54+
it("should create a verification request with all optional and mandatory fields", () => {
55+
openCreateVerificationRequestForm();
56+
cy.intercept("GET", "**/verification-request/**").as("getVerification");
57+
58+
cy.get(locators.verificationRequest.FORM_CONTENT).type(fullVerificationRequest.content);
59+
selectPublicationDate(today);
60+
cy.get(locators.verificationRequest.FORM_REPORT_TYPE).click();
61+
cy.contains(fullVerificationRequest.reportType).click();
62+
cy.get(locators.verificationRequest.FORM_IMPACT_AREA).type(fullVerificationRequest.impactArea, { delay: 200 });
63+
cy.contains(fullVerificationRequest.impactArea).click();
64+
65+
cy.get(locators.verificationRequest.FORM_HEARD_FROM).type(fullVerificationRequest.heardFrom);
66+
cy.get(locators.verificationRequest.FORM_SOURCE).type(`https://${fullVerificationRequest.source}`);
67+
cy.get(locators.verificationRequest.FORM_EMAIL).type(fullVerificationRequest.email);
68+
saveVerificationRequest();
69+
70+
cy.wait("@getVerification").then((interception) => {
71+
getHashFromUrl(interception)
72+
fullRequestHash = getHashFromUrl(interception);
73+
cy.log("Hash capturado:", fullRequestHash);
74+
});
75+
cy.url().should("match", regexVerificationRequestPage);
76+
77+
assertDetailFields([
78+
[locators.verificationRequest.DETAIL_CONTENT, fullVerificationRequest.content],
79+
[locators.verificationRequest.DETAIL_REPORT_TYPE, fullVerificationRequest.reportType],
80+
[locators.verificationRequest.DETAIL_IMPACT_AREA, fullVerificationRequest.impactArea],
81+
[locators.verificationRequest.DETAIL_SOURCE_CHANNEL, "Web"],
82+
[locators.verificationRequest.DETAIL_HEARD_FROM, fullVerificationRequest.heardFrom],
83+
[locators.verificationRequest.DETAIL_PUBLICATION_DATE, today.format("DD/MM/YYYY")],
84+
[locators.verificationRequest.DETAIL_DATE, today.format("DD/MM/YYYY")],
85+
[locators.verificationRequest.DETAIL_SOURCE_0, fullVerificationRequest.source],
86+
]);
87+
88+
it("should update an existing request by adding additional sources and modifying the publication date", () => {
89+
goToVerificationRequest(fullRequestHash)
90+
91+
cy.get(locators.verificationRequest.EDIT_BUTTON).should("be.visible").click();
92+
cy.get(locators.verificationRequest.FORM_SOURCE_ADD).click();
93+
cy.get(locators.verificationRequest.FORM_SOURCE_ITEM_1).type(`https://${updatedSource}`);
94+
selectPublicationDate(getPastDay(1));
95+
saveVerificationRequest();
96+
cy.url().should("match", regexVerificationRequestPage);
97+
98+
assertDetailFields([
99+
[locators.verificationRequest.DETAIL_PUBLICATION_DATE, getPastDay(1).format("DD/MM/YYYY")],
100+
[locators.verificationRequest.DETAIL_SOURCE_1, updatedSource],
101+
])
102+
})
103+
})
104+
105+
it("should manage topic tags by adding and removing them", () => {
106+
goToVerificationRequest(fullRequestHash)
107+
cy.intercept("PUT", "**/verification-request/*/topics").as("updateTopics");
108+
109+
cy.get(locators.verificationRequest.ADD_TOPIC_ICON).click();
110+
cy.get(locators.verificationRequest.TYPE_TOPIC_INPUT).type(fullVerificationRequest.topic, { delay: 200 });
111+
cy.contains(fullVerificationRequest.topic).click();
112+
cy.get(locators.verificationRequest.ADD_TOPIC_SUBMIT).click();
113+
114+
cy.wait("@updateTopics").then((interception) => {
115+
expect(interception.response.statusCode).to.be.oneOf([200, 201]);
116+
});
117+
118+
cy.contains(locators.verificationRequest.DETAIL_TOPIC_TAG, fullVerificationRequest.topic.toUpperCase())
119+
.should("be.visible")
120+
.within(() => {
121+
cy.get(locators.verificationRequest.REMOVE_TOPIC_ICON).click();
122+
});
123+
124+
125+
cy.contains(locators.verificationRequest.DETAIL_TOPIC_TAG, fullVerificationRequest.topic.toUpperCase()).should("not.exist");
126+
})
127+
128+
it("should discard unsaved changes when the edition form is canceled", () => {
129+
goToVerificationRequest(fullRequestHash)
130+
131+
cy.get(locators.verificationRequest.EDIT_BUTTON).should("be.visible").click();
132+
cy.get(locators.verificationRequest.FORM_SOURCE_ADD).click();
133+
cy.get(locators.verificationRequest.FORM_SOURCE_ITEM_1).type(`https://${updatedSource}`);
134+
selectPublicationDate(getPastDay(10));
135+
cy.get(locators.verificationRequest.CANCEL_BUTTON).click();
136+
137+
cy.get(locators.verificationRequest.DETAIL_PUBLICATION_DATE).should("be.visible").and("not.contain", getPastDay(10).format("DD/MM/YYYY"));
138+
cy.get(locators.verificationRequest.DETAIL_SOURCE_1).should("not.exist");
139+
})
140+
});
141+
142+
describe("Minimum verification request flow", () => {
143+
let minRequestHash: string;
144+
145+
it("should allow request creation using only the minimum mandatory information", () => {
146+
openCreateVerificationRequestForm();
147+
cy.intercept("GET", "**/verification-request/**").as("getVerification");
148+
149+
cy.get(locators.verificationRequest.FORM_CONTENT).type(minimumContent);
150+
selectPublicationDate(today);
151+
saveVerificationRequest();
152+
cy.wait("@getVerification").then((interception) => {
153+
getHashFromUrl(interception)
154+
minRequestHash = getHashFromUrl(interception);
155+
156+
cy.log("Hash capturado:", minRequestHash);
157+
});
158+
cy.url().should("match", regexVerificationRequestPage);
159+
160+
assertDetailFields([
161+
[locators.verificationRequest.DETAIL_CONTENT, minimumContent],
162+
[locators.verificationRequest.DETAIL_PUBLICATION_DATE, today.format("DD/MM/YYYY")],
163+
])
164+
});
165+
166+
it("should supplement a minimalist request by adding its first source during edition", () => {
167+
goToVerificationRequest(minRequestHash)
168+
169+
cy.get(locators.verificationRequest.EDIT_BUTTON).should("be.visible").click();
170+
cy.get(locators.verificationRequest.FORM_SOURCE_ITEM_0).type(`https://${fullVerificationRequest.source}`);
171+
selectPublicationDate(getPastDay(1));
172+
saveVerificationRequest();
173+
cy.url().should("match", regexVerificationRequestPage);
174+
175+
assertDetailFields([
176+
[locators.verificationRequest.DETAIL_PUBLICATION_DATE, getPastDay(1).format("DD/MM/YYYY")],
177+
[locators.verificationRequest.DETAIL_SOURCE_0, fullVerificationRequest.source],
178+
])
179+
})
180+
})
181+
});
182+
});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const fullVerificationRequest = {
2+
content: "Verification Request Content",
3+
reportType: "Discurso",
4+
impactArea: "Ambientalismo",
5+
topic: "Socialismo",
6+
heardFrom: "Verification Request heardFrom",
7+
source: "wikimedia.org",
8+
email: "test-cypress@aletheiafact.org",
9+
};
10+
11+
const minimumContent = "Verification Request Content minimium"
12+
13+
const regexVerificationRequestPage = /\/verification-request\/[\w-]+$/
14+
const updatedSource = "www.wikidata.org"
15+
16+
export { fullVerificationRequest, regexVerificationRequestPage, updatedSource, minimumContent }

cypress/support/locators.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ const locators = {
3838
BTN_SUBMIT_CLAIM: "[data-cy=testSaveButton]",
3939
INPUT_TITLE: "[data-cy=testTitleClaimForm]",
4040
INPUT_DATA: "[data-cy=testSelectDate]",
41-
INPUT_DATA_TODAY: ".MuiPickersDay-today",
4241
INPUT_SOURCE: "[data-cy=testSource1]",
4342
},
4443

@@ -52,6 +51,7 @@ const locators = {
5251
ADD_CLAIM: "[data-cy=testFloatButtonAddClaim]",
5352
ADD_PERSONALITY: "[data-cy=testFloatButtonAddPersonality]",
5453
ADD_SOURCE: "[data-cy=testFloatButtonAddSources]",
54+
ADD_VERIFICATION_REQUEST: "[data-cy=testFloatButtonAddVerificationRequest]"
5555
},
5656

5757
claimReview: {
@@ -83,6 +83,49 @@ const locators = {
8383
"[data-cy=testClaimReviewSourcesButton]",
8484
},
8585

86+
verificationRequest: {
87+
FORM_CONTENT: "[data-cy=testClaimReviewcontent]",
88+
FORM_REPORT_TYPE: "[data-cy=testClaimReviewreportType]",
89+
FORM_IMPACT_AREA: "[data-cy=testClaimReviewimpactArea]",
90+
FORM_HEARD_FROM: "[data-cy=testClaimReviewheardFrom]",
91+
FORM_PUBLICATION_DATE: "[data-cy=testSelectDate]",
92+
FORM_SOURCE: "[data-cy=testClaimReviewsource]",
93+
FORM_EMAIL: "[data-cy=testClaimReviewemail]",
94+
95+
FORM_SOURCE_ITEM_0: "[data-cy=testClaimReviewsourceEdit-0]",
96+
FORM_SOURCE_ITEM_1: "[data-cy=testClaimReviewsourceEdit-1]",
97+
FORM_SOURCE_ADD: "[data-cy=testClaimReviewsource-addSources]",
98+
FORM_SOURCE_REMOVE_2: "[data-cy=testClaimReviewsourceRemove-2]",
99+
100+
DETAIL_CONTENT: "[data-cy=testVerificationRequestContent]",
101+
DETAIL_REPORT_TYPE: "[data-cy=testVerificationRequestReportType]",
102+
DETAIL_IMPACT_AREA: "[data-cy=testVerificationRequestImpactArea]",
103+
DETAIL_SOURCE_CHANNEL: "[data-cy=testVerificationRequestSourceChannel]",
104+
DETAIL_SEVERITY: "[data-cy=testVerificationRequestSeverity]",
105+
DETAIL_HEARD_FROM: "[data-cy=testVerificationRequestHeardFrom]",
106+
DETAIL_PUBLICATION_DATE: "[data-cy=testVerificationRequestPublicationDate]",
107+
DETAIL_DATE: "[data-cy=testVerificationRequestDate]",
108+
DETAIL_SOURCE_0: "[data-cy=testVerificationRequestSource0]",
109+
DETAIL_SOURCE_1: "[data-cy=testVerificationRequestSource1]",
110+
111+
ERROR_VALIDATION_CONTENT: "[data-cy=testClaimReviewErrorcontent]",
112+
ERROR_VALIDATION_PUBLICATION_DATE: "[data-cy=testClaimReviewErrorpublicationDate]",
113+
114+
DETAIL_CARD_CONTENT: "[data-cy=testVerificationRequestCardContent0]",
115+
DETAIL_CARD_CONTENT_1: "[data-cy=testVerificationRequestCardContent1]",
116+
117+
ADD_TOPIC_ICON: "[data-cy=testVerificationRequestTopicsToggle]",
118+
TYPE_TOPIC_INPUT: "[data-cy=testVerificationRequestTopicsInput]",
119+
ADD_TOPIC_SUBMIT: "[data-cy=testVerificationRequestAddTopicButton]",
120+
DETAIL_TOPIC_TAG: "[data-cy=testVerificationRequestTopicChip0]",
121+
REMOVE_TOPIC_ICON: "[data-cy=testVerificationRequestTopicRemoveButton0]",
122+
123+
SEE_FULL_BUTTON: "[data-cy=testSeeFullVerificationRequest]",
124+
EDIT_BUTTON: "[data-cy=testVerificationRequestEditButton]",
125+
SAVE_BUTTON: "[data-cy=testSaveButton]",
126+
CANCEL_BUTTON: "[data-cy=testCancelButton]",
127+
},
128+
86129
menu: {
87130
SIDE_MENU: "[data-cy=testOpenSideMenu]",
88131
USER_ICON: "[data-cy=testUserIcon]",

cypress/utils/dateUtils.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import dayjs from "dayjs";
2+
3+
export const today = dayjs();
4+
5+
export const getPastDay = (daysAgo: number) =>
6+
dayjs().subtract(daysAgo, "day");

src/components/AletheiaMenu.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { Roles } from "../types/enums";
1212
import { NameSpaceEnum } from "../types/Namespace";
1313
import { currentNameSpace } from "../atoms/namespace";
1414
import localConfig from "../../config/localConfig";
15+
import { isAdmin } from "../utils/GetUserPermission";
1516

1617
const AletheiaMenu = () => {
1718
const { t } = useTranslation();
@@ -99,7 +100,7 @@ const AletheiaMenu = () => {
99100
{t("menu:kanbanItem")}
100101
</ListItemButton>
101102
)}
102-
{(role === Roles.Admin || role === Roles.SuperAdmin) && (
103+
{isAdmin(role) && (
103104
<>
104105
<ListItemButton
105106
data-cy={"testadminItem"}

src/components/Claim/ClaimView.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import claimApi from "../../api/claim";
1717
import { currentUserRole } from "../../atoms/currentUser";
1818
import { useAtom } from "jotai";
1919
import AffixButtonV2 from "../Collaborative/Components/AffixButtonV2";
20+
import { isAdmin } from "../../utils/GetUserPermission";
2021

2122
const ClaimView = ({ personality, claim, href, hideDescriptions }) => {
2223
const dispatch = useDispatch();
@@ -44,7 +45,7 @@ const ClaimView = ({ personality, claim, href, hideDescriptions }) => {
4445

4546
return (
4647
<>
47-
{(role === Roles.Admin || role === Roles.SuperAdmin) && (
48+
{isAdmin(role) && (
4849
<AdminToolBar
4950
content={claim}
5051
deleteApiFunction={claimApi.deleteClaim}

src/components/ClaimReview/ClaimReviewForm.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { useAtom } from "jotai";
2121
import { useSelector } from "@xstate/react";
2222
import ReportModelButtons from "./ReportModelButtons";
2323
import LoginButton from "../LoginButton";
24+
import { isAdmin } from "../../utils/GetUserPermission";
2425

2526
const ClaimReviewForm = ({
2627
dataHash,
@@ -48,7 +49,7 @@ const ClaimReviewForm = ({
4849
const [formCollapsed, setFormCollapsed] = useState(
4950
isUnassigned && !reportModel
5051
);
51-
const userIsAdmin = role === Roles.Admin || role === Roles.SuperAdmin;
52+
const userIsAdmin = isAdmin(role);
5253
const [showForm, setShowForm] = useState(false);
5354

5455
useEffect(() => {

0 commit comments

Comments
 (0)