Add language endpoint to developer APIs (#41)
* Added languages endpoint and its tests
This commit is contained in:
@@ -58,7 +58,9 @@ it("returns audio triggering fetch", async () => {
|
||||
query: `
|
||||
query($lang: String! $text: String!) {
|
||||
audio(lang: $lang query: $text) {
|
||||
lang
|
||||
lang {
|
||||
code
|
||||
}
|
||||
text
|
||||
audio
|
||||
}
|
||||
@@ -66,15 +68,15 @@ it("returns audio triggering fetch", async () => {
|
||||
`,
|
||||
variables: { lang, text }
|
||||
});
|
||||
expect(data).toMatchObject({ audio: { lang, text, audio: expect.any(Array) } });
|
||||
expect(data).toMatchObject({ audio: { lang: { code: lang }, text, audio: expect.any(Array) } });
|
||||
expect(fetch).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("returns null on translation error", async () => {
|
||||
it("returns null and throws on translation error", async () => {
|
||||
const text = faker.random.words();
|
||||
fetchMock.mockRejectOnce();
|
||||
|
||||
const { data } = await query({
|
||||
const { data, errors } = await query({
|
||||
query: `
|
||||
query($text: String!) {
|
||||
translation(query: $text) {
|
||||
@@ -86,15 +88,16 @@ it("returns null on translation error", async () => {
|
||||
`,
|
||||
variables: { text }
|
||||
});
|
||||
expect(data).toMatchObject({ translation: { target: { text: null } } });
|
||||
expect(data).toBeNull();
|
||||
expect(errors).toBeTruthy();
|
||||
});
|
||||
|
||||
it("returns null on audio error", async () => {
|
||||
it("returns null and throws on audio error", async () => {
|
||||
const lang = faker.random.locale();
|
||||
const text = faker.random.words();
|
||||
fetchMock.mockRejectOnce();
|
||||
|
||||
const { data } = await query({
|
||||
const { data, errors } = await query({
|
||||
query: `
|
||||
query($lang: String! $text: String!) {
|
||||
audio(lang: $lang query: $text) {
|
||||
@@ -104,29 +107,52 @@ it("returns null on audio error", async () => {
|
||||
`,
|
||||
variables: { lang, text }
|
||||
});
|
||||
expect(data).toMatchObject({ audio: { audio: null } });
|
||||
expect(data).toBeNull();
|
||||
expect(errors).toBeTruthy();
|
||||
});
|
||||
|
||||
it("keeps a default value for both source and target languages", async () => {
|
||||
const text = faker.random.words();
|
||||
fetchMock.mockRejectOnce();
|
||||
const translation = faker.random.words();
|
||||
resolveFetchWith(htmlRes(translation));
|
||||
|
||||
const { data } = await query({
|
||||
query: `
|
||||
query($text: String!) {
|
||||
translation(query: $text) {
|
||||
source {
|
||||
lang
|
||||
lang {
|
||||
code
|
||||
name
|
||||
}
|
||||
}
|
||||
target {
|
||||
lang
|
||||
lang {
|
||||
code
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: { text }
|
||||
});
|
||||
expect(data).toMatchObject({ translation: { source: { lang: "auto" }, target: { lang: "en" } } });
|
||||
expect(data).toMatchObject({
|
||||
translation: {
|
||||
source: {
|
||||
lang: {
|
||||
code: "auto",
|
||||
name: "Detect"
|
||||
}
|
||||
},
|
||||
target: {
|
||||
lang: {
|
||||
code: "en",
|
||||
name: "English"
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it("throws error on empty query in translation", async () => {
|
||||
@@ -135,10 +161,14 @@ it("throws error on empty query in translation", async () => {
|
||||
query {
|
||||
translation {
|
||||
source {
|
||||
lang
|
||||
lang {
|
||||
code
|
||||
}
|
||||
}
|
||||
target {
|
||||
lang
|
||||
lang {
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,7 +185,9 @@ it("throws error on empty lang or query in audio", async () => {
|
||||
query: `
|
||||
query($lang: String!) {
|
||||
audio(lang: $lang) {
|
||||
lang
|
||||
lang {
|
||||
code
|
||||
}
|
||||
text
|
||||
}
|
||||
}
|
||||
@@ -168,7 +200,9 @@ it("throws error on empty lang or query in audio", async () => {
|
||||
query: `
|
||||
query($text: String!) {
|
||||
audio(query: $text) {
|
||||
lang
|
||||
lang {
|
||||
code
|
||||
}
|
||||
text
|
||||
}
|
||||
}
|
||||
@@ -177,3 +211,44 @@ it("throws error on empty lang or query in audio", async () => {
|
||||
});
|
||||
expect(langErrors).toBeTruthy();
|
||||
});
|
||||
|
||||
it("returns languages on empty type", async () => {
|
||||
const { data } = await query({
|
||||
query: `
|
||||
query {
|
||||
languages {
|
||||
code
|
||||
}
|
||||
}
|
||||
`
|
||||
});
|
||||
expect(data).toMatchObject({ languages: expect.any(Array) });
|
||||
});
|
||||
|
||||
it("returns languages on 'source' type", async () => {
|
||||
const { data } = await query({
|
||||
query: `
|
||||
query($type: LangType!) {
|
||||
languages(type: $type) {
|
||||
code
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: { type: "SOURCE" }
|
||||
});
|
||||
expect(data).toMatchObject({ languages: expect.any(Array) });
|
||||
});
|
||||
|
||||
it("returns languages on 'target' type", async () => {
|
||||
const { data } = await query({
|
||||
query: `
|
||||
query($type: LangType!) {
|
||||
languages(type: $type) {
|
||||
code
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: { type: "TARGET" }
|
||||
});
|
||||
expect(data).toMatchObject({ languages: expect.any(Array) });
|
||||
});
|
||||
|
||||
65
tests/pages/api/v1/languages/[[...slug]].test.ts
Normal file
65
tests/pages/api/v1/languages/[[...slug]].test.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import httpMocks from "node-mocks-http";
|
||||
import handler from "@pages/api/v1/languages/[[...slug]]";
|
||||
|
||||
it("returns 404 on >1 params", async () => {
|
||||
const { req, res } = httpMocks.createMocks<any, any>({
|
||||
method: "GET",
|
||||
query: { slug: ["one", "two"] }
|
||||
});
|
||||
|
||||
await handler(req, res);
|
||||
expect(res.statusCode).toBe(404);
|
||||
});
|
||||
|
||||
it("returns 405 on forbidden method", async () => {
|
||||
const { req, res } = httpMocks.createMocks<any, any>({
|
||||
method: "POST",
|
||||
query: {}
|
||||
});
|
||||
|
||||
await handler(req, res);
|
||||
expect(res.statusCode).toBe(405);
|
||||
});
|
||||
|
||||
it("returns 400 on wrong param", async () => {
|
||||
const { req, res } = httpMocks.createMocks<any, any>({
|
||||
method: "GET",
|
||||
query: { slug: ["other"] }
|
||||
});
|
||||
|
||||
await handler(req, res);
|
||||
expect(res.statusCode).toBe(400);
|
||||
});
|
||||
|
||||
it("returns 200 on empty param", async () => {
|
||||
const { req, res } = httpMocks.createMocks<any, any>({
|
||||
method: "GET",
|
||||
query: {}
|
||||
});
|
||||
|
||||
await handler(req, res);
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(res._getJSONData()).toStrictEqual({ languages: expect.any(Array) });
|
||||
});
|
||||
|
||||
it("returns 200 on 'source' param", async () => {
|
||||
const { req, res } = httpMocks.createMocks<any, any>({
|
||||
method: "GET",
|
||||
query: { slug: ["source"] }
|
||||
});
|
||||
|
||||
await handler(req, res);
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(res._getJSONData()).toStrictEqual({ languages: expect.any(Array) });
|
||||
});
|
||||
|
||||
it("returns 200 on 'target' param", async () => {
|
||||
const { req, res } = httpMocks.createMocks<any, any>({
|
||||
method: "GET",
|
||||
query: { slug: ["target"] }
|
||||
});
|
||||
|
||||
await handler(req, res);
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(res._getJSONData()).toStrictEqual({ languages: expect.any(Array) });
|
||||
});
|
||||
@@ -1,4 +1,5 @@
|
||||
import { replaceBoth, retrieveFiltered, CheckType, LangType } from "@utils/language";
|
||||
import faker from "faker";
|
||||
import { replaceBoth, retrieveFromType, getName, CheckType, LangType } from "@utils/language";
|
||||
import { languages, exceptions, mappings } from "@utils/languages.json";
|
||||
|
||||
describe("replaceBoth", () => {
|
||||
@@ -34,14 +35,34 @@ describe("replaceBoth", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("retrieveFiltered", () => {
|
||||
const filteredEntries = (langType: LangType) => (
|
||||
Object.entries(languages).filter(([code]) => !Object.keys(exceptions[langType]).includes(code))
|
||||
describe("retrieveFromType", () => {
|
||||
const checkExceptions = (langType: LangType) => (
|
||||
retrieveFromType(langType).forEach(([code]) => !Object.keys(exceptions).includes(code))
|
||||
);
|
||||
|
||||
it("filters by exceptions", () => {
|
||||
const { sourceLangs, targetLangs } = retrieveFiltered();
|
||||
expect(sourceLangs).toStrictEqual(filteredEntries("source"));
|
||||
expect(targetLangs).toStrictEqual(filteredEntries("target"));
|
||||
it("returns full list on empty type", () => {
|
||||
expect(retrieveFromType()).toStrictEqual(Object.entries(languages));
|
||||
});
|
||||
|
||||
it("filters source exceptions", () => {
|
||||
checkExceptions("source");
|
||||
});
|
||||
|
||||
it("filters target exceptions", () => {
|
||||
checkExceptions("target");
|
||||
});
|
||||
});
|
||||
|
||||
describe("getName", () => {
|
||||
it("returns name from valid code", () => {
|
||||
const langEntries = Object.entries(languages);
|
||||
const randomEntry = faker.random.arrayElement(langEntries);
|
||||
const [code, name] = randomEntry;
|
||||
expect(getName(code)).toEqual(name);
|
||||
});
|
||||
|
||||
it("returns null on wrong code", () => {
|
||||
const randomCode = faker.random.words();
|
||||
expect(getName(randomCode)).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -24,14 +24,14 @@ describe("googleScrape", () => {
|
||||
resolveFetchWith({ status });
|
||||
|
||||
const res = await googleScrape(source, target, query);
|
||||
expect(res?.errorMsg).toMatch(/retrieving/);
|
||||
expect("errorMsg" in res && res.errorMsg).toMatch(/retrieving/);
|
||||
});
|
||||
|
||||
it("returns correct message on network error", async () => {
|
||||
fetchMock.mockRejectOnce();
|
||||
|
||||
const res = await googleScrape(source, target, query);
|
||||
expect(res?.errorMsg).toMatch(/retrieving/);
|
||||
expect("errorMsg" in res && res.errorMsg).toMatch(/retrieving/);
|
||||
});
|
||||
|
||||
it("returns correct message on parsing wrong class", async () => {
|
||||
@@ -41,7 +41,7 @@ describe("googleScrape", () => {
|
||||
resolveFetchWith(html);
|
||||
|
||||
const res = await googleScrape(source, target, query);
|
||||
expect(res?.errorMsg).toMatch(/parsing/);
|
||||
expect("errorMsg" in res && res.errorMsg).toMatch(/parsing/);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user