Skip to content

Commit

Permalink
Merge pull request #504 from CodeYourFuture/chore/test-diagnostics
Browse files Browse the repository at this point in the history
Improve test diagnostics
  • Loading branch information
MitchLloyd authored Jun 4, 2024
2 parents a5ce7f1 + 34460ff commit e443210
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 40 deletions.
66 changes: 34 additions & 32 deletions client/src/App.test.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import {
render,
screen,
fireEvent,
waitForElementToBeRemoved,
} from "@testing-library/react";
import { server } from "./tests/setupTests.js";
import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { http, HttpResponse } from "msw";

import { server } from "./tests/setupTests.js";

import App from "./App.jsx";

describe("Main Page", () => {
/** @type {import("@testing-library/user-event").UserEvent} */
let user;

beforeEach(async () => {
// Here we create a fake backend that will always return two videos when calling the /api/videos endpoint
server.use(
Expand All @@ -34,6 +34,7 @@ describe("Main Page", () => {

// Let's wait for one of the videos to appear
await screen.findByText("Never Gonna Give You Up");
user = userEvent.setup();
});

it("Renders the videos", async () => {
Expand All @@ -43,72 +44,73 @@ describe("Main Page", () => {
);

// We have two videos, so the amount should be two
expect(videoContainers.length).toBe(2);
expect(videoContainers).toHaveLength(2);
});

it("Removes the video when asked to do", async () => {
// we create another fake backend that listens on the delete call, and returns success
server.use(
http.delete("/api/videos/1", () => HttpResponse.json({ success: true }))
http.delete(
"/api/videos/1",
() => new HttpResponse(null, { status: 204 })
)
);

// we find the delete button on the website
const deleteButton = screen.getAllByText("Remove video")[0];
const deleteButton = screen.getAllByRole("button", {
name: "Remove video",
})[0];

// then we click it
fireEvent.click(deleteButton);
await user.click(deleteButton);

// wait for the video to get deleted from the page
await waitForElementToBeRemoved(deleteButton);
await waitFor(() =>
expect(
screen.getAllByRole("button", { name: "Remove video" })
).toHaveLength(1)
);

// we calculate the number of videos after the call
const videoContainers = screen.getAllByText(
(_, e) => e.tagName.toLowerCase() === "iframe"
);

// this should now be only 1
expect(videoContainers.length).toBe(1);
expect(videoContainers).toHaveLength(1);
});

it("Adds a new video when asked to do", async () => {
const title = "New Title";
const url = "https://www.youtube.com/watch?v=CDEYRFUTURE";

// we set up a fake backend that allows us to send a new video. It only allows one specific title and url however
server.use(
http.post("/api/videos", async ({ request }) => {
const data = await request.json();
if (
data.title != "New Title" ||
data.url != "https://www.youtube.com/watch?v=CDEYRFUTURE"
) {
return HttpResponse.json({ success: false });
if (data.title !== title || data.url !== url) {
return HttpResponse.json({ success: false }, { status: 400 });
}
return HttpResponse.json({
id: 3,
title: "New Title",
url: "https://www.youtube.com/watch?v=CDEYRFUTURE",
});
return HttpResponse.json({ id: 3, title, url });
})
);

// we fill in the form
fireEvent.change(screen.getByRole("textbox", { name: "Title:" }), {
target: { value: "New Title" },
});
fireEvent.change(screen.getByRole("textbox", { name: "Url:" }), {
target: { value: "https://www.youtube.com/watch?v=CDEYRFUTURE" },
});
await user.type(screen.getByRole("textbox", { name: "Title:" }), title);
await user.type(screen.getByRole("textbox", { name: "Url:" }), url);

// then click submit
fireEvent.click(screen.getByRole("button", { name: "Submit" }));
await user.click(screen.getByRole("button", { name: "Submit" }));

// wait for the new video to appear
await screen.findByText("New Title");
await screen.findByText(title);

// afterwards we calculate the number of videos on the page
const videoContainers = screen.getAllByText(
(_, e) => e.tagName.toLowerCase() === "iframe"
);

// this should now be three
expect(videoContainers.length).toBe(3);
expect(videoContainers).toHaveLength(3);
});
});
2 changes: 0 additions & 2 deletions db/initdb.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
\c videorec;

DROP TABLE IF EXISTS videos CASCADE;

CREATE TABLE videos (
Expand Down
14 changes: 8 additions & 6 deletions server/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ describe("/api", () => {
const response = await request(app).get("/api/videos");

expect(response.statusCode).toBe(200);
expect(response.body[0].title).toBe("Never Gonna Give You Up");
expect(response.body[0].url).toBe(
"https://www.youtube.com/watch?v=dQw4w9WgXcQ"
);
expect(response.body).toEqual([
{
title: "Never Gonna Give You Up",
url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
},
]);
});
});

Expand All @@ -21,7 +23,7 @@ describe("/api", () => {
it("Returns a successful response if the id exists", async () => {
const response = await request(app).delete("/api/videos/1");

expect(response.statusCode).toBe(200);
expect(response.statusCode).toBe(204);
});

it("Deletes the video from the database if the id exists", async () => {
Expand All @@ -31,7 +33,7 @@ describe("/api", () => {
"SELECT * FROM videos WHERE id = $1",
[1]
);
expect(dbResponse.rows.length).toBe(0);
expect(dbResponse.rows).toHaveLength(0);
});
});
});
Expand Down

0 comments on commit e443210

Please sign in to comment.