223 lines
4.8 KiB
TypeScript
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);
|
||
|
}
|
||
|
});
|
||
|
});
|