From ed68b5f9d990345f1c4dcabf665ec60e6c9e84fc Mon Sep 17 00:00:00 2001 From: StevanFreeborn Date: Fri, 3 Feb 2023 22:32:57 -0600 Subject: [PATCH] fix: properly implement saveFile method and write test --- .nycrc | 8 +- src/models/ApiResponse.ts | 26 +-- src/models/OnspringClient.ts | 18 +- src/models/SaveFileRequest.ts | 11 +- tests/ApiResponse.spec.ts | 86 ++++++--- tests/CreatedWithIdResponse.spec.ts | 28 +++ tests/OnspringClient.spec.ts | 290 ++++++++++++++++++++++++++++ tests/SaveFileRequest.spec.ts | 257 ++++++++++++++++++++++++ tsconfig.json | 3 +- 9 files changed, 669 insertions(+), 58 deletions(-) create mode 100644 tests/CreatedWithIdResponse.spec.ts create mode 100644 tests/SaveFileRequest.spec.ts diff --git a/.nycrc b/.nycrc index 8db21fb..f7ac663 100644 --- a/.nycrc +++ b/.nycrc @@ -1,10 +1,10 @@ { "extends": "@istanbuljs/nyc-config-typescript", "check-coverage": true, - "branches": 80, - "lines": 80, - "functions": 80, - "statements": 80, + "branches": 100, + "lines": 100, + "functions": 100, + "statements": 100, "all": true, "include": ["src/**/*.ts"], "exclude": ["src/index.ts", "**/*.spec.ts"], diff --git a/src/models/ApiResponse.ts b/src/models/ApiResponse.ts index 655f3c1..ad5d75a 100644 --- a/src/models/ApiResponse.ts +++ b/src/models/ApiResponse.ts @@ -44,10 +44,10 @@ export class ApiResponse { } /** - * @method AsGetPagedAppsResponseType - Converts the ApiResponse to an ApiResponse. + * @method asGetPagedAppsResponseType - Converts the ApiResponse to an ApiResponse. * @returns {ApiResponse} - An ApiResponse. */ - public AsGetPagedAppsResponseType(): ApiResponse { + public asGetPagedAppsResponseType(): ApiResponse { const apiResponse = this as ApiResponse; const apps = apiResponse.data.items.map((item: any) => { @@ -70,10 +70,10 @@ export class ApiResponse { } /** - * @method AsAppType - Converts the ApiResponse to an ApiResponse. + * @method asAppType - Converts the ApiResponse to an ApiResponse. * @returns {ApiResponse} - An ApiResponse. */ - public AsAppType(): ApiResponse { + public asAppType(): ApiResponse { const apiResponse = this as ApiResponse; const app = new App( @@ -90,10 +90,10 @@ export class ApiResponse { } /** - * @method AsAppCollectionType - Converts the ApiResponse to an ApiResponse>. + * @method asAppCollectionType - Converts the ApiResponse to an ApiResponse>. * @returns {ApiResponse>} - An ApiResponse>. */ - public AsAppCollectionType(): ApiResponse> { + public asAppCollectionType(): ApiResponse> { const apiResponse = this as ApiResponse; const apps = apiResponse.data.items.map((item: any) => { @@ -113,10 +113,10 @@ export class ApiResponse { } /** - * @method AsFieldType - Converts the ApiResponse to an ApiResponse. + * @method asFieldType - Converts the ApiResponse to an ApiResponse. * @returns {ApiResponse} - An ApiResponse. */ - public AsFieldType(): ApiResponse { + public asFieldType(): ApiResponse { const apiResponse = this as ApiResponse; const field = new Field( @@ -137,10 +137,10 @@ export class ApiResponse { } /** - * @method AsFieldCollectionType - Converts the ApiResponse to an ApiResponse>. + * @method asFieldCollectionType - Converts the ApiResponse to an ApiResponse>. * @returns {ApiResponse>} - An ApiResponse>. */ - public AsFieldCollectionType(): ApiResponse> { + public asFieldCollectionType(): ApiResponse> { const apiResponse = this as ApiResponse; const fields = apiResponse.data.items.map((item: any) => { @@ -168,10 +168,10 @@ export class ApiResponse { } /** - * @method AsGetPagedFieldsResponseType - Converts the ApiResponse to an ApiResponse. + * @method asGetPagedFieldsResponseType - Converts the ApiResponse to an ApiResponse. * @returns {ApiResponse} - An ApiResponse. */ - public AsGetPagedFieldsResponseType(): ApiResponse { + public asGetPagedFieldsResponseType(): ApiResponse { const apiResponse = this as ApiResponse; const fields = apiResponse.data.items.map((item: any) => { @@ -201,7 +201,7 @@ export class ApiResponse { ); } - public AsCreatedWithIdResponseType(): ApiResponse { + public asCreatedWithIdResponseType(): ApiResponse { const apiResponse = this as ApiResponse; const createdWithIdResponse = new CreatedWithIdResponse( diff --git a/src/models/OnspringClient.ts b/src/models/OnspringClient.ts index 923d25a..85deb94 100644 --- a/src/models/OnspringClient.ts +++ b/src/models/OnspringClient.ts @@ -75,7 +75,7 @@ export class OnspringClient { return apiResponse; } - return apiResponse.AsGetPagedAppsResponseType(); + return apiResponse.asGetPagedAppsResponseType(); } /** @@ -92,7 +92,7 @@ export class OnspringClient { return apiResponse; } - return apiResponse.AsAppType(); + return apiResponse.asAppType(); } /** @@ -110,7 +110,7 @@ export class OnspringClient { return apiResponse; } - return apiResponse.AsAppCollectionType(); + return apiResponse.asAppCollectionType(); } /** @@ -126,7 +126,7 @@ export class OnspringClient { return apiResponse; } - return apiResponse.AsFieldType(); + return apiResponse.asFieldType(); } /** @@ -145,7 +145,7 @@ export class OnspringClient { return apiResponse; } - return apiResponse.AsFieldCollectionType(); + return apiResponse.asFieldCollectionType(); } /** @@ -168,7 +168,7 @@ export class OnspringClient { return apiResponse; } - return apiResponse.AsGetPagedFieldsResponseType(); + return apiResponse.asGetPagedFieldsResponseType(); } /** @@ -180,16 +180,16 @@ export class OnspringClient { request: SaveFileRequest ): Promise> { const endpoint = EndpointFactory.getSaveFileEndpoint(); - const formData = request.AsFormData(); + const formData = request.asFormData(); const apiResponse = await this.post(endpoint, formData, { - headers: formData.getHeaders(), + headers: { 'Content-Type': 'multipart/form-data' }, }); if (apiResponse.isSuccessful === false) { return apiResponse; } - return apiResponse.AsCreatedWithIdResponseType(); + return apiResponse.asCreatedWithIdResponseType(); } /** diff --git a/src/models/SaveFileRequest.ts b/src/models/SaveFileRequest.ts index f1978d4..4bbe9c8 100644 --- a/src/models/SaveFileRequest.ts +++ b/src/models/SaveFileRequest.ts @@ -1,3 +1,4 @@ +import { type Readable } from 'stream'; import FormData = require('form-data'); /** @@ -35,9 +36,9 @@ export class SaveFileRequest { public contentType: string; /** - * @property {ReadableStream} fileStream - The file stream. + * @property {Readable} fileStream - The file stream. */ - public fileStream: ReadableStream; + public fileStream: Readable; /** * @constructor - Creates a new SaveFileRequest. @@ -47,7 +48,7 @@ export class SaveFileRequest { * @param {Date} modifiedDate - The modified date for the file. * @param {string} fileName - The name of the file. * @param {string} contentType - The content type of the file. - * @param {ReadableStream} fileStream - The file stream. + * @param {Readable} fileStream - The file stream. * @returns {SaveFileRequest} - A new SaveFileRequest. */ constructor( @@ -57,7 +58,7 @@ export class SaveFileRequest { modifiedDate: Date, fileName: string, contentType: string, - fileStream: ReadableStream + fileStream: Readable ) { this.recordId = recordId; this.fieldId = fieldId; @@ -72,7 +73,7 @@ export class SaveFileRequest { * @method AsFormData - Converts the SaveFileRequest to a FormData object. * @returns {FormData} - The SaveFileRequest as a FormData object. */ - public AsFormData(): FormData { + public asFormData(): FormData { const formData = new FormData(); formData.append('recordId', this.recordId.toString()); formData.append('fieldId', this.fieldId.toString()); diff --git a/tests/ApiResponse.spec.ts b/tests/ApiResponse.spec.ts index 476b77b..af495a7 100644 --- a/tests/ApiResponse.spec.ts +++ b/tests/ApiResponse.spec.ts @@ -7,6 +7,7 @@ import { Field } from '../src/models/Field'; import { FieldStatus } from '../src/enums/FieldStatus'; import { FieldType } from '../src/enums/FieldType'; import { GetPagedFieldsResponse } from '../src/models/GetPagedFieldsResponse'; +import { CreatedWithIdResponse } from '../src/models/CreatedWithIdResponse'; describe('ApiResponse', function () { it('should be defined', function () { @@ -77,14 +78,14 @@ describe('ApiResponse', function () { ); }); - describe('AsGetPagedAppsResponseType', function () { + describe('asGetPagedAppsResponseType', function () { it('should be defined', function () { - expect(ApiResponse.prototype.AsGetPagedAppsResponseType).to.not.be + expect(ApiResponse.prototype.asGetPagedAppsResponseType).to.not.be .undefined; }); it('should have no parameters', function () { - expect(ApiResponse.prototype.AsGetPagedAppsResponseType).to.have.lengthOf( + expect(ApiResponse.prototype.asGetPagedAppsResponseType).to.have.lengthOf( 0 ); }); @@ -110,7 +111,7 @@ describe('ApiResponse', function () { }; const apiResponse = new ApiResponse(200, 'OK', mockResponseData); - const appsPagedResponse = apiResponse.AsGetPagedAppsResponseType(); + const appsPagedResponse = apiResponse.asGetPagedAppsResponseType(); expect(appsPagedResponse).to.be.instanceOf(ApiResponse); expect(appsPagedResponse.data).to.be.instanceOf(GetPagedAppsResponse); @@ -137,7 +138,7 @@ describe('ApiResponse', function () { }; const apiResponse = new ApiResponse(200, 'OK', mockResponseData); - const appsPagedResponse = apiResponse.AsGetPagedAppsResponseType(); + const appsPagedResponse = apiResponse.asGetPagedAppsResponseType(); expect(appsPagedResponse).to.be.instanceOf(ApiResponse); expect(appsPagedResponse.data).to.be.instanceOf(GetPagedAppsResponse); @@ -153,13 +154,13 @@ describe('ApiResponse', function () { }); }); - describe('AsAppType', function () { + describe('asAppType', function () { it('should be defined', function () { - expect(ApiResponse.prototype.AsAppType).to.not.be.undefined; + expect(ApiResponse.prototype.asAppType).to.not.be.undefined; }); it('should have no parameters', function () { - expect(ApiResponse.prototype.AsAppType).to.have.lengthOf(0); + expect(ApiResponse.prototype.asAppType).to.have.lengthOf(0); }); it('should return an ApiResponse when data contain an app', function () { @@ -170,7 +171,7 @@ describe('ApiResponse', function () { }; const apiResponse = new ApiResponse(200, 'OK', mockResponseData); - const appResponse = apiResponse.AsAppType(); + const appResponse = apiResponse.asAppType(); expect(appResponse).to.be.instanceOf(ApiResponse); expect(appResponse.data).to.be.instanceOf(App); @@ -185,13 +186,13 @@ describe('ApiResponse', function () { }); }); - describe('AsAppCollectionType', function () { + describe('asAppCollectionType', function () { it('should be defined', function () { - expect(ApiResponse.prototype.AsAppCollectionType).to.not.be.undefined; + expect(ApiResponse.prototype.asAppCollectionType).to.not.be.undefined; }); it('should have no parameters', function () { - expect(ApiResponse.prototype.AsAppCollectionType).to.have.lengthOf(0); + expect(ApiResponse.prototype.asAppCollectionType).to.have.lengthOf(0); }); it('should return an ApiResponse> when data contains app items', function () { @@ -212,7 +213,7 @@ describe('ApiResponse', function () { }; const apiResponse = new ApiResponse(200, 'OK', mockResponseData); - const appCollectionResponse = apiResponse.AsAppCollectionType(); + const appCollectionResponse = apiResponse.asAppCollectionType(); expect(appCollectionResponse).to.be.instanceOf( ApiResponse> @@ -237,13 +238,13 @@ describe('ApiResponse', function () { }); }); - describe('AsFieldType', function () { + describe('asFieldType', function () { it('should be defined', function () { - expect(ApiResponse.prototype.AsFieldType).to.not.be.undefined; + expect(ApiResponse.prototype.asFieldType).to.not.be.undefined; }); it('should have no parameters', function () { - expect(ApiResponse.prototype.AsFieldType).to.have.lengthOf(0); + expect(ApiResponse.prototype.asFieldType).to.have.lengthOf(0); }); it('should return an ApiResponse when data contain a field', function () { @@ -258,7 +259,7 @@ describe('ApiResponse', function () { }; const apiResponse = new ApiResponse(200, 'OK', mockResponseData); - const fieldResponse = apiResponse.AsFieldType(); + const fieldResponse = apiResponse.asFieldType(); expect(fieldResponse).to.be.instanceOf(ApiResponse); expect(fieldResponse.data).to.be.instanceOf(Field); @@ -275,13 +276,13 @@ describe('ApiResponse', function () { }); }); - describe('AsFieldCollectionType', function () { + describe('asFieldCollectionType', function () { it('should be defined', function () { - expect(ApiResponse.prototype.AsFieldCollectionType).to.not.be.undefined; + expect(ApiResponse.prototype.asFieldCollectionType).to.not.be.undefined; }); it('should have no parameters', function () { - expect(ApiResponse.prototype.AsFieldCollectionType).to.have.lengthOf(0); + expect(ApiResponse.prototype.asFieldCollectionType).to.have.lengthOf(0); }); it('should return an ApiResponse> when data contains field items', function () { @@ -310,7 +311,7 @@ describe('ApiResponse', function () { }; const apiResponse = new ApiResponse(200, 'OK', mockResponseData); - const fieldCollectionResponse = apiResponse.AsFieldCollectionType(); + const fieldCollectionResponse = apiResponse.asFieldCollectionType(); expect(fieldCollectionResponse).to.be.instanceOf( ApiResponse> @@ -336,15 +337,15 @@ describe('ApiResponse', function () { }); }); - describe('AsGetPagedFieldsResponseType', function () { + describe('asGetPagedFieldsResponseType', function () { it('should be defined', function () { - expect(ApiResponse.prototype.AsGetPagedFieldsResponseType).to.not.be + expect(ApiResponse.prototype.asGetPagedFieldsResponseType).to.not.be .undefined; }); it('should have no parameters', function () { expect( - ApiResponse.prototype.AsGetPagedFieldsResponseType + ApiResponse.prototype.asGetPagedFieldsResponseType ).to.have.lengthOf(0); }); @@ -377,7 +378,7 @@ describe('ApiResponse', function () { }; const apiResponse = new ApiResponse(200, 'OK', mockResponseData); - const getPagedFieldsResponse = apiResponse.AsGetPagedFieldsResponseType(); + const getPagedFieldsResponse = apiResponse.asGetPagedFieldsResponseType(); expect(getPagedFieldsResponse).to.be.instanceOf( ApiResponse @@ -417,7 +418,7 @@ describe('ApiResponse', function () { }; const apiResponse = new ApiResponse(200, 'OK', mockResponseData); - const getPagedFieldsResponse = apiResponse.AsGetPagedFieldsResponseType(); + const getPagedFieldsResponse = apiResponse.asGetPagedFieldsResponseType(); expect(getPagedFieldsResponse).to.be.instanceOf( ApiResponse @@ -437,4 +438,37 @@ describe('ApiResponse', function () { } }); }); + + describe('asCreatedWithIdResponseType', function () { + it('should be defined', function () { + expect(ApiResponse.prototype.asCreatedWithIdResponseType).to.not.be + .undefined; + }); + + it('should have no parameters', function () { + expect( + ApiResponse.prototype.asCreatedWithIdResponseType + ).to.have.lengthOf(0); + }); + + it('should return an ApiResponse when data contains an id', function () { + const mockResponseData = { + id: 1, + }; + + const apiResponse = new ApiResponse(200, 'OK', mockResponseData); + const createdWithIdResponse = apiResponse.asCreatedWithIdResponseType(); + + expect(createdWithIdResponse).to.be.instanceOf( + ApiResponse + ); + expect(createdWithIdResponse.data).to.be.instanceOf( + CreatedWithIdResponse + ); + expect(createdWithIdResponse.data).to.not.be.null; + if (createdWithIdResponse.data != null) { + expect(createdWithIdResponse.data.id).to.equal(1); + } + }); + }); }); diff --git a/tests/CreatedWithIdResponse.spec.ts b/tests/CreatedWithIdResponse.spec.ts new file mode 100644 index 0000000..cbc21eb --- /dev/null +++ b/tests/CreatedWithIdResponse.spec.ts @@ -0,0 +1,28 @@ +import { expect } from 'chai'; +import { CreatedWithIdResponse } from '../src/models/CreatedWithIdResponse'; + +describe('CreatedWithIdResponse', function () { + it('should be defined', function () { + expect(CreatedWithIdResponse).to.not.be.undefined; + }); + + it('should have a constructor', function () { + expect(CreatedWithIdResponse).to.have.property('constructor'); + }); + + it('should have 1 parameters', function () { + expect(CreatedWithIdResponse).to.have.lengthOf(1); + }); + + it('should create a new instance of the CreatedWithIdResponse class', function () { + expect(() => new CreatedWithIdResponse(1)).to.not.throw(); + }); + + it('should have a property named id', function () { + expect(new CreatedWithIdResponse(1)).to.have.property('id'); + }); + + it('should set the id property to the value passed to the constructor', function () { + expect(new CreatedWithIdResponse(1).id).to.equal(1); + }); +}); diff --git a/tests/OnspringClient.spec.ts b/tests/OnspringClient.spec.ts index 44e68ac..73180c3 100644 --- a/tests/OnspringClient.spec.ts +++ b/tests/OnspringClient.spec.ts @@ -13,6 +13,9 @@ import { Field } from '../src/models/Field'; import { FieldStatus } from '../src/enums/FieldStatus'; import { FieldType } from '../src/enums/FieldType'; import { GetPagedFieldsResponse } from '../src/models/GetPagedFieldsResponse'; +import { SaveFileRequest } from '../src/models/SaveFileRequest'; +import { Readable } from 'stream'; +import { CreatedWithIdResponse } from '../src/models/CreatedWithIdResponse'; describe('OnspringClient', function () { const baseUrl = 'https://api.onspring.dev'; @@ -1205,4 +1208,291 @@ describe('OnspringClient', function () { expect(result.data).to.be.null; }); }); + + describe('saveFile', function () { + it('should be a function', function () { + expect(new OnspringClient(baseUrl, apiKey).saveFile).to.be.a('function'); + }); + + it('should return a promise', function () { + const client = new OnspringClient(baseUrl, apiKey); + const saveFileRequest = new SaveFileRequest( + 1, + 1, + 'notes', + new Date(), + 'file name', + 'content type', + new Readable() + ); + expect(client.saveFile(saveFileRequest)).to.be.instanceOf(Promise); + }); + + it('should return a promise that resolves to an api response of with a created id when the request is successful', async function () { + const client = new OnspringClient(baseUrl, apiKey); + + const mockAxiosClient = axios.create({ + baseURL: baseUrl, + headers: { + 'x-apikey': apiKey, + 'x-api-version': '2', + }, + }); + + sinon.stub(mockAxiosClient, 'post').returns( + Promise.resolve({ + status: 201, + statusText: 'Created', + data: { + id: 1, + }, + headers: {}, + config: {} as InternalAxiosRequestConfig, + } as AxiosResponse) + ); + + sinon.stub(client, '_client' as any).value(mockAxiosClient); + + const saveFileRequest = new SaveFileRequest( + 1, + 1, + 'notes', + new Date(), + 'file name', + 'content type', + new Readable() + ); + + const result = await client.saveFile(saveFileRequest); + + expect(result).to.be.instanceOf(ApiResponse); + expect(result).to.have.property('statusCode', 201); + expect(result).to.have.property('isSuccessful', true); + expect(result).to.have.property('message', ''); + expect(result).to.have.property('data'); + expect(result.data).to.be.instanceOf(CreatedWithIdResponse); + expect(result.data).to.have.property('id', 1); + }); + + it('should return a promise that resolves to an api response when request receives a 400 response', async function () { + const client = new OnspringClient(baseUrl, apiKey); + + const mockAxiosClient = axios.create({ + baseURL: baseUrl, + headers: { + 'x-apikey': apiKey, + 'x-api-version': '2', + }, + }); + + sinon.stub(mockAxiosClient, 'post').returns( + Promise.resolve({ + status: 400, + statusText: 'Bad Request', + data: { + File: ['The File field is required.'], + }, + headers: {}, + config: {} as InternalAxiosRequestConfig, + } as AxiosResponse) + ); + + sinon.stub(client, '_client' as any).value(mockAxiosClient); + + const saveFileRequest = new SaveFileRequest( + 1, + 1, + 'notes', + new Date(), + 'file name', + 'content type', + new Readable() + ); + + const result = await client.saveFile(saveFileRequest); + + expect(result).to.be.instanceOf(ApiResponse); + expect(result).to.have.property('statusCode', 400); + expect(result).to.have.property('isSuccessful', false); + expect(result).to.have.property( + 'message', + '{"File":["The File field is required."]}' + ); + expect(result).to.have.property('data'); + expect(result.data).to.be.null; + }); + + it('should return a promise that resolves to an api response when request receives a 401 response', async function () { + const client = new OnspringClient(baseUrl, apiKey); + + const mockAxiosClient = axios.create({ + baseURL: baseUrl, + headers: { + 'x-apikey': apiKey, + 'x-api-version': '2', + }, + }); + + sinon.stub(mockAxiosClient, 'post').returns( + Promise.resolve({ + status: 401, + statusText: 'Unauthorized', + headers: {}, + config: {} as InternalAxiosRequestConfig, + } as AxiosResponse) + ); + + sinon.stub(client, '_client' as any).value(mockAxiosClient); + + const saveFileRequest = new SaveFileRequest( + 1, + 1, + 'notes', + new Date(), + 'file name', + 'content type', + new Readable() + ); + + const result = await client.saveFile(saveFileRequest); + + expect(result).to.be.instanceOf(ApiResponse); + expect(result).to.have.property('statusCode', 401); + expect(result).to.have.property('isSuccessful', false); + expect(result.message).to.be.undefined; + expect(result.data).to.be.null; + }); + + it('should return a promise that resolves to an api response when request receives a 403 response', async function () { + const client = new OnspringClient(baseUrl, apiKey); + + const mockAxiosClient = axios.create({ + baseURL: baseUrl, + headers: { + 'x-apikey': apiKey, + 'x-api-version': '2', + }, + }); + + sinon.stub(mockAxiosClient, 'post').returns( + Promise.resolve({ + status: 403, + statusText: 'Forbidden', + data: { + message: + 'The user does not have permission to access this resource.', + }, + headers: {}, + config: {} as InternalAxiosRequestConfig, + } as AxiosResponse) + ); + + sinon.stub(client, '_client' as any).value(mockAxiosClient); + + const saveFileRequest = new SaveFileRequest( + 1, + 1, + 'notes', + new Date(), + 'file name', + 'content type', + new Readable() + ); + + const result = await client.saveFile(saveFileRequest); + + expect(result).to.be.instanceOf(ApiResponse); + expect(result).to.have.property('statusCode', 403); + expect(result).to.have.property('isSuccessful', false); + expect(result.message).to.equal( + 'The user does not have permission to access this resource.' + ); + expect(result.data).to.be.null; + }); + + it('should return a promise that resolves to an api response when request receives a 404 response', async function () { + const client = new OnspringClient(baseUrl, apiKey); + + const mockAxiosClient = axios.create({ + baseURL: baseUrl, + headers: { + 'x-apikey': apiKey, + 'x-api-version': '2', + }, + }); + + sinon.stub(mockAxiosClient, 'post').returns( + Promise.resolve({ + status: 404, + statusText: 'Not Found', + data: { + message: 'The requested resource was not found.', + }, + headers: {}, + config: {} as InternalAxiosRequestConfig, + } as AxiosResponse) + ); + + sinon.stub(client, '_client' as any).value(mockAxiosClient); + + const saveFileRequest = new SaveFileRequest( + 1, + 1, + 'notes', + new Date(), + 'file name', + 'content type', + new Readable() + ); + + const result = await client.saveFile(saveFileRequest); + + expect(result).to.be.instanceOf(ApiResponse); + expect(result).to.have.property('statusCode', 404); + expect(result).to.have.property('isSuccessful', false); + expect(result.message).to.equal('The requested resource was not found.'); + expect(result.data).to.be.null; + }); + + it('should return a promise that resolves to an api response when request receives a 500 response', async function () { + const client = new OnspringClient(baseUrl, apiKey); + + const mockAxiosClient = axios.create({ + baseURL: baseUrl, + headers: { + 'x-apikey': apiKey, + 'x-api-version': '2', + }, + }); + + sinon.stub(mockAxiosClient, 'post').returns( + Promise.resolve({ + status: 500, + statusText: 'Internal Server Error', + headers: {}, + config: {} as InternalAxiosRequestConfig, + } as AxiosResponse) + ); + + sinon.stub(client, '_client' as any).value(mockAxiosClient); + + const saveFileRequest = new SaveFileRequest( + 1, + 1, + 'notes', + new Date(), + 'file name', + 'content type', + new Readable() + ); + + const result = await client.saveFile(saveFileRequest); + + expect(result).to.be.instanceOf(ApiResponse); + expect(result).to.have.property('statusCode', 500); + expect(result).to.have.property('isSuccessful', false); + expect(result.message).to.be.undefined; + expect(result.data).to.be.null; + }); + }); }); diff --git a/tests/SaveFileRequest.spec.ts b/tests/SaveFileRequest.spec.ts new file mode 100644 index 0000000..6becf5e --- /dev/null +++ b/tests/SaveFileRequest.spec.ts @@ -0,0 +1,257 @@ +import { expect } from 'chai'; +import { SaveFileRequest } from '../src/models/SaveFileRequest'; +import FormData from 'form-data'; +import { Readable } from 'stream'; + +describe('SaveFileRequest', function () { + it('should be defined', function () { + expect(SaveFileRequest).to.not.be.undefined; + }); + + it('should have a constructor', function () { + expect(SaveFileRequest).to.have.property('constructor'); + }); + + it('should have 7 parameters', function () { + expect(SaveFileRequest).to.have.lengthOf(7); + }); + + it('should create a new instance of the SaveFileRequest class', function () { + expect( + () => + new SaveFileRequest( + 1, + 1, + 'note', + new Date(), + 'file', + 'contentType', + new Readable() + ) + ).to.not.throw(); + }); + + it('should have a property named recordId', function () { + expect( + new SaveFileRequest( + 1, + 1, + 'note', + new Date(), + 'file', + 'contentType', + new Readable() + ) + ).to.have.property('recordId'); + }); + + it('should set the recordId property to the value passed to the constructor', function () { + expect( + new SaveFileRequest( + 1, + 1, + 'note', + new Date(), + 'file', + 'contentType', + new Readable() + ).recordId + ).to.equal(1); + }); + + it('should have a property named fieldId', function () { + expect( + new SaveFileRequest( + 1, + 1, + 'note', + new Date(), + 'file', + 'contentType', + new Readable() + ) + ).to.have.property('fieldId'); + }); + + it('should set the fieldId property to the value passed to the constructor', function () { + expect( + new SaveFileRequest( + 1, + 1, + 'note', + new Date(), + 'file', + 'contentType', + new Readable() + ).fieldId + ).to.equal(1); + }); + + it('should have a property named notes', function () { + expect( + new SaveFileRequest( + 1, + 1, + 'note', + new Date(), + 'file', + 'contentType', + new Readable() + ) + ).to.have.property('notes'); + }); + + it('should set the notes property to the value passed to the constructor', function () { + expect( + new SaveFileRequest( + 1, + 1, + 'note', + new Date(), + 'file', + 'contentType', + new Readable() + ).notes + ).to.equal('note'); + }); + + it('should have a property named modifiedDate', function () { + expect( + new SaveFileRequest( + 1, + 1, + 'note', + new Date(), + 'file', + 'contentType', + new Readable() + ) + ).to.have.property('modifiedDate'); + }); + + it('should set the modifiedDate property to the value passed to the constructor', function () { + const modifiedDate = new Date(); + + expect( + new SaveFileRequest( + 1, + 1, + 'note', + modifiedDate, + 'file', + 'contentType', + new Readable() + ).modifiedDate + ).to.deep.equal(modifiedDate); + }); + + it('should have a property named fileName', function () { + expect( + new SaveFileRequest( + 1, + 1, + 'note', + new Date(), + 'file', + 'contentType', + new Readable() + ) + ).to.have.property('fileName'); + }); + + it('should set the fileName property to the value passed to the constructor', function () { + expect( + new SaveFileRequest( + 1, + 1, + 'note', + new Date(), + 'file', + 'contentType', + new Readable() + ).fileName + ).to.equal('file'); + }); + + it('should have a property named contentType', function () { + expect( + new SaveFileRequest( + 1, + 1, + 'note', + new Date(), + 'file', + 'contentType', + new Readable() + ) + ).to.have.property('contentType'); + }); + + it('should set the contentType property to the value passed to the constructor', function () { + expect( + new SaveFileRequest( + 1, + 1, + 'note', + new Date(), + 'file', + 'contentType', + new Readable() + ).contentType + ).to.equal('contentType'); + }); + + it('should have a property named fileStream', function () { + expect( + new SaveFileRequest( + 1, + 1, + 'note', + new Date(), + 'file', + 'contentType', + new Readable() + ) + ).to.have.property('fileStream'); + }); + + it('should set the fileStream property to the value passed to the constructor', function () { + const stream = new Readable(); + + expect( + new SaveFileRequest( + 1, + 1, + 'note', + new Date(), + 'file', + 'contentType', + stream + ).fileStream + ).to.deep.equal(stream); + }); + + describe('asFormData', function () { + it('should be defined', function () { + expect(SaveFileRequest.prototype.asFormData).to.not.be.undefined; + }); + + it('should have 0 parameters', function () { + expect(SaveFileRequest.prototype.asFormData).to.have.lengthOf(0); + }); + + it('should return a FormData object', function () { + const formData = new SaveFileRequest( + 1, + 1, + 'note', + new Date(), + 'file', + 'contentType', + new Readable() + ).asFormData(); + + expect(formData).to.be.instanceof(FormData); + }); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index 6a616af..eb434f9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,8 @@ "module": "commonjs", "target": "es2015", "declaration": true, - "outDir": "./dist" + "outDir": "./dist", + "esModuleInterop": true }, "include": ["src/**/*"] }