Skip to content

Commit

Permalink
fix: improve unit-tests for JsonService
Browse files Browse the repository at this point in the history
  • Loading branch information
pamapa committed Nov 21, 2021
1 parent 956e961 commit 2decbab
Showing 1 changed file with 279 additions and 39 deletions.
318 changes: 279 additions & 39 deletions test/unit/JsonService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,41 +19,33 @@ describe("JsonService", () => {
});

describe("getJson", () => {

it("should return a promise", async () => {
it("should reject promise when no url is passed", async () => {
// act
const p = subject.getJson("http://test");

// assert
expect(p).toBeInstanceOf(Promise);
// eslint-disable-next-line no-empty
try { await p; } catch {}
await expect(subject.getJson(""))
// assert
.rejects.toThrow("url");
});

it("should make GET request to url", async () => {
// act
const p = subject.getJson("http://test");
await expect(subject.getJson("http://test")).rejects.toThrow();

// assert
expect(fetchMock).toBeCalledWith("http://test", {
headers: {},
method: "GET"
});
// eslint-disable-next-line no-empty
try { await p; } catch {}
});

it("should set token as authorization header", async () => {
// act
const p = subject.getJson("http://test", "token");
await expect(subject.getJson("http://test", "token")).rejects.toThrow();

// assert
expect(fetchMock).toBeCalledWith("http://test", {
headers: { Authorization: "Bearer token" },
method: "GET"
});
// eslint-disable-next-line no-empty
try { await p; } catch {}
});

it("should fulfill promise when http response is 200", async () => {
Expand All @@ -74,6 +66,23 @@ describe("JsonService", () => {
expect(result).toEqual(json);
});

it("should reject promise when http response is 200 and json is not able to parse", async () => {
// arrange
const error = new SyntaxError("Unexpected token a in JSON");
fetchMock.mockResolvedValue({
status: 200,
headers: new Headers({
"Content-Type": "application/json"
}),
json: () => Promise.reject(error)
});

// act
await expect(subject.getJson("http://test"))
// assert
.rejects.toThrow(error);
});

it("should reject promise when http response is not 200", async () => {
// arrange
fetchMock.mockResolvedValue({
Expand All @@ -82,30 +91,19 @@ describe("JsonService", () => {
});

// act
try {
await subject.getJson("http://test");
fail("should not come here");
}
catch (err) {
expect(err).toBeInstanceOf(Error);
expect((err as Error).message).toContain("500");
expect((err as Error).message).toContain("server error");
}
await expect(subject.getJson("http://test"))
// assert
.rejects.toThrow(/server error.+500/);
});

it("should reject promise when http response is error", async () => {
// arrange
fetchMock.mockRejectedValue({});

// act
try {
await subject.getJson("http://test");
fail("should not come here");
}
catch (err) {
expect(err).toBeInstanceOf(Error);
expect((err as Error).message).toEqual("Network Error");
}
await expect(subject.getJson("http://test"))
// assert
.rejects.toThrow("Network Error");
});

it("should reject promise when http response content type is not json", async () => {
Expand All @@ -120,14 +118,9 @@ describe("JsonService", () => {
});

// act
try {
await subject.getJson("http://test");
fail("should not come here");
}
catch (err) {
expect(err).toBeInstanceOf(Error);
expect((err as Error).message).toContain("Invalid response Content-Type: text/html");
}
await expect(subject.getJson("http://test"))
// assert
.rejects.toThrow("Invalid response Content-Type: text/html");
});

it("should accept custom content type in response", async () => {
Expand All @@ -148,5 +141,252 @@ describe("JsonService", () => {
// assert
expect(result).toEqual(json);
});

it("should work with custom jwtHandler", async () => {
// arrange
const jwtHandler = jest.fn();
subject = new JsonService([], jwtHandler);
const text = "text";
fetchMock.mockResolvedValue({
status: 200,
headers: new Headers({
"Content-Type": "application/jwt"
}),
text: () => Promise.resolve(text)
});

// act
await subject.getJson("http://test");

// assert
expect(jwtHandler).toBeCalledWith(text);
});
});

describe("postForm", () => {
it("should reject promise when no url is passed", async () => {
// act
await expect(subject.postForm("", { "a": "b" }))
// assert
.rejects.toThrow("url");
});

it("should make POST request to url", async () => {
// act
await expect(subject.postForm("http://test", { "a": "b" })).rejects.toThrow();

// assert
expect(fetchMock).toBeCalledWith(
"http://test",
expect.objectContaining({
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
method: "POST",
body: new URLSearchParams()
})
);
});

it("should set basicAuth as authorization header", async () => {
// act
await expect(subject.postForm("http://test", { "payload": "dummy" }, "basicAuth")).rejects.toThrow();

// assert
expect(fetchMock).toBeCalledWith(
"http://test",
expect.objectContaining({
headers: {
Authorization: "Basic " + btoa("basicAuth"),
"Content-Type": "application/x-www-form-urlencoded",
},
method: "POST",
body: new URLSearchParams()
})
);
});

it("should set payload as body", async () => {
// act
await expect(subject.postForm("http://test", { "payload": "dummy" })).rejects.toThrow();

// assert
const body = new URLSearchParams();
body.set("payload", "dummy");

expect(fetchMock).toBeCalledWith(
"http://test",
expect.objectContaining({
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
method: "POST",
body
})
);
});

it("should fulfill promise when http response is 200", async () => {
// arrange
const json = { foo: 1, bar: "test" };
fetchMock.mockResolvedValue({
status: 200,
headers: new Headers({
"Content-Type": "application/json"
}),
json: () => Promise.resolve(json)
});

// act
const result = await subject.postForm("http://test", { "payload": "dummy" });

// assert
expect(result).toEqual(json);
});

it("should reject promise when http response is error", async () => {
// arrange
fetchMock.mockRejectedValue({});

// act
await expect(subject.postForm("http://test", { "payload": "dummy" }))
// assert
.rejects.toThrow("Network Error");
});

it("should reject promise when http response is 200 and json is not able to parse", async () => {
// arrange
const error = new SyntaxError("Unexpected token a in JSON");
fetchMock.mockResolvedValue({
status: 200,
headers: new Headers({
"Content-Type": "application/json"
}),
json: () => Promise.reject(error)
});

// act
await expect(subject.postForm("http://test", { "payload": "dummy" }))
// assert
.rejects.toThrow(error);
});

it("should reject promise when http response is 200 and content type is not json", async () => {
// arrange
const json = { foo: 1, bar: "test" };
fetchMock.mockResolvedValue({
status: 200,
headers: new Headers({
"Content-Type": "text/html"
}),
json: () => Promise.resolve(json)
});

// act
await expect(subject.postForm("http://test", { "payload": "dummy" }))
// assert
.rejects.toThrow("Invalid response Content-Type: text/html");
});

it("should reject promise when http response is 400 and json has error field", async () => {
// arrange
const json = { error: "error" };
fetchMock.mockResolvedValue({
status: 400,
headers: new Headers({
"Content-Type": "application/json"
}),
json: () => Promise.resolve(json)
});

// act
await expect(subject.postForm("http://test", { "payload": "dummy" }))
// assert
.rejects.toThrow(json.error);
});

it("should fulfill promise when http response is 400 and json has no error field", async () => {
// arrange
const json = { foo: 1, bar: "test" };
fetchMock.mockResolvedValue({
status: 400,
headers: new Headers({
"Content-Type": "application/json"
}),
json: () => Promise.resolve(json)
});

// act
const result = await subject.postForm("http://test", { "payload": "dummy" });

// assert
expect(result).toEqual(json);
});

it("should reject promise when http response is 400 and json is not able to parse", async () => {
// arrange
const error = new SyntaxError("Unexpected token a in JSON");
fetchMock.mockResolvedValue({
status: 400,
headers: new Headers({
"Content-Type": "application/json"
}),
json: () => Promise.reject(error)
});

// act
await expect(subject.postForm("http://test", { "payload": "dummy" }))
// assert
.rejects.toThrow(error);
});

it("should reject promise when http response is 400 and content type is not json", async () => {
// arrange
const json = { foo: 1, bar: "test" };
fetchMock.mockResolvedValue({
status: 400,
headers: new Headers({
"Content-Type": "text/html"
}),
json: () => Promise.resolve(json)
});

// act
await expect(subject.postForm("http://test", { "payload": "dummy" }))
// assert
.rejects.toThrow("Invalid response Content-Type: text/html");
});

it("should reject promise when http response is not 200", async () => {
// arrange
fetchMock.mockResolvedValue({
status: 500,
statusText: "server error",
});

// act
await expect(subject.postForm("http://test", { "payload": "dummy" }))
// assert
.rejects.toThrow(/server error.+500/);
});

it("should accept custom content type in response", async () => {
// arrange
subject = new JsonService(["foo/bar"]);
const json = { foo: 1, bar: "test" };
fetchMock.mockResolvedValue({
status: 200,
headers: new Headers({
"Content-Type": "foo/bar"
}),
json: () => Promise.resolve(json)
});

// act
const result = await subject.postForm("http://test", { "payload": "dummy" });

// assert
expect(result).toEqual(json);
});
});
});

0 comments on commit 2decbab

Please sign in to comment.