Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@reactway/api-builder",
"version": "1.0.0-alpha.4",
"version": "1.0.0-alpha.5",
"description": "An easy api client builder for applications with identity.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
139 changes: 63 additions & 76 deletions src/__tests__/api-builder.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { ApiBuilder } from "../api-builder";
import fetchMock from "fetch-mock";
import { ApiRequestBinaryBody, OAuthResponseDto, HttpMethods, ApiRequest } from "../contracts";
import { ApiRequestBinaryBody, OAuthResponseDto, HttpMethods, ApiRequest, BaseApiRequest, QueryParams } from "../contracts";
import { OAuthIdentity } from "../identities/oauth-identity";
jest.useFakeTimers();

interface ApiTestClient {
get: (requestDto: BaseApiRequest<never>) => Promise<Response>;
post: <TBody = {}>(requestDto: BaseApiRequest<TBody>) => Promise<Response>;
put: <TBody = {}>(requestDto: BaseApiRequest<TBody>) => Promise<Response>;
patch: <TBody = {}>(requestDto: BaseApiRequest<TBody>) => Promise<Response>;
delete: <TBody = {}>(requestDto: BaseApiRequest<TBody>) => Promise<Response>;

getItem: () => Promise<Response>;
}

const API_TEST_HOST = "https://example.com";
const PATH = "/api";
const PATH_GET = "/get";
Expand All @@ -25,6 +35,38 @@ const LOGIN_RESPONSE: OAuthResponseDto = {
expires_in: 28800
};

class ApiClient extends ApiBuilder {
constructor(identity?: OAuthIdentity, queryParams?: QueryParams, queueLimit?: number, usePath?: boolean) {
super({
host: API_TEST_HOST,
path: usePath === false ? undefined : PATH,
identity: identity,
defaultQueryParams: queryParams,
requestQueueLimit: queueLimit
});
}

public async getItem(): Promise<Response> {
const request: ApiRequest = {
requestPath: PATH_GET,
method: HttpMethods.GET
};
return this.get(request);
}
}

// FIXME: Temporary solution.
// tslint:disable-next-line:no-any
const ApiTestClient: { new (): ApiTestClient } = ApiClient as any;
// FIXME: Temporary solution.
// tslint:disable-next-line:no-any
const ApiTestClientIdentity: { new (identity: OAuthIdentity): ApiTestClient } = ApiClient as any;
const ApiTestClientQueryParams: { new (identity: undefined, queryParams: QueryParams): ApiTestClient } = ApiClient as any;
const ApiTestClientQueueLimits: { new (identity: undefined, queryParams: undefined, queueLimit: number): ApiTestClient } = ApiClient as any;
const ApiTestClientNoPath: {
new (identity: undefined, queryParams: undefined, queueLimit: undefined, usePath: boolean): ApiTestClient;
} = ApiClient as any;

