From bc8b9a497775b2345c19372c5d27f1f4c592d962 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Fri, 17 Feb 2023 14:27:33 -0600 Subject: [PATCH] fix: begin writing Lists integration tests. fix: list item response model's id value should be of type string so modified the created with id response model that it extends so that the id property is generically typed and type can be passed in. --- .../Lists/addOrUpdateListItem.spec.ts | 115 ++++++++++++++++++ .../Lists/addOrUpdateListItemById.spec.ts | 0 src/models/ApiResponse.ts | 12 +- src/models/CreatedWithIdResponse.ts | 10 +- src/models/ListItemRequest.ts | 24 ++-- src/models/ListItemResponse.ts | 7 +- src/models/OnspringClient.ts | 6 +- src/models/SaveRecordResponse.ts | 2 +- tests/ApiResponse.spec.ts | 2 +- tests/ListItemResponse.spec.ts | 2 +- 10 files changed, 148 insertions(+), 32 deletions(-) create mode 100644 integrationTests/Lists/addOrUpdateListItem.spec.ts delete mode 100644 integrationTests/Lists/addOrUpdateListItemById.spec.ts diff --git a/integrationTests/Lists/addOrUpdateListItem.spec.ts b/integrationTests/Lists/addOrUpdateListItem.spec.ts new file mode 100644 index 0000000..a489d62 --- /dev/null +++ b/integrationTests/Lists/addOrUpdateListItem.spec.ts @@ -0,0 +1,115 @@ +import { ListItemRequest } from './../../src'; +import { OnspringClient } from '../../src'; +import { expect } from 'chai'; +import { baseURL, apiKey } from '../mochaRootHooks'; + +describe('addOrUpdateListItem', function () { + this.timeout(30000); + this.retries(3); + + const newListItemIds: string[] = []; + + // Delete the list items that were created during the test + after(async function () { + for (const id of newListItemIds) { + await deleteListItem(id); + } + }); + + it('should add a list item', async function () { + const client = new OnspringClient(baseURL, apiKey); + + if (process.env.TEST_LIST_FIELD === undefined) { + expect.fail('TEST_LIST_FIELD is not defined'); + } + + if (process.env.TEST_LIST_ID === undefined) { + expect.fail('TEST_LIST_ID is not defined'); + } + + const request = new ListItemRequest( + parseInt(process.env.TEST_LIST_ID), + null, + `added_list_value_${new Date().getTime()}}`, + 1, + '#000000' + ); + + const response = await client.addOrUpdateListItem(request); + + expect(response.statusCode).to.equal(201); + expect(response.isSuccessful).to.be.true; + expect(response.message).to.equal(''); + expect(response.data).to.not.be.null; + + if (response.data != null) { + expect(response.data.id).to.not.be.null; + newListItemIds.push(response.data.id); + } + }); + + it('should update a list item', async function () { + const client = new OnspringClient(baseURL, apiKey); + + if (process.env.TEST_LIST_FIELD === undefined) { + expect.fail('TEST_LIST_FIELD is not defined'); + } + + if (process.env.TEST_LIST_ID === undefined) { + expect.fail('TEST_LIST_ID is not defined'); + } + + const request = new ListItemRequest( + parseInt(process.env.TEST_LIST_ID), + null, + `added_list_value_${new Date().getTime()}}`, + null, + null + ); + + const response = await client.addOrUpdateListItem(request); + const listItemId = response.data?.id; + + if (listItemId == null) { + expect.fail('new listItemId is null'); + } + + newListItemIds.push(listItemId); + + const updateRequest = new ListItemRequest( + parseInt(process.env.TEST_LIST_ID), + listItemId, + `updated_list_value_${new Date().getTime()}}`, + 1, + '#000000' + ); + + const updateResponse = await client.addOrUpdateListItem(updateRequest); + + expect(updateResponse.statusCode).to.equal(200); + expect(updateResponse.isSuccessful).to.be.true; + expect(updateResponse.message).to.equal(''); + expect(updateResponse.data).to.not.be.null; + }); + + // it('should return a 401 error when an invalid api key is used', async function () {}); + + // it('should return a 403 error when api key does not have access to the list', async function () {}); + + // it('should return a 404 error when the list does not exist', async function () {}); + + // it('should return a 404 error when the list item does not exist', async function () {}); +}); + +async function deleteListItem(listItemIds: string): Promise { + const client = new OnspringClient(baseURL, apiKey); + + if (process.env.TEST_LIST_ID === undefined) { + return; + } + + await client.deleteListItemById( + parseInt(process.env.TEST_LIST_ID), + listItemIds + ); +} diff --git a/integrationTests/Lists/addOrUpdateListItemById.spec.ts b/integrationTests/Lists/addOrUpdateListItemById.spec.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/models/ApiResponse.ts b/src/models/ApiResponse.ts index 804a3d4..bba2439 100644 --- a/src/models/ApiResponse.ts +++ b/src/models/ApiResponse.ts @@ -219,17 +219,19 @@ export class ApiResponse { } /** - * @method asCreatedWithIdResponseType - Converts the ApiResponse to an ApiResponse. - * @returns {ApiResponse} - An ApiResponse. + * @method asCreatedWithIdResponseType - Converts the ApiResponse to an ApiResponse>. + * @returns {ApiResponse>} - An ApiResponse>. */ - public asCreatedWithIdResponseType(): ApiResponse { + public asCreatedWithIdResponseType(): ApiResponse< + CreatedWithIdResponse + > { const apiResponse = this as ApiResponse; - const createdWithIdResponse = new CreatedWithIdResponse( + const createdWithIdResponse = new CreatedWithIdResponse( apiResponse.data.id ); - return new ApiResponse( + return new ApiResponse>( apiResponse.statusCode, apiResponse.message, createdWithIdResponse diff --git a/src/models/CreatedWithIdResponse.ts b/src/models/CreatedWithIdResponse.ts index 3dbd2c4..9907e65 100644 --- a/src/models/CreatedWithIdResponse.ts +++ b/src/models/CreatedWithIdResponse.ts @@ -1,15 +1,15 @@ -export class CreatedWithIdResponse { +export class CreatedWithIdResponse { /** - * @property {number} id - The id of the created object. + * @property {T} id - The id of the created object. */ - public id: number; + public id: T; /** * @constructor - Creates a new instance of the CreatedWithIdResponse class. * @param id - The id of the created object. - * @returns {CreatedWithIdResponse} - A new instance of the CreatedWithIdResponse class. + * @returns {CreatedWithIdResponse} - A new instance of the CreatedWithIdResponse class. */ - constructor(id: number) { + constructor(id: T) { this.id = id; } } diff --git a/src/models/ListItemRequest.ts b/src/models/ListItemRequest.ts index 5af2f65..eee1458 100644 --- a/src/models/ListItemRequest.ts +++ b/src/models/ListItemRequest.ts @@ -8,9 +8,9 @@ export class ListItemRequest { public listId: number; /** - * @property {string} id - The id for the list item. + * @property {string | null} id - The id for the list item. */ - public id: string; + public id: string | null; /** * @property {string} name - The name of the list item. @@ -18,30 +18,30 @@ export class ListItemRequest { public name: string; /** - * @property {number} numericValue - The numeric value of the list item. + * @property {number | null} numericValue - The numeric value of the list item. */ - public numericValue: number; + public numericValue: number | null; /** - * @property {string} color - The color of the list item. + * @property {string | null} color - The color of the list item. */ - public color: string; + public color: string | null; /** * @constructor - Creates a new instance of the ListItemRequest class. * @param {number} listId - The id for the list that the item belongs to. - * @param {string} id - The id for the list item. + * @param {string | null} id - The id for the list item. * @param {string} name - The name of the list item. - * @param {number} numericValue - The numeric value of the list item. - * @param {string} color - The color of the list item. + * @param {number | null} numericValue - The numeric value of the list item. + * @param {string | null} color - The color of the list item. * @returns {ListItemRequest} - A new instance of the ListItemRequest class. */ constructor( listId: number, - id: string, + id: string | null, name: string, - numericValue: number, - color: string + numericValue: number | null, + color: string | null ) { this.listId = listId; this.id = id; diff --git a/src/models/ListItemResponse.ts b/src/models/ListItemResponse.ts index d68ecac..24dc238 100644 --- a/src/models/ListItemResponse.ts +++ b/src/models/ListItemResponse.ts @@ -1,15 +1,14 @@ import { CreatedWithIdResponse } from './CreatedWithIdResponse'; - /** * @class ListItemResponse - Represents a respons when a list item is created or updated. */ -export class ListItemResponse extends CreatedWithIdResponse { +export class ListItemResponse extends CreatedWithIdResponse { /** * @constructor - Creates a new instance of ListItemResponse. - * @param {number} id - The id of the list item. + * @param {string} id - The id of the list item. * @returns {ListItemResponse} - A new instance of ListItemResponse. */ - constructor(id: number) { + constructor(id: string) { super(id); } } diff --git a/src/models/OnspringClient.ts b/src/models/OnspringClient.ts index 2cdf228..b79696b 100644 --- a/src/models/OnspringClient.ts +++ b/src/models/OnspringClient.ts @@ -264,11 +264,11 @@ export class OnspringClient { /** * @method saveFile - Saves a file to a record in Onspring. * @param {SaveFileRequest} request - The request that will be used to save the file. - * @returns {Promise>} - A promise that resolves to an ApiResponse of type CreatedWithIdResponse. + * @returns {Promise>>} - A promise that resolves to an ApiResponse of type CreatedWithIdResponse. */ public async saveFile( request: SaveFileRequest - ): Promise> { + ): Promise>> { const endpoint = EndpointFactory.getSaveFileEndpoint(); const formData = request.asFormData(); const apiResponse = await this.post(endpoint, formData, { @@ -279,7 +279,7 @@ export class OnspringClient { return apiResponse; } - return apiResponse.asCreatedWithIdResponseType(); + return apiResponse.asCreatedWithIdResponseType(); } public async deleteFileById( diff --git a/src/models/SaveRecordResponse.ts b/src/models/SaveRecordResponse.ts index 0c3dcec..ad70380 100644 --- a/src/models/SaveRecordResponse.ts +++ b/src/models/SaveRecordResponse.ts @@ -1,6 +1,6 @@ import { CreatedWithIdResponse } from './CreatedWithIdResponse'; -export class SaveRecordResponse extends CreatedWithIdResponse { +export class SaveRecordResponse extends CreatedWithIdResponse { public warnings: string[]; constructor(id: number, warnings: string[] = []) { diff --git a/tests/ApiResponse.spec.ts b/tests/ApiResponse.spec.ts index 2a48785..1b4136f 100644 --- a/tests/ApiResponse.spec.ts +++ b/tests/ApiResponse.spec.ts @@ -780,7 +780,7 @@ describe('ApiResponse', function () { const createdWithIdResponse = apiResponse.asCreatedWithIdResponseType(); expect(createdWithIdResponse).to.be.instanceOf( - ApiResponse + ApiResponse> ); expect(createdWithIdResponse.data).to.be.instanceOf( CreatedWithIdResponse diff --git a/tests/ListItemResponse.spec.ts b/tests/ListItemResponse.spec.ts index 9de321a..67a68c8 100644 --- a/tests/ListItemResponse.spec.ts +++ b/tests/ListItemResponse.spec.ts @@ -12,7 +12,7 @@ describe('ListItemResponse', function () { }); it('should have a constructor that takes an id and sets the id property', function () { - const id = 1; + const id = '3fa85f64-5717-4562-b3fc-2c963f66afa6'; const listItemResponse = new ListItemResponse(id); expect(listItemResponse).to.have.property('id', id); });