fix: properly implement saveFile method and write test

This commit is contained in:
StevanFreeborn
2023-02-03 22:32:57 -06:00
parent 3dee5b690c
commit ed68b5f9d9
9 changed files with 669 additions and 58 deletions
+60 -26
View File
@@ -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<App> 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<CollectionResponse<App[]>> 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<CollectionResponse<App>>
@@ -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<Field> 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<CollectionResponse<Field>> 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<CollectionResponse<Field>>
@@ -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<GetPagedFieldsResponse>
@@ -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<GetPagedFieldsResponse>
@@ -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<CreatedWithIdResponse> 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<CreatedWithIdResponse>
);
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);
}
});
});
});
+28
View File
@@ -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);
});
});
+290
View File
@@ -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;
});
});
});
+257
View File
@@ -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);
});
});
});