contact form tests

This commit is contained in:
Owen Rees
2023-06-22 12:52:41 +02:00
parent ae805e5d80
commit 6f7b840b54
11 changed files with 116 additions and 79 deletions
+1 -7
View File
@@ -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
-1
View File
@@ -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,
-2
View File
@@ -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");
+6
View File
@@ -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>
-55
View File
@@ -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);
// });
// });
// });
// });
+50
View File
@@ -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");
});
});
});
+48 -13
View File
@@ -1,11 +1,27 @@
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", () => {
const testLinks = () => {
cy.get("a:not([href*='mailto:']):not(nav a):not(footer a)").each((link) => {
if (
!link
.prop("href")
.includes("http://www.echecs.asso.fr/FicheTournoi.aspx") // ignore every external FFE tournament link
) {
cy.request({
url: link.prop("href"),
failOnStatusCode: false,
});
cy.log(link.prop("href"));
}
});
};
it("navbar links point to correct pathname as a slug", () => {
cy.viewport(600, 600);
cy.visit("/");
pages.forEach((page) => {
@@ -16,22 +32,41 @@ describe("Test all links", () => {
});
});
it("Check dead links", () => {
pages.forEach((page) => {
cy.visit(`/${navLinkToSlug(page)}`);
cy.get("a:not([href*='mailto:']").each((link) => {
if (
!link
.prop("href")
.includes("http://www.echecs.asso.fr/FicheTournoi.aspx") // ignore every external FFE tournament link
) {
// 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"));
}
});
});
}
);
});
});
+10
View File
@@ -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