diff --git a/tests/commonUtils.ts b/tests/commonUtils.ts
new file mode 100644
index 0000000..6a2cbe6
--- /dev/null
+++ b/tests/commonUtils.ts
@@ -0,0 +1,13 @@
+import { MockResponseInit } from "jest-fetch-mock";
+
+export const htmlRes = (translation: string, className = "result-container") => `
+
+`;
+
+export const resolveFetchWith = (params: string | MockResponseInit) => (
+ fetchMock.mockResponseOnce(async () => params)
+);
diff --git a/tests/pages/[[...slug]].test.tsx b/tests/pages/[[...slug]].test.tsx
index be26efb..fff761d 100644
--- a/tests/pages/[[...slug]].test.tsx
+++ b/tests/pages/[[...slug]].test.tsx
@@ -1,18 +1,12 @@
import { screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
+import { htmlRes, resolveFetchWith } from "../commonUtils";
import Router from "next/router";
import { getPage } from "next-page-tester";
import faker from "faker";
import { getStaticProps } from "../../pages/[[...slug]]";
-const mockPush = jest.fn().mockImplementation(async () => true);
-Router.push = mockPush;
-
-const html = (translation: string) => `
-
- ${translation}
-
-`;
+const mockPush = jest.spyOn(Router, "push").mockImplementation(async () => true);
beforeEach(() => {
fetchMock.resetMocks();
@@ -45,7 +39,8 @@ describe("getStaticProps", () => {
it("returns translation & initial values on 3 params", async () => {
const translation = faker.random.words();
- fetchMock.mockResponseOnce(async () => ({ body: html(translation) }));
+ const html = htmlRes(translation);
+ resolveFetchWith(html);
const slug = [source, target, query];
expect(await getStaticProps({ params: { slug } })).toStrictEqual({
@@ -72,6 +67,10 @@ describe("Page", () => {
const query = screen.getByRole("textbox", { name: /query/i });
userEvent.type(query, faker.random.words());
+ await waitFor(
+ () => expect(Router.push).not.toHaveBeenCalled(),
+ { timeout: 250 }
+ );
await waitFor(
() => expect(Router.push).toHaveBeenCalledTimes(1),
{ timeout: 2500 }
@@ -82,10 +81,10 @@ describe("Page", () => {
const initial = {
source: "ca",
target: "es",
- query: faker.random.words()
+ query: encodeURIComponent(faker.random.words())
};
const translation = faker.random.words();
- fetchMock.mockResponseOnce(async () => ({ body: html(translation) }));
+ resolveFetchWith(htmlRes(translation));
const { render } = await getPage({
route: `/${initial.source}/${initial.target}/${initial.query}`
@@ -93,22 +92,22 @@ describe("Page", () => {
render();
expect(await screen.findByText(translation)).toBeVisible();
- const query = screen.getByRole("textbox", { name: /query/i });
- expect(query).toHaveValue(encodeURIComponent(initial.query));
const source = screen.getByRole("combobox", { name: /source/i });
expect(source).toHaveValue(initial.source);
const target = screen.getByRole("combobox", { name: /target/i });
expect(target).toHaveValue(initial.target);
+ const query = screen.getByRole("textbox", { name: /query/i });
+ expect(query).toHaveValue(initial.query);
});
it("parses urlencoding correctly", async () => {
const initial = {
source: "zh",
target: "en",
- query: "你好"
+ query: encodeURIComponent("你好")
};
const translation = "Hello";
- fetchMock.mockResponseOnce(async () => ({ body: html(translation) }));
+ resolveFetchWith(htmlRes(translation));
const { render } = await getPage({
route: `/${initial.source}/${initial.target}/${initial.query}`
@@ -121,11 +120,11 @@ describe("Page", () => {
const target = screen.getByRole("combobox", { name: /target/i });
expect(target).toHaveValue(initial.target);
const query = screen.getByRole("textbox", { name: /query/i });
- expect(query).toHaveValue(encodeURIComponent(initial.query));
+ expect(query).toHaveValue(initial.query);
});
it("switches the page on language change", async () => {
- fetchMock.mockResponseOnce(async () => ({ body: html(faker.random.words()) }));
+ resolveFetchWith(htmlRes(faker.random.words()));
const { render } = await getPage({
route: `/auto/en/${faker.random.words()}`
diff --git a/tests/utils/language.test.ts b/tests/utils/language.test.ts
index 3c3d958..e42bf9d 100644
--- a/tests/utils/language.test.ts
+++ b/tests/utils/language.test.ts
@@ -1,46 +1,51 @@
import faker from "faker";
-import { replaceBoth, retrieveFiltered } from "../../utils/language";
+import { replaceBoth, retrieveFiltered, CheckType, LangType } from "../../utils/language";
import { languages, exceptions, mappings } from "../../utils/languages.json";
describe("replaceBoth", () => {
+ const testReplacer = (
+ checkType: CheckType,
+ checkObj: {
+ [key in LangType]: {
+ [key: string]: string
+ }
+ },
+ langType: LangType
+ ) => (
+ Object.entries(checkObj[langType]).forEach(([code, replacement]) => {
+ const res = replaceBoth(checkType, { source: "", target: "", [langType]: code })
+ expect(res[langType]).toBe(replacement);
+ })
+ );
+
it("replaces excepted sources correctly", () => {
- Object.entries(exceptions.source).forEach(([code, replacement]) => {
- const { source } = replaceBoth("exception", { source: code, target: "" })
- expect(source).toBe(replacement);
- });
+ testReplacer("exception", exceptions, "source");
});
it("replaces excepted targets correctly", () => {
- Object.entries(exceptions.target).forEach(([code, replacement]) => {
- const { target } = replaceBoth("exception", { source: "", target: code })
- expect(target).toBe(replacement);
- });
+ testReplacer("exception", exceptions, "target");
});
it("replaces mapped sources correctly", () => {
- Object.entries(mappings.source).forEach(([code, replacement]) => {
- const { source } = replaceBoth("mapping", { source: code, target: "" })
- expect(source).toBe(replacement);
- });
+ testReplacer("mapping", mappings, "source");
});
it("replaces mapped targets correctly", () => {
- Object.entries(mappings.target).forEach(([code, replacement]) => {
- const { target } = replaceBoth("mapping", { source: "", target: code })
- expect(target).toBe(replacement);
- });
+ testReplacer("mapping", mappings, "target");
});
});
describe("retrieveFiltered", () => {
+ const filteredEntries = (langType: LangType, current: string) => (
+ Object.entries(languages).filter(([code]) => !Object.keys(exceptions[langType]).includes(code) && code !== current)
+ );
+
it("filters by exceptions & by opposite values", () => {
const source = faker.random.locale();
const target = faker.random.locale();
- const sourceKeys = Object.keys(languages).filter(code => !Object.keys(exceptions.source).includes(code) && code !== target);
- const targetKeys = Object.keys(languages).filter(code => !Object.keys(exceptions.target).includes(code) && code !== source);
const { sourceLangs, targetLangs } = retrieveFiltered(source, target);
- expect(sourceLangs.map(([code]) => code)).toStrictEqual(sourceKeys);
- expect(targetLangs.map(([code]) => code)).toStrictEqual(targetKeys);
+ expect(sourceLangs).toStrictEqual(filteredEntries("source", target));
+ expect(targetLangs).toStrictEqual(filteredEntries("target", source));
});
});
diff --git a/tests/utils/translate.test.ts b/tests/utils/translate.test.ts
index 70a8c0a..e52c6f9 100644
--- a/tests/utils/translate.test.ts
+++ b/tests/utils/translate.test.ts
@@ -1,3 +1,4 @@
+import { htmlRes, resolveFetchWith } from "../commonUtils";
import faker from "faker";
import { googleScrape, extractSlug } from "../../utils/translate";
@@ -12,20 +13,15 @@ describe("googleScrape", () => {
it("parses html response correctly", async () => {
const translation = faker.random.words();
- const className = "result-container";
- const html = `
-
- ${translation}
-
- `;
- fetchMock.mockResponseOnce(async () => ({ body: html }));
+ const html = htmlRes(translation);
+ resolveFetchWith(html);
expect(await googleScrape(source, target, query)).toStrictEqual({ translation });
});
it("returns status code on request error", async () => {
const status = faker.random.number({ min: 400, max: 499 });
- fetchMock.mockResponseOnce(async () => ({ status }));
+ resolveFetchWith({ status });
expect(await googleScrape(source, target, query)).toStrictEqual({ statusCode: status });
});
@@ -40,12 +36,8 @@ describe("googleScrape", () => {
it("returns correct message on parsing wrong class", async () => {
const translation = faker.random.words();
const className = "wrong-container";
- const html = `
-
- ${translation}
-
- `;
- fetchMock.mockResponseOnce(async () => ({ body: html }));
+ const html = htmlRes(translation, className);
+ resolveFetchWith(html);
const res = await googleScrape(source, target, query);
expect(res?.errorMsg).toMatch(/parsing/);
diff --git a/utils/language.ts b/utils/language.ts
index c376c62..3719d52 100644
--- a/utils/language.ts
+++ b/utils/language.ts
@@ -3,16 +3,16 @@ import { languages, exceptions, mappings } from "./languages.json";
const checkTypes = {
exception: exceptions,
mapping: mappings
-}
+};
-type CheckType = keyof typeof checkTypes;
+export type CheckType = keyof typeof checkTypes;
const langTypes = [
"source",
"target"
] as const;
-type LangType = typeof langTypes[number];
+export type LangType = typeof langTypes[number];
const isKeyOf = (obj: T) => (key: keyof any): key is keyof T => key in obj;