magnetar/fe_calckey/frontend/calckey-js/test/api.ts

223 lines
4.8 KiB
TypeScript

import { APIClient, isAPIError } from "../src/api";
import { enableFetchMocks } from "jest-fetch-mock";
enableFetchMocks();
function getFetchCall(call: any[]) {
const { body, method } = call[1];
if (body != null && typeof body !== "string") {
throw new Error("invalid body");
}
return {
url: call[0],
method: method,
body: JSON.parse(body as any),
};
}
describe("API", () => {
test("success", async () => {
fetchMock.resetMocks();
fetchMock.mockResponse(async (req) => {
const body = await req.json();
if (req.method === "POST" && req.url === "https://calckey.test/api/i") {
if (body.i === "TOKEN") {
return JSON.stringify({ id: "foo" });
} else {
return { status: 400 };
}
} else {
return { status: 404 };
}
});
const cli = new APIClient({
origin: "https://calckey.test",
credential: "TOKEN",
});
const res = await cli.request("i");
expect(res).toEqual({
id: "foo",
});
expect(getFetchCall(fetchMock.mock.calls[0])).toEqual({
url: "https://calckey.test/api/i",
method: "POST",
body: { i: "TOKEN" },
});
});
test("with params", async () => {
fetchMock.resetMocks();
fetchMock.mockResponse(async (req) => {
const body = await req.json();
if (
req.method === "POST" &&
req.url === "https://calckey.test/api/notes/show"
) {
if (body.i === "TOKEN" && body.noteId === "aaaaa") {
return JSON.stringify({ id: "foo" });
} else {
return { status: 400 };
}
} else {
return { status: 404 };
}
});
const cli = new APIClient({
origin: "https://calckey.test",
credential: "TOKEN",
});
const res = await cli.request("notes/show", { noteId: "aaaaa" });
expect(res).toEqual({
id: "foo",
});
expect(getFetchCall(fetchMock.mock.calls[0])).toEqual({
url: "https://calckey.test/api/notes/show",
method: "POST",
body: { i: "TOKEN", noteId: "aaaaa" },
});
});
test("204 No Content で null が返る", async () => {
fetchMock.resetMocks();
fetchMock.mockResponse(async (req) => {
if (
req.method === "POST" &&
req.url === "https://calckey.test/api/reset-password"
) {
return { status: 204 };
} else {
return { status: 404 };
}
});
const cli = new APIClient({
origin: "https://calckey.test",
credential: "TOKEN",
});
const res = await cli.request("reset-password", {
token: "aaa",
password: "aaa",
});
expect(res).toEqual(null);
expect(getFetchCall(fetchMock.mock.calls[0])).toEqual({
url: "https://calckey.test/api/reset-password",
method: "POST",
body: { i: "TOKEN", token: "aaa", password: "aaa" },
});
});
test("インスタンスの credential が指定されていても引数で credential が null ならば null としてリクエストされる", async () => {
fetchMock.resetMocks();
fetchMock.mockResponse(async (req) => {
const body = await req.json();
if (req.method === "POST" && req.url === "https://calckey.test/api/i") {
if (typeof body.i === "string") {
return JSON.stringify({ id: "foo" });
} else {
return {
status: 401,
body: JSON.stringify({
error: {
message: "Credential required.",
code: "CREDENTIAL_REQUIRED",
id: "1384574d-a912-4b81-8601-c7b1c4085df1",
},
}),
};
}
} else {
return { status: 404 };
}
});
try {
const cli = new APIClient({
origin: "https://calckey.test",
credential: "TOKEN",
});
await cli.request("i", {}, null);
} catch (e) {
expect(isAPIError(e)).toEqual(true);
}
});
test("api error", async () => {
fetchMock.resetMocks();
fetchMock.mockResponse(async (req) => {
return {
status: 500,
body: JSON.stringify({
error: {
message:
"Internal error occurred. Please contact us if the error persists.",
code: "INTERNAL_ERROR",
id: "5d37dbcb-891e-41ca-a3d6-e690c97775ac",
kind: "server",
},
}),
};
});
try {
const cli = new APIClient({
origin: "https://calckey.test",
credential: "TOKEN",
});
await cli.request("i");
} catch (e: any) {
expect(isAPIError(e)).toEqual(true);
expect(e.id).toEqual("5d37dbcb-891e-41ca-a3d6-e690c97775ac");
}
});
test("network error", async () => {
fetchMock.resetMocks();
fetchMock.mockAbort();
try {
const cli = new APIClient({
origin: "https://calckey.test",
credential: "TOKEN",
});
await cli.request("i");
} catch (e) {
expect(isAPIError(e)).toEqual(false);
}
});
test("json parse error", async () => {
fetchMock.resetMocks();
fetchMock.mockResponse(async (req) => {
return {
status: 500,
body: "<html>I AM NOT JSON</html>",
};
});
try {
const cli = new APIClient({
origin: "https://calckey.test",
credential: "TOKEN",
});
await cli.request("i");
} catch (e) {
expect(isAPIError(e)).toEqual(false);
}
});
});