mirror of
https://github.com/TheRealOwenRees/echecsfrance.git
synced 2026-07-23 04:26:57 +00:00
contact form tests
This commit is contained in:
@@ -1,10 +1,6 @@
|
||||
TESTS
|
||||
// TODO tests for tournament page:
|
||||
- map and table mounts in tournament page <- get data to send to map/table
|
||||
//TODO data fetching tests
|
||||
//TODO redo layer groups tests
|
||||
//TODO write tests for contact form
|
||||
//TODO dead link tests take too long, split them into separate tests per page
|
||||
|
||||
-----------------------------------------------------------------
|
||||
BUGS
|
||||
@@ -21,20 +17,18 @@ DESIGN CHANGES
|
||||
//TODO test entire site for english to french translations
|
||||
//TODO success and error messages into french - mailer
|
||||
//TODO font size on mobile screen
|
||||
//TODO mobile navbar is creeping into the page by a few pixels when hidden - move it to the right a bit. It is easier to see in light mode
|
||||
//TODO mobile navbar is creeping into the page by a few pixels when hidden - move it to the right a bit. It is easier to see in light mode. I cant see this on Linux
|
||||
//TODO logo for navbar and favicon
|
||||
//TODO mobile map needs improving
|
||||
|
||||
----------------------------------------------------------------
|
||||
LOGIC
|
||||
//TODO SRP for web and API data fetching
|
||||
//TODO error handling
|
||||
//TODO consider offering GraphQL support
|
||||
|
||||
MISC
|
||||
----------------------------------------------------------------
|
||||
//TODO write logger (fullstack open examples)
|
||||
//TODO SEO - next headers etc
|
||||
//TODO multi-language i18n support - https://nextjs.org/docs/app/building-your-application/routing/internationalization
|
||||
//TODO move smaller ui components into a new folder, and make them reusable - such as using generic prop names
|
||||
//TODO readme
|
||||
|
||||
@@ -14,7 +14,6 @@ export async function GET() {
|
||||
try {
|
||||
const client = await clientPromise;
|
||||
const db = client.db("tournamentsFranceDB");
|
||||
|
||||
const results = await dateOrderingFrance(db);
|
||||
const data = results.map(({ _id, ...rest }) => ({
|
||||
id: _id,
|
||||
|
||||
@@ -23,9 +23,7 @@ const getTournaments = async () => {
|
||||
try {
|
||||
const client = await clientPromise;
|
||||
const db = client.db("tournamentsFranceDB");
|
||||
|
||||
const data = await dateOrderingFrance(db);
|
||||
|
||||
return JSON.stringify(data);
|
||||
} catch (error) {
|
||||
throw new Error("Error fetching tournament data");
|
||||
|
||||
@@ -17,6 +17,7 @@ const ContactForm = () => {
|
||||
className={`${
|
||||
responseMessage.isSuccessful ? "text-green-600" : "text-red-600"
|
||||
} italic`}
|
||||
data-cy="info-message"
|
||||
>
|
||||
{responseMessage.message}
|
||||
</p>
|
||||
@@ -51,6 +52,7 @@ const ContactForm = () => {
|
||||
className="shadow-sm bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 dark:shadow-sm-light"
|
||||
placeholder="nom@exemple.com"
|
||||
required
|
||||
data-cy="email-input"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
@@ -68,6 +70,7 @@ const ContactForm = () => {
|
||||
className="block p-3 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 shadow-sm focus:ring-primary-500 focus:border-primary-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 dark:shadow-sm-light"
|
||||
placeholder="Le motif de ma demande"
|
||||
required
|
||||
data-cy="subject-input"
|
||||
/>
|
||||
</div>
|
||||
<div className="sm:col-span-2">
|
||||
@@ -84,12 +87,15 @@ const ContactForm = () => {
|
||||
rows={6}
|
||||
className="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg shadow-sm border border-gray-300 focus:ring-primary-500 focus:border-primary-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500"
|
||||
placeholder="Détaillez ici votre demande..."
|
||||
data-cy="message-input"
|
||||
required
|
||||
></textarea>
|
||||
</div>
|
||||
<button
|
||||
disabled={isSending}
|
||||
type="submit"
|
||||
className="py-3 px-5 text-sm font-medium text-center text-white rounded-lg bg-teal-600 sm:w-fit hover:bg-primary-800 focus:ring-4 focus:outline-none focus:ring-primary-300 dark:hover:bg-primary-700 dark:focus:ring-primary-800 dark:text-white disabled:opacity-25"
|
||||
data-cy="submit-button"
|
||||
>
|
||||
{isSending ? "Sending..." : "Send Message"}
|
||||
</button>
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
// import { Tournament } from "@/types";
|
||||
// import getTournaments from "@/utils/getTournamentData";
|
||||
// import { createLayerGroups } from "@/utils/layerGroups";
|
||||
//
|
||||
|
||||
// // TODO rewrite this test suite since I no longer use fetch for the map
|
||||
// // TODO add tests for the API once it is active
|
||||
// describe("Unit tests of utils directory", () => {
|
||||
// describe("Retrieve tournament data from DB", () => {
|
||||
// let response: Tournament[];
|
||||
// let results: Tournament[];
|
||||
//
|
||||
// describe("France", () => {
|
||||
// before(async () => {
|
||||
// response = await getTournaments("france");
|
||||
// results = response.splice(0, 5);
|
||||
// });
|
||||
//
|
||||
// it("log first 5 results", () => {
|
||||
// results.forEach((result) => cy.log(JSON.stringify(result)));
|
||||
// });
|
||||
//
|
||||
// it("check tournament urls are active", () => {
|
||||
// results.forEach((result) => cy.request(result.url));
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// describe("Create layer groups for map markers", () => {
|
||||
// let response: Tournament[];
|
||||
// let results: Tournament[];
|
||||
// describe("France", () => {
|
||||
// const timeControls = [
|
||||
// { name: "Cadence Lente", colour: "green" },
|
||||
// { name: "Rapide", colour: "blue" },
|
||||
// { name: "Blitz", colour: "yellow" },
|
||||
// { name: "1h KO", colour: "red" },
|
||||
// ];
|
||||
//
|
||||
// before(async () => {
|
||||
// response = await getTournaments("france");
|
||||
// results = response.splice(0, 5);
|
||||
// });
|
||||
//
|
||||
// it("generate layer groups", () => {
|
||||
// const result = timeControls.map((timeControl) => {
|
||||
// return createLayerGroups(timeControl.name, timeControl.colour, {
|
||||
// tournamentData: results,
|
||||
// });
|
||||
// });
|
||||
// cy.wrap(result.length).should("be.greaterThan", 0);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
@@ -0,0 +1,50 @@
|
||||
describe("Contact form", () => {
|
||||
const email = "test@test.com";
|
||||
const invalidEmail = "test@";
|
||||
const subject = "Test Subject";
|
||||
const message = "Test message";
|
||||
|
||||
describe("Invalid data", () => {
|
||||
beforeEach(() => {
|
||||
cy.visit("/contactez-nous");
|
||||
});
|
||||
|
||||
it("invalid email address", () => {
|
||||
cy.getByData("email-input").type(invalidEmail);
|
||||
cy.getByData("subject-input").type(subject);
|
||||
cy.getByData("message-input").type(message);
|
||||
cy.getByData("submit-button").click();
|
||||
cy.getByData("info-message").should("have.text", "");
|
||||
});
|
||||
|
||||
it("missing subject", () => {
|
||||
cy.getByData("email-input").type(email);
|
||||
cy.getByData("message-input").type(message);
|
||||
cy.getByData("submit-button").click();
|
||||
cy.getByData("info-message").should("have.text", "");
|
||||
});
|
||||
|
||||
it("missing message", () => {
|
||||
cy.getByData("email-input").type(email);
|
||||
cy.getByData("subject-input").type(subject);
|
||||
cy.getByData("submit-button").click();
|
||||
cy.getByData("info-message").should("have.text", "");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Valid data", () => {
|
||||
beforeEach(() => {
|
||||
cy.visit("/contactez-nous");
|
||||
});
|
||||
|
||||
it("valid input", () => {
|
||||
cy.getByData("email-input").type(email);
|
||||
cy.getByData("subject-input").type(subject);
|
||||
cy.getByData("message-input").type(message);
|
||||
cy.getByData("submit-button").click().should("be.disabled");
|
||||
cy.wait(3000);
|
||||
cy.getByData("info-message").contains("Thank you");
|
||||
cy.getByData("submit-button").click().should("be.not.disabled");
|
||||
});
|
||||
});
|
||||
});
|
||||
+51
-16
@@ -1,25 +1,12 @@
|
||||
describe("Test all links", () => {
|
||||
describe("Test links", () => {
|
||||
const pages = ["tournois", "qui sommes-nous", "contactez-nous"];
|
||||
|
||||
const navLinkToSlug = (navLink: string) => {
|
||||
return navLink.replace(/\s+/g, "-");
|
||||
};
|
||||
|
||||
it("Check navbar links point to correct pathname as a slug", () => {
|
||||
cy.viewport(600, 600);
|
||||
cy.visit("/");
|
||||
pages.forEach((page) => {
|
||||
cy.get("[data-cy='hamburger-button']").click();
|
||||
cy.contains(page, { matchCase: false }).click();
|
||||
cy.location("pathname").should("eq", `/${navLinkToSlug(page)}`); // url path matches link name, replacing whitespace with hyphens
|
||||
cy.go("back");
|
||||
});
|
||||
});
|
||||
|
||||
it("Check dead links", () => {
|
||||
pages.forEach((page) => {
|
||||
cy.visit(`/${navLinkToSlug(page)}`);
|
||||
cy.get("a:not([href*='mailto:']").each((link) => {
|
||||
const testLinks = () => {
|
||||
cy.get("a:not([href*='mailto:']):not(nav a):not(footer a)").each((link) => {
|
||||
if (
|
||||
!link
|
||||
.prop("href")
|
||||
@@ -32,6 +19,54 @@ describe("Test all links", () => {
|
||||
cy.log(link.prop("href"));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
it("navbar links point to correct pathname as a slug", () => {
|
||||
cy.viewport(600, 600);
|
||||
cy.visit("/");
|
||||
pages.forEach((page) => {
|
||||
cy.get("[data-cy='hamburger-button']").click();
|
||||
cy.contains(page, { matchCase: false }).click();
|
||||
cy.location("pathname").should("eq", `/${navLinkToSlug(page)}`); // url path matches link name, replacing whitespace with hyphens
|
||||
cy.go("back");
|
||||
});
|
||||
});
|
||||
|
||||
// TODO consider doing .each from pages array once links are on each page
|
||||
// TODO at present, the commented out tests have no links so fail
|
||||
it("homepage dead links", () => {
|
||||
cy.visit("/");
|
||||
testLinks();
|
||||
});
|
||||
|
||||
it("tournois dead links", () => {
|
||||
cy.visit("/tournois");
|
||||
testLinks();
|
||||
});
|
||||
|
||||
// it("qui-sommes-nous dead links", () => {s
|
||||
// cy.visit("/qui-sommes-nous");
|
||||
// testLinks();
|
||||
// });
|
||||
//
|
||||
// it("contactez-nous dead links", () => {
|
||||
// cy.visit("/contactez-nous");
|
||||
// testLinks();
|
||||
// });
|
||||
|
||||
//TODO consider 5 random links rather than first 5
|
||||
it("first 5 tournament external links", () => {
|
||||
cy.visit("/tournois");
|
||||
cy.get("a:not([href*='mailto:']):not(nav a):not(footer a)").each(
|
||||
(link, index) => {
|
||||
if (index < 5) {
|
||||
cy.request({
|
||||
url: link.prop("href"),
|
||||
failOnStatusCode: false,
|
||||
});
|
||||
cy.log(link.prop("href"));
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
declare namespace Cypress {
|
||||
interface Chainable {
|
||||
getByData(dataTestAttribute: string): Chainable<JQuery<HTMLElement>>;
|
||||
}
|
||||
}
|
||||
|
||||
Cypress.Commands.add("getByData", (selector) => {
|
||||
return cy.get(`[data-cy=${selector}]`);
|
||||
});
|
||||
|
||||
/// <reference types="cypress" />
|
||||
// ***********************************************
|
||||
// This example commands.ts shows you how to
|
||||
|
||||
Reference in New Issue
Block a user