2021-03-18 18:52:58 +01:00
|
|
|
import { render, screen, waitFor } from "../reactUtils";
|
2021-03-13 19:37:44 +01:00
|
|
|
import { htmlRes, resolveFetchWith } from "../commonUtils";
|
2021-03-18 18:52:58 +01:00
|
|
|
import userEvent from "@testing-library/user-event";
|
2021-03-13 12:00:41 +01:00
|
|
|
import Router from "next/router";
|
|
|
|
|
import faker from "faker";
|
2021-03-18 18:52:58 +01:00
|
|
|
import Page, { getStaticProps } from "../../pages/[[...slug]]";
|
2021-03-13 12:00:41 +01:00
|
|
|
|
2021-03-13 19:37:44 +01:00
|
|
|
const mockPush = jest.spyOn(Router, "push").mockImplementation(async () => true);
|
2021-03-13 12:00:41 +01:00
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
|
fetchMock.resetMocks();
|
|
|
|
|
mockPush.mockReset();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe("getStaticProps", () => {
|
|
|
|
|
const source = faker.random.locale();
|
|
|
|
|
const target = faker.random.locale();
|
|
|
|
|
const query = faker.random.words();
|
|
|
|
|
|
2021-03-18 23:47:12 +01:00
|
|
|
it("returns home on empty params", async () => {
|
|
|
|
|
expect(await getStaticProps({ params: {} })).toStrictEqual({ props: { home: true } });
|
2021-03-13 12:00:41 +01:00
|
|
|
});
|
|
|
|
|
|
2021-03-18 23:47:12 +01:00
|
|
|
it("returns not found on >=4 params", async () => {
|
2021-03-13 12:00:41 +01:00
|
|
|
const slug = [source, target, query, ""];
|
|
|
|
|
expect(await getStaticProps({ params: { slug } })).toStrictEqual({ notFound: true });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("redirects on 1 param", async () => {
|
|
|
|
|
const slug = [query];
|
|
|
|
|
expect(await getStaticProps({ params: { slug } })).toMatchObject({ redirect: expect.any(Object) });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("redirects on 2 params", async () => {
|
|
|
|
|
const slug = [target, query];
|
|
|
|
|
expect(await getStaticProps({ params: { slug } })).toMatchObject({ redirect: expect.any(Object) });
|
|
|
|
|
});
|
|
|
|
|
|
2021-03-25 16:48:46 +01:00
|
|
|
it("returns translation, audio & initial values on 3 params", async () => {
|
2021-03-18 23:47:12 +01:00
|
|
|
const translationRes = faker.random.words();
|
|
|
|
|
resolveFetchWith(htmlRes(translationRes));
|
2021-03-13 12:00:41 +01:00
|
|
|
|
|
|
|
|
const slug = [source, target, query];
|
|
|
|
|
expect(await getStaticProps({ params: { slug } })).toStrictEqual({
|
|
|
|
|
props: {
|
2021-03-18 23:47:12 +01:00
|
|
|
translationRes,
|
2021-03-25 16:48:46 +01:00
|
|
|
audio: {
|
|
|
|
|
source: expect.any(Array),
|
|
|
|
|
target: expect.any(Array)
|
|
|
|
|
},
|
2021-03-13 12:00:41 +01:00
|
|
|
initial: {
|
|
|
|
|
source,
|
|
|
|
|
target,
|
|
|
|
|
query
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
revalidate: expect.any(Number)
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe("Page", () => {
|
2021-03-25 16:48:46 +01:00
|
|
|
const translationRes = faker.random.words();
|
|
|
|
|
const randomAudio = Array.from({ length: 10 }, () => faker.random.number(100));
|
|
|
|
|
const audio = {
|
|
|
|
|
source: randomAudio,
|
|
|
|
|
target: randomAudio
|
|
|
|
|
};
|
|
|
|
|
|
2021-03-18 18:52:58 +01:00
|
|
|
it("loads the layout correctly", async () => {
|
2021-03-18 23:47:12 +01:00
|
|
|
render(<Page home={true} />);
|
2021-03-18 18:52:58 +01:00
|
|
|
|
|
|
|
|
expect(screen.getByRole("link", { name: /skip to content/i })).toBeEnabled();
|
|
|
|
|
expect(await screen.findByRole("img", { name: /logo/i })).toBeVisible();
|
|
|
|
|
expect(screen.getByRole("button", { name: /toggle color mode/i })).toBeEnabled();
|
|
|
|
|
expect(screen.getByRole("link", { name: /github/i })).toBeEnabled();
|
|
|
|
|
expect(screen.getByText(/\xA9/)).toBeVisible();
|
|
|
|
|
});
|
|
|
|
|
|
2021-03-13 12:00:41 +01:00
|
|
|
it("switches the page on query change", async () => {
|
2021-03-18 23:47:12 +01:00
|
|
|
render(<Page home={true} />)
|
2021-03-13 12:00:41 +01:00
|
|
|
|
2021-03-18 18:52:58 +01:00
|
|
|
const query = screen.getByRole("textbox", { name: /translation query/i });
|
2021-03-13 12:00:41 +01:00
|
|
|
userEvent.type(query, faker.random.words());
|
|
|
|
|
|
2021-03-13 19:37:44 +01:00
|
|
|
await waitFor(
|
|
|
|
|
() => expect(Router.push).not.toHaveBeenCalled(),
|
|
|
|
|
{ timeout: 250 }
|
|
|
|
|
);
|
2021-03-13 12:00:41 +01:00
|
|
|
await waitFor(
|
|
|
|
|
() => expect(Router.push).toHaveBeenCalledTimes(1),
|
|
|
|
|
{ timeout: 2500 }
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("translates & loads initials correctly", async () => {
|
|
|
|
|
const initial = {
|
|
|
|
|
source: "ca",
|
|
|
|
|
target: "es",
|
2021-03-18 18:52:58 +01:00
|
|
|
query: faker.random.words()
|
2021-03-13 12:00:41 +01:00
|
|
|
};
|
2021-03-25 16:48:46 +01:00
|
|
|
render(<Page translationRes={translationRes} audio={audio} initial={initial} />);
|
2021-03-13 12:00:41 +01:00
|
|
|
|
2021-03-18 18:52:58 +01:00
|
|
|
const source = screen.getByRole("combobox", { name: /source language/i });
|
2021-03-13 12:00:41 +01:00
|
|
|
expect(source).toHaveValue(initial.source);
|
2021-03-18 18:52:58 +01:00
|
|
|
const target = screen.getByRole("combobox", { name: /target language/i });
|
2021-03-13 12:00:41 +01:00
|
|
|
expect(target).toHaveValue(initial.target);
|
2021-03-18 18:52:58 +01:00
|
|
|
const query = screen.getByRole("textbox", { name: /translation query/i });
|
2021-03-13 19:37:44 +01:00
|
|
|
expect(query).toHaveValue(initial.query);
|
2021-03-18 18:52:58 +01:00
|
|
|
const translation = screen.getByRole("textbox", { name: /translation result/i });
|
2021-03-18 23:47:12 +01:00
|
|
|
expect(translation).toHaveValue(translationRes);
|
2021-03-13 12:00:41 +01:00
|
|
|
});
|
|
|
|
|
|
2021-03-18 18:52:58 +01:00
|
|
|
it("switches the page on language change", async () => {
|
2021-03-13 12:00:41 +01:00
|
|
|
const initial = {
|
2021-03-18 18:52:58 +01:00
|
|
|
source: "auto",
|
2021-03-13 12:00:41 +01:00
|
|
|
target: "en",
|
2021-03-18 18:52:58 +01:00
|
|
|
query: faker.random.words()
|
2021-03-13 12:00:41 +01:00
|
|
|
};
|
2021-03-25 16:48:46 +01:00
|
|
|
render(<Page translationRes={translationRes} audio={audio} initial={initial} />);
|
2021-03-13 12:00:41 +01:00
|
|
|
|
2021-03-18 18:52:58 +01:00
|
|
|
const source = screen.getByRole("combobox", { name: /source language/i });
|
2021-03-13 12:00:41 +01:00
|
|
|
|
|
|
|
|
const sourceVal = "eo";
|
|
|
|
|
userEvent.selectOptions(source, sourceVal);
|
|
|
|
|
expect(source).toHaveValue(sourceVal);
|
|
|
|
|
|
|
|
|
|
await waitFor(() => expect(Router.push).toHaveBeenCalledTimes(1));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("doesn't switch the page on language change on the start page", async () => {
|
2021-03-18 23:47:12 +01:00
|
|
|
render(<Page home={true} />);
|
2021-03-13 12:00:41 +01:00
|
|
|
|
2021-03-18 18:52:58 +01:00
|
|
|
const source = screen.getByRole("combobox", { name: /source language/i });
|
2021-03-13 12:00:41 +01:00
|
|
|
|
|
|
|
|
const sourceVal = "eo";
|
|
|
|
|
userEvent.selectOptions(source, sourceVal);
|
|
|
|
|
expect(source).toHaveValue(sourceVal);
|
|
|
|
|
|
|
|
|
|
await waitFor(() => expect(Router.push).not.toHaveBeenCalled());
|
|
|
|
|
});
|
2021-03-18 18:52:58 +01:00
|
|
|
|
2021-03-18 23:47:12 +01:00
|
|
|
it("switches languages & translations", async () => {
|
|
|
|
|
const initial = {
|
|
|
|
|
source: "es",
|
|
|
|
|
target: "ca",
|
|
|
|
|
query: faker.random.words()
|
|
|
|
|
};
|
2021-03-25 16:48:46 +01:00
|
|
|
render(<Page translationRes={translationRes} audio={audio} initial={initial} />);
|
2021-03-18 23:47:12 +01:00
|
|
|
|
|
|
|
|
const btnSwitch = screen.getByRole("button", { name: /switch languages/i });
|
|
|
|
|
userEvent.click(btnSwitch);
|
|
|
|
|
|
|
|
|
|
expect(screen.getByRole("combobox", { name: /source language/i })).toHaveValue(initial.target);
|
|
|
|
|
expect(screen.getByRole("combobox", { name: /target language/i })).toHaveValue(initial.source);
|
|
|
|
|
expect(screen.getByRole("textbox", { name: /translation query/i })).toHaveValue(translationRes);
|
|
|
|
|
expect(screen.getByRole("textbox", { name: /translation result/i })).toHaveValue("");
|
|
|
|
|
|
|
|
|
|
await waitFor(() => expect(Router.push).toHaveBeenCalledTimes(1));
|
|
|
|
|
});
|
|
|
|
|
|
2021-03-25 16:48:46 +01:00
|
|
|
it("loads audio & clipboard correctly", async () => {
|
|
|
|
|
const initial = {
|
|
|
|
|
source: "eo",
|
|
|
|
|
target: "zh",
|
|
|
|
|
query: faker.random.words()
|
|
|
|
|
};
|
|
|
|
|
render(<Page translationRes={translationRes} audio={audio} initial={initial} />);
|
|
|
|
|
|
|
|
|
|
const btnsAudio = screen.getAllByRole("button", { name: /play audio/i });
|
|
|
|
|
btnsAudio.forEach(btn => expect(btn).toBeVisible());
|
|
|
|
|
const btnCopy = screen.getByRole("button", { name: /copy to clipboard/i });
|
|
|
|
|
expect(btnCopy).toBeEnabled();
|
|
|
|
|
});
|
|
|
|
|
|
2021-03-18 18:52:58 +01:00
|
|
|
it("renders error page on status code", async () => {
|
|
|
|
|
const code = faker.random.number({ min: 400, max: 599 });
|
|
|
|
|
render(<Page statusCode={code} />);
|
|
|
|
|
await waitFor(() => expect(screen.getByText(code)).toBeVisible());
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("shows alert correctly on error", async () => {
|
|
|
|
|
const errorMsg = faker.random.words();
|
|
|
|
|
render(<Page errorMsg={errorMsg} />);
|
|
|
|
|
|
|
|
|
|
const alert = screen.getByRole("alert");
|
|
|
|
|
|
|
|
|
|
await waitFor(() => expect(alert).toBeVisible());
|
|
|
|
|
expect(alert).toHaveTextContent(/unexpected error/i);
|
|
|
|
|
expect(alert).toHaveTextContent(errorMsg);
|
|
|
|
|
});
|
2021-03-13 12:00:41 +01:00
|
|
|
});
|