diff --git a/src/constants/forms.ts b/src/constants/forms.ts new file mode 100644 index 0000000..c249e56 --- /dev/null +++ b/src/constants/forms.ts @@ -0,0 +1,5 @@ +export default class Forms { + static get CANCELLATION() { + return 1; + } +} diff --git a/src/resources/form.test.ts b/src/resources/form.test.ts new file mode 100644 index 0000000..f716963 --- /dev/null +++ b/src/resources/form.test.ts @@ -0,0 +1,88 @@ +import mockAxios from 'axios'; + +import Forms from '../constants/forms'; +import Form from './form'; + +it('will set cancellation filter and necessary included resources', async () => { + const resource = new Form(mockAxios); + + const expected = expect(resource.cancellations()); + + expected.toHaveProperty('filters', { + type: Forms.CANCELLATION, + }); + expected.toHaveProperty('parameters', { + include: 'questions.options', + }); +}); + +it('will set the page we are on', async () => { + const resource = new Form(mockAxios); + + expect(resource.on(4)).toHaveProperty('page', 4); +}); + +it('will set the limit given', async () => { + const resource = new Form(mockAxios); + + expect(resource.take(5)).toHaveProperty('limit', 5); +}); + +it('will set the sortable filter', async () => { + const resource = new Form(mockAxios); + + expect(resource.sortBy('type,-created')).toHaveProperty('sortable', 'type,-created'); +}); + +it('can string all filterable options together', async () => { + const resource = new Form(mockAxios); + + const expected = expect( + resource + .cancellations() + .sortBy('created') + .take(5) + .on(1), + ); + + expected.toHaveProperty('filters', { + type: Forms.CANCELLATION, + }); + expected.toHaveProperty('parameters', { + include: 'questions.options', + }); + expected.toHaveProperty('sortable', 'created'); + expected.toHaveProperty('limit', 5); + expected.toHaveProperty('page', 1); +}); + +it('can get forms without additional parameters', async () => { + const resource = new Form(mockAxios); + + await resource.get(); + + expect(mockAxios.get).toHaveBeenCalledTimes(1); + expect(mockAxios.get).toHaveBeenCalledWith('forms', { params: {} }); +}); + +it('can get forms with additional parameters', async () => { + const resource = new Form(mockAxios); + + await resource + .cancellations() + .sortBy('created') + .take(5) + .on(1) + .get(); + + expect(mockAxios.get).toHaveBeenCalledTimes(1); + expect(mockAxios.get).toHaveBeenCalledWith('forms', { + params: { + 'filter[type]': Forms.CANCELLATION, + include: 'questions.options', + limit: 5, + page: 1, + sort: 'created', + }, + }); +}); diff --git a/src/resources/form.ts b/src/resources/form.ts index ad57f62..7a4dc51 100644 --- a/src/resources/form.ts +++ b/src/resources/form.ts @@ -1,23 +1,105 @@ import { AxiosInstance } from 'axios'; -import { Resource } from '../index'; +import Forms from '../constants/forms'; +import { combine } from '../helpers/filters'; +import { Filterable, Pageable } from '../index'; -export interface FormResource extends Resource { +export interface FormFilter { + type?: number; +} + +export interface FormFilterable extends Filterable { + include?: string; +} + +export interface FormUrlParameters { + include?: string; +} + +interface FormParameters { + type?: number; +} + +export interface FormResource extends Pageable { cancellations(): this; } export default class Form implements FormResource { protected client: AxiosInstance; + protected filters: FormFilter; + protected page: number | null; + protected parameters: FormUrlParameters; + protected sortable: string | null; + protected limit: number | null; constructor(client: AxiosInstance) { this.client = client; + this.filters = {}; + this.page = null; + this.parameters = {}; + this.sortable = null; + this.limit = null; } public cancellations(): this { + this.filters.type = Forms.CANCELLATION; + this.parameters.include = 'questions.options'; + return this; } - public get(): Promise { - return new Promise((resolve) => resolve()); + public async get(): Promise { + const parameters = this.params(); + let params: FormFilterable = {}; + + if (Object.keys(parameters).length) { + params = combine(params, parameters); + } + + if (this.parameters.include) { + params.include = this.parameters.include; + } + + if (this.limit) { + params.limit = this.limit; + } + + if (this.page) { + params.page = this.page; + } + + if (this.sortable) { + params.sort = this.sortable; + } + + return await this.client.get('forms', { params }); + } + + public on(page: number): this { + this.page = page; + + return this; + } + + public sortBy(sortable: string): this { + this.sortable = sortable; + + return this; + } + + public take(limit: number): this { + this.limit = limit; + + return this; + } + + protected params(): FormParameters { + const params: FormParameters = {}; + + if (typeof this.filters.type !== 'undefined') { + params.type = this.filters.type; + } + + return params; } }