// #region Mocked fetch results.
function mockLoginSuccess(): void {
fetchMock.post(
Expand Down Expand Up @@ -123,27 +165,17 @@ afterEach(() => {
});

it("make Get request", async done => {
const apiBuilder = new ApiBuilder({
host: API_TEST_HOST,
path: PATH
});
const apiClient = new ApiTestClient();

mockGetSuccess();
const request: ApiRequest = {
requestPath: PATH_GET,
method: HttpMethods.GET
};
const getExample = await apiBuilder.get(request);

const getExample = await apiClient.getItem();
expect(getExample.status).toEqual(200);
done();
});

it("make Post request", async done => {
const apiBuilder = new ApiBuilder({
host: API_TEST_HOST,
path: PATH
});
const apiBuilder = new ApiTestClient();

mockPostSuccess();
const getExample = await apiBuilder.post({
Expand All @@ -155,10 +187,7 @@ it("make Post request", async done => {
});

it("make Post request with body of type string", async done => {
const apiBuilder = new ApiBuilder({
host: API_TEST_HOST,
path: PATH
});
const apiBuilder = new ApiTestClient();

mockPostSuccess();
const getExample = await apiBuilder.post({
Expand All @@ -171,10 +200,7 @@ it("make Post request with body of type string", async done => {
});

it("make Post request with body of type object", async done => {
const apiBuilder = new ApiBuilder({
host: API_TEST_HOST,
path: PATH
});
const apiBuilder = new ApiTestClient();

mockPostSuccess();
const getExample = await apiBuilder.post<{ name: string; surname: string }>({
Expand All @@ -190,10 +216,7 @@ it("make Post request with body of type object", async done => {
});

it("make Put request", async done => {
const apiBuilder = new ApiBuilder({
host: API_TEST_HOST,
path: PATH
});
const apiBuilder = new ApiTestClient();

mockPutSuccess();
const getExample = await apiBuilder.put<{ name: string }>({
Expand All @@ -208,9 +231,7 @@ it("make Put request", async done => {
});

it("make Get request without config path given", async done => {
const apiBuilder = new ApiBuilder({
host: API_TEST_HOST
});
const apiBuilder = new ApiTestClientNoPath(undefined, undefined, undefined, false);

mockGetPathSuccess();
const getExample = await apiBuilder.get({
Expand All @@ -222,11 +243,7 @@ it("make Get request without config path given", async done => {
});

it("make Get request with queue limits", async done => {
const apiBuilder = new ApiBuilder({
host: API_TEST_HOST,
path: PATH,
requestQueueLimit: 1
});
const apiBuilder = new ApiTestClientQueueLimits(undefined, undefined, 1);

mockGetSuccess();
const getExampleOne = apiBuilder.get({
Expand All @@ -245,10 +262,7 @@ it("make Get request with queue limits", async done => {
});

it("make forced Get request", async done => {
const apiBuilder = new ApiBuilder({
host: API_TEST_HOST,
path: PATH
});
const apiBuilder = new ApiTestClient();

mockGetSuccess();
const getExample = await apiBuilder.get({
Expand All @@ -261,13 +275,10 @@ it("make forced Get request", async done => {
});

it("make Get request with api configuration query params", async done => {
const apiBuilder = new ApiBuilder({
host: API_TEST_HOST,
path: PATH,
defaultQueryParams: {
page: 2
}
});
const queryParams: QueryParams = {
page: 2
};
const apiBuilder = new ApiTestClientQueryParams(undefined, queryParams);

mockGetQueryParamsPathSuccess();
const getExample = await apiBuilder.get({
Expand All @@ -280,10 +291,7 @@ it("make Get request with api configuration query params", async done => {
});

it("make Get request with request query params", async done => {
const apiBuilder = new ApiBuilder({
host: API_TEST_HOST,
path: PATH
});
const apiBuilder = new ApiTestClient();

mockGetQueryParamsPathSuccess();
const getExample = await apiBuilder.get({
Expand All @@ -299,10 +307,7 @@ it("make Get request with request query params", async done => {
});

it("make Post request with Uint8Array body", async done => {
const apiBuilder = new ApiBuilder({
host: API_TEST_HOST,
path: PATH
});
const apiBuilder = new ApiTestClient();

mockPostSuccess();
const getExample = await apiBuilder.post<ApiRequestBinaryBody>({
Expand All @@ -318,10 +323,7 @@ it("make Post request with Uint8Array body", async done => {
});

it("make Delete request", async done => {
const apiBuilder = new ApiBuilder({
host: API_TEST_HOST,
path: PATH
});
const apiBuilder = new ApiTestClient();

mockDeleteSuccess();
const getExample = await apiBuilder.delete<{ id: number }>({
Expand All @@ -336,10 +338,7 @@ it("make Delete request", async done => {
});

it("make Patch request", async done => {
const apiBuilder = new ApiBuilder({
host: API_TEST_HOST,
path: PATH
});
const apiBuilder = new ApiTestClient();

mockPatchSuccess();
const getExample = await apiBuilder.patch<{ id: number }>({
Expand All @@ -363,11 +362,7 @@ it("authenticated request", async done => {
mockLoginSuccess();
await identity.login("", "");

const apiBuilder = new ApiBuilder({
host: API_TEST_HOST,
path: PATH,
identity: identity
});
const apiBuilder = new ApiTestClientIdentity(identity);

mockGetSuccess();
const getExample = await apiBuilder.get({
Expand All @@ -389,11 +384,7 @@ it("authenticated request but failed", async done => {
mockLoginSuccess();
await identity.login("", "");

const apiBuilder = new ApiBuilder({
host: API_TEST_HOST,
path: PATH,
identity: identity
});
const apiBuilder = new ApiTestClientIdentity(identity);

mockGetAuthFailed();
mockLogoutSuccess();
Expand All @@ -419,11 +410,7 @@ it("authenticated request and then logout", async done => {
mockLoginSuccess();
await identity.login("", "");

const apiBuilder = new ApiBuilder({
host: API_TEST_HOST,
path: PATH,
identity: identity
});
const apiBuilder = new ApiTestClientIdentity(identity);

mockGetSuccess();
const getExample = await apiBuilder.get({
Expand Down
10 changes: 5 additions & 5 deletions src/api-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export class ApiBuilder {
this.makeRequest();
}

public async get(requestDto: BaseApiRequest<never>): Promise<Response> {
protected async get(requestDto: BaseApiRequest<never>): Promise<Response> {
return new Promise<Response>((resolve, reject) => {
this.requestsQueue.push({
...requestDto,
Expand All @@ -139,7 +139,7 @@ export class ApiBuilder {
});
}

public async post<TBody = {}>(requestDto: BaseApiRequest<TBody>): Promise<Response> {
protected async post<TBody = {}>(requestDto: BaseApiRequest<TBody>): Promise<Response> {
return new Promise<Response>((resolve, reject) => {
this.requestsQueue.push({
...requestDto,
Expand All @@ -150,7 +150,7 @@ export class ApiBuilder {
});
}

public async put<TBody = {}>(requestDto: BaseApiRequest<TBody>): Promise<Response> {
protected async put<TBody = {}>(requestDto: BaseApiRequest<TBody>): Promise<Response> {
return new Promise<Response>((resolve, reject) => {
this.requestsQueue.push({
...requestDto,
Expand All @@ -161,7 +161,7 @@ export class ApiBuilder {
});
}

public async patch<TBody = {}>(requestDto: BaseApiRequest<TBody>): Promise<Response> {
protected async patch<TBody = {}>(requestDto: BaseApiRequest<TBody>): Promise<Response> {
return new Promise<Response>((resolve, reject) => {
this.requestsQueue.push({
...requestDto,
Expand All @@ -172,7 +172,7 @@ export class ApiBuilder {
});
}

public async delete<TBody = {}>(requestDto: BaseApiRequest<TBody>): Promise<Response> {
protected async delete<TBody = {}>(requestDto: BaseApiRequest<TBody>): Promise<Response> {
return new Promise<Response>((resolve, reject) => {
this.requestsQueue.push({
...requestDto,
Expand Down