Skip to content

Commit

Permalink
refactor(project): api from function to object approach
Browse files Browse the repository at this point in the history
  • Loading branch information
guidiego committed Sep 18, 2020
1 parent 0c702d2 commit 0fc7821
Show file tree
Hide file tree
Showing 15 changed files with 250 additions and 310 deletions.
6 changes: 0 additions & 6 deletions src/api.ts

This file was deleted.

62 changes: 62 additions & 0 deletions src/entity/Api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import Request from './Request';
import TableConnector from './TableConnector';

type Database = {
datname: string;
};

type Schema = {
schema_name: string;
};

type Table = {
schema: string;
name: string;
type: string;
owner: string;
};

type TableDescriptionItem = {
table_schema: string;
table_name: string;
position: number;
column_name: string;
data_type: string;
max_length: number;
is_nullable: string;
is_generated: string;
is_updatable: string;
default_value: string;
};

export class Api extends Request {
private prepareConnectionPath(entries: string[]) {
return '/' + (entries.length === 1 ? entries[0].replace(/\./g, '/') : entries.join('/'));
}

databases(): Promise<Database[]> {
return this.call<Database[]>('get', '/databases');
}

schemas(): Promise<Schema[]> {
return this.call<Schema[]>('get', '/schemas');
}

tables(): Promise<Table[]> {
return this.call<Table[]>('get', '/tables');
}

tablesByDBInSchema(...entries: string[]): Promise<Table[]> {
return this.call<Table[]>('get', `${this.prepareConnectionPath(entries)}`);
}

show(...entries: string[]): Promise<TableDescriptionItem[]> {
return this.call<TableDescriptionItem[]>('get', `/show${this.prepareConnectionPath(entries)}`);
}

tableConnection<T>(...entries: string[]): TableConnector<T> {
return new TableConnector<T>(this.baseUrl, this.prepareConnectionPath(entries));
}
}

export default Api;
15 changes: 15 additions & 0 deletions src/entity/Request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import axios, { Method } from 'axios';

export class Request {
protected baseUrl: string;

constructor(baseUrl: string) {
this.baseUrl = baseUrl;
}

public call<T>(method: Method, path: string): Promise<T> {
return axios[method](this.baseUrl + path).then(({ data }) => data);
}
}

export default Request;
16 changes: 16 additions & 0 deletions src/entity/TableConnector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Request from './Request';

export class TableConnector<T> extends Request {
private dbPath: string;

constructor(baseUrl: string, dbPath: string) {
super(baseUrl);
this.dbPath = dbPath;
}

query(): Promise<T[]> {
return this.call('get', this.dbPath);
}
}

export default TableConnector;
30 changes: 0 additions & 30 deletions src/http.ts

This file was deleted.

6 changes: 4 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export { getOptions, getOption, setOption } from './store';
export * from './api';
import Api from './entity/Api';

export const PRestAPI = Api;
export default Api;
63 changes: 0 additions & 63 deletions src/store.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/types/http.d.ts

This file was deleted.

9 changes: 0 additions & 9 deletions src/types/store.d.ts

This file was deleted.

27 changes: 0 additions & 27 deletions tests/unit/api.spec.ts

This file was deleted.

110 changes: 110 additions & 0 deletions tests/unit/entity/Api.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
jest.mock('../../../src/entity/TableConnector');

import Api from '~/entity/Api';
import TableConnector from '~/entity/TableConnector';

describe('entity/Api', () => {
const baseUrl = 'foo.bar';
const api = new Api(baseUrl);
const fakeResponse = 'foo';
const database = 'prest';
const schema = 'public';
const table = 'foo';
const expectedUrl = `/${database}/${schema}/${table}`;

beforeEach(() => {
api.call = jest.fn();
});

afterEach(() => {
jest.resetAllMocks();
});

it('should call .database() method correctly', async () => {
(api.call as jest.Mock).mockResolvedValue(fakeResponse);

const resp = await api.databases();
expect(resp).toBe(fakeResponse);

expect(api.call).toHaveBeenCalledTimes(1);
expect(api.call).toHaveBeenCalledWith('get', '/databases');
});

it('should call .schemas() method correctly', async () => {
(api.call as jest.Mock).mockResolvedValue(fakeResponse);

const resp = await api.schemas();
expect(resp).toBe(fakeResponse);

expect(api.call).toHaveBeenCalledTimes(1);
expect(api.call).toHaveBeenCalledWith('get', '/schemas');
});

it('should call .tables() method correctly', async () => {
(api.call as jest.Mock).mockResolvedValue(fakeResponse);

const resp = await api.tables();
expect(resp).toBe(fakeResponse);

expect(api.call).toHaveBeenCalledTimes(1);
expect(api.call).toHaveBeenCalledWith('get', '/tables');
});

describe('.tableConnection', () => {
it('should call correctly for string param', () => {
(TableConnector as jest.Mock).mockImplementation(() => ({ fakeResponse }));

expect(api.tableConnection(`${database}.${schema}.${table}`)).toEqual({ fakeResponse });
expect(TableConnector).toHaveBeenCalledWith(baseUrl, expectedUrl);
});

it('should call correctly for splited params', () => {
(TableConnector as jest.Mock).mockImplementation(() => ({ fakeResponse }));

expect(api.tableConnection(database, schema, table)).toEqual({ fakeResponse });
expect(TableConnector).toHaveBeenCalledWith(baseUrl, expectedUrl);
});
});

describe('.tablesByDBInSchema()', () => {
it('should call correctly for string param', async () => {
(api.call as jest.Mock).mockResolvedValue(fakeResponse);

const resp = await api.tablesByDBInSchema(`${database}.${schema}`);

expect(resp).toBe(fakeResponse);
expect(api.call).toHaveBeenCalledWith('get', `/${database}/${schema}`);
});

it('should call correctly for splited params', async () => {
(api.call as jest.Mock).mockResolvedValue(fakeResponse);

const resp = await api.tablesByDBInSchema(database, schema);

expect(resp).toBe(fakeResponse);
expect(api.call).toHaveBeenCalledWith('get', `/${database}/${schema}`);
});
});

describe('.show()', () => {
it('should call correctly for string param', async () => {
(api.call as jest.Mock).mockResolvedValue(fakeResponse);

const resp = await api.show(`${database}.${schema}.${table}`);
expect(resp).toBe(fakeResponse);

expect(api.call).toHaveBeenCalledTimes(1);
expect(api.call).toHaveBeenCalledWith('get', '/show' + expectedUrl);
});

it('should call correctly for splited param', async () => {
(api.call as jest.Mock).mockResolvedValue(fakeResponse);

const resp = await api.show(database, schema, table);
expect(resp).toBe(fakeResponse);

expect(api.call).toHaveBeenCalledTimes(1);
expect(api.call).toHaveBeenCalledWith('get', '/show' + expectedUrl);
});
});
});
19 changes: 19 additions & 0 deletions tests/unit/entity/Request.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
jest.mock('axios');

import Request from '~/entity/Request';
import axios from 'axios';

describe('entity/Request', () => {
it('should execute call and get the response', async () => {
const data = 'foo';
const baseUrl = 'bar';
(axios.get as jest.Mock).mockResolvedValue({ data });

const req = new Request(baseUrl);
const resp = await req.call('get', '');

expect(resp).toBe(data);
expect(axios.get).toHaveBeenCalledTimes(1);
expect(axios.get).toHaveBeenCalledWith(baseUrl);
});
});
Loading

0 comments on commit 0fc7821

Please sign in to comment.