diff --git a/src/models/ApiResponse.ts b/src/models/ApiResponse.ts index 5503fa9..2b22c37 100644 --- a/src/models/ApiResponse.ts +++ b/src/models/ApiResponse.ts @@ -17,6 +17,7 @@ import { ListField } from './ListField'; import { ListItemResponse } from './ListItemResponse'; import { ListValue } from './ListValue'; import { Record } from './Record'; +import { RecordValue } from './RecordValue'; import { ReferenceField } from './ReferenceField'; import { Report } from './Report'; import { ReportData } from './ReportData'; @@ -336,10 +337,18 @@ export class ApiResponse { public asRecordType(): ApiResponse { const apiResponse = this as ApiResponse; + const recordValues = apiResponse.data.fieldData.map((fieldData: any) => { + return new RecordValue( + fieldData.type, + fieldData.fieldId, + fieldData.value + ); + }); + const record = new Record( apiResponse.data.appId, apiResponse.data.recordId, - apiResponse.data.fieldData + recordValues ); return new ApiResponse( diff --git a/src/models/GetRecordRequest.ts b/src/models/GetRecordRequest.ts index 1c3ca56..2a3a2e5 100644 --- a/src/models/GetRecordRequest.ts +++ b/src/models/GetRecordRequest.ts @@ -1,46 +1,46 @@ -import { type DataFormat } from '../enums/DataFormat'; - -/** - * @class GetRecordRequest - A request to get a record. - */ -export class GetRecordRequest { - /** - * @property {number} appId - The id of the app that the record belongs to. - */ - public appId: number; - - /** - * @property {number} recordId - The id of the record. - */ - public recordId: number; - - /** - * @property {number[]} fieldIds - The ids of the fields to include in the response. - */ - public fieldIds: number[]; - - /** - * @property {DataFormat} dataFormat - The format of the data in the response. - */ - public dataFormat: DataFormat; - - /** - * @constructor - Creates a new instance of GetRecordRequest. - * @param {number} appId - The id of the app that the record belongs to. - * @param {number} recordId - The id of the record. - * @param {number[]} fieldIds - The ids of the fields to include in the response. - * @param {DataFormat} dataFormat - The format of the data in the response. - * @returns {GetRecordRequest} - A new instance of GetRecordRequest. - */ - constructor( - appId: number, - recordId: number, - fieldIds: number[], - dataFormat: DataFormat - ) { - this.appId = appId; - this.recordId = recordId; - this.fieldIds = fieldIds; - this.dataFormat = dataFormat; - } -} +import { DataFormat } from '../enums/DataFormat'; + +/** + * @class GetRecordRequest - A request to get a record. + */ +export class GetRecordRequest { + /** + * @property {number} appId - The id of the app that the record belongs to. + */ + public appId: number; + + /** + * @property {number} recordId - The id of the record. + */ + public recordId: number; + + /** + * @property {number[]} fieldIds - The ids of the fields to include in the response. + */ + public fieldIds: number[]; + + /** + * @property {DataFormat} dataFormat - The format of the data in the response. + */ + public dataFormat: DataFormat; + + /** + * @constructor - Creates a new instance of GetRecordRequest. + * @param {number} appId - The id of the app that the record belongs to. + * @param {number} recordId - The id of the record. + * @param {number[]} fieldIds - The ids of the fields to include in the response. + * @param {DataFormat} dataFormat - The format of the data in the response. + * @returns {GetRecordRequest} - A new instance of GetRecordRequest. + */ + constructor( + appId: number, + recordId: number, + fieldIds: number[] = [], + dataFormat: DataFormat = DataFormat.Raw + ) { + this.appId = appId; + this.recordId = recordId; + this.fieldIds = fieldIds; + this.dataFormat = dataFormat; + } +} diff --git a/src/models/OnspringClient.ts b/src/models/OnspringClient.ts index f0c5da6..e5f6964 100644 --- a/src/models/OnspringClient.ts +++ b/src/models/OnspringClient.ts @@ -313,9 +313,11 @@ export class OnspringClient { public async getRecordById( request: GetRecordRequest ): Promise> { - const { appId, recordId, ...params } = request; + const { appId, recordId, fieldIds, dataFormat } = request; const endpoint = EndpointFactory.getRecordByIdEndpoint(appId, recordId); - const apiResponse = await this.get(endpoint, { params }); + const apiResponse = await this.get(endpoint, { + params: { fieldIds: fieldIds.join(','), dataFormat }, + }); if (apiResponse.isSuccessful === false) { return apiResponse; diff --git a/src/models/RecordValue.ts b/src/models/RecordValue.ts index 53979bc..8435cdf 100644 --- a/src/models/RecordValue.ts +++ b/src/models/RecordValue.ts @@ -78,18 +78,17 @@ export class RecordValue { */ public asAttachmentArray(): Attachment[] { this.validateType([RecordValueType.AttachmentList]); - - const storageLocation = FileStorageSite[this.value.storageLocation]; - - if (storageLocation === undefined) { - throw new Error( - `${ - this.value.storageLocation as string - } is not a valid FileStorageSite.` - ); - } - return this.value.map((attachment: any) => { + const storageLocation = FileStorageSite[attachment.storageLocation]; + + if (storageLocation === undefined) { + throw new Error( + `${ + this.value.storageLocation as string + } is not a valid FileStorageSite.` + ); + } + const hasNotes = attachment.notes !== null && attachment.notes !== undefined; @@ -177,7 +176,7 @@ export class RecordValue { scoringGroup.listValueId, scoringGroup.name, scoringGroup.score, - scoringGroup.maximunScore + scoringGroup.maximumScore ) ); } diff --git a/tests/ApiResponse.spec.ts b/tests/ApiResponse.spec.ts index 230e68b..c6b0b73 100644 --- a/tests/ApiResponse.spec.ts +++ b/tests/ApiResponse.spec.ts @@ -23,6 +23,8 @@ import { GetPagedReportsResponse } from '../src/models/GetPagedReportsResponse'; import { Report } from '../src/models/Report'; import { ReportData } from '../src/models/ReportData'; import { Row } from '../src/models/Row'; +import { Record } from '../src/models/Record'; +import { RecordValue } from '../src/models/RecordValue'; describe('ApiResponse', function () { it('should be defined', function () { @@ -526,6 +528,21 @@ describe('ApiResponse', function () { .that.is.instanceOf(Array) .and.has.lengthOf(0); }); + + it('should throw an error when data contains an unknown field type', function () { + const mockResponseData = { + id: 1, + appId: 1, + name: 'Unknown Field', + type: 'Unknown', + status: 'Enabled', + isRequired: false, + isUnique: false, + }; + + const apiResponse = new ApiResponse(200, 'OK', mockResponseData); + expect(() => apiResponse.asFieldType()).to.throw(); + }); }); describe('asFieldCollectionType', function () { @@ -591,6 +608,26 @@ describe('ApiResponse', function () { }); } }); + + it('should throw an error when data contains an unknown field type', function () { + const mockResponseData = { + count: 1, + items: [ + { + id: 1, + appId: 1, + name: 'Unknown Field', + type: 'Unknown', + status: 'Enabled', + isRequired: false, + isUnique: false, + }, + ], + }; + + const apiResponse = new ApiResponse(200, 'OK', mockResponseData); + expect(() => apiResponse.asFieldCollectionType()).to.throw(); + }); }); describe('asGetPagedFieldsResponseType', function () { @@ -694,6 +731,29 @@ describe('ApiResponse', function () { .that.is.instanceOf(Array) .and.has.lengthOf(0); }); + + it('should throw an error when data contains an unknown field type', function () { + const mockResponseData = { + pageNumber: 1, + pageSize: 1, + totalPages: 1, + totalRecords: 1, + items: [ + { + id: 1, + appId: 1, + name: 'Unknown Field', + type: 'Unknown', + status: 'Enabled', + isRequired: false, + isUnique: false, + }, + ], + }; + + const apiResponse = new ApiResponse(200, 'OK', mockResponseData); + expect(() => apiResponse.asGetPagedFieldsResponseType()).to.throw(); + }); }); describe('asCreatedWithIdResponseType', function () { @@ -1066,4 +1126,51 @@ describe('ApiResponse', function () { } }); }); + + describe('asRecordType', function () { + it('should be defined', function () { + expect(ApiResponse.prototype.asRecordType).to.not.be.undefined; + }); + + it('should be a function', function () { + expect(ApiResponse.prototype.asRecordType).to.be.a('function'); + }); + + it('should have no parameters', function () { + expect(ApiResponse.prototype.asRecordType).to.have.lengthOf(0); + }); + + it('should return an ApiResponse', function () { + const mockResponseData = { + appId: 1, + recordId: 1, + fieldData: [ + { + type: 'Text', + fieldId: 'field 1', + value: 'field value 1', + }, + ], + }; + + const apiResponse = new ApiResponse(200, 'OK', mockResponseData); + const record = apiResponse.asRecordType(); + + expect(record).to.be.an.instanceof(ApiResponse); + expect(record.data).to.be.an.instanceof(Record); + expect(record.data).to.have.property('appId', 1); + expect(record.data).to.have.property('recordId', 1); + expect(record.data).to.have.property('fieldData').that.is.an('array'); + expect(record.data).to.not.be.null; + + if (record.data != null) { + record.data.fieldData.forEach((recordValue) => { + expect(recordValue).to.be.an.instanceof(RecordValue); + expect(recordValue).to.have.property('type'); + expect(recordValue).to.have.property('fieldId'); + expect(recordValue).to.have.property('value'); + }); + } + }); + }); }); diff --git a/tests/Attachment.spec.ts b/tests/Attachment.spec.ts index 205a616..21c3976 100644 --- a/tests/Attachment.spec.ts +++ b/tests/Attachment.spec.ts @@ -1,6 +1,55 @@ import { Attachment } from '../src/models/Attachment'; import { expect } from 'chai'; +import { FileStorageSite } from '../src/enums/FileStorageSite'; describe('Attachment', function () { - throw new Error('Not implemented'); + it('should be defined', function () { + expect(Attachment).to.not.be.undefined; + }); + + it('should have a constructor', function () { + expect(Attachment).to.have.property('constructor'); + }); + + it('should have a constructor that takes 4 parameters', function () { + expect(Attachment).to.have.lengthOf(4); + }); + + it('should have a fileId property', function () { + expect( + new Attachment(1, 'test', 'test', FileStorageSite.Internal) + ).to.have.property('fileId'); + }); + + it('should have a fileName property', function () { + expect( + new Attachment(1, 'test', 'test', FileStorageSite.Internal) + ).to.have.property('fileName'); + }); + + it('should have a notes property', function () { + expect( + new Attachment(1, 'test', 'test', FileStorageSite.Internal) + ).to.have.property('notes'); + }); + + it('should have a storageLocation property', function () { + expect( + new Attachment(1, 'test', 'test', FileStorageSite.Internal) + ).to.have.property('storageLocation'); + }); + + it('should have a constructor that sets its properties correctly', function () { + const fileId = 1; + const fileName = 'test'; + const notes = 'test'; + const storageLocation = FileStorageSite.Internal; + + const attachment = new Attachment(fileId, fileName, notes, storageLocation); + + expect(attachment).to.have.property('fileId', fileId); + expect(attachment).to.have.property('fileName', fileName); + expect(attachment).to.have.property('notes', notes); + expect(attachment).to.have.property('storageLocation', storageLocation); + }); }); diff --git a/tests/Delegate.spec.ts b/tests/Delegate.spec.ts new file mode 100644 index 0000000..3c02503 --- /dev/null +++ b/tests/Delegate.spec.ts @@ -0,0 +1,102 @@ +import { Delegate } from '../src/models/Delegate'; +import { expect } from 'chai'; +import { DelegateType } from '../src/enums/DelegateType'; + +describe('Delegate', function () { + it('should be defined', function () { + expect(Delegate).to.not.be.undefined; + }); + + it('should have a constructor', function () { + expect(Delegate).to.have.property('constructor'); + }); + + it('should have a constructor that takes 5 parameters', function () { + expect(Delegate).to.have.lengthOf(5); + }); + + it('should have a delegateType property', function () { + expect( + new Delegate( + DelegateType.External, + 'John Doe', + 'john.doe@email.com', + new Date(), + new Date() + ) + ).to.have.property('delegateType'); + }); + + it('should have a name property', function () { + expect( + new Delegate( + DelegateType.External, + 'John Doe', + 'john.doe@email.com', + new Date(), + new Date() + ) + ).to.have.property('name'); + }); + + it('should have a emailAddress property', function () { + expect( + new Delegate( + DelegateType.External, + 'John Doe', + 'john.doe@email.com', + new Date(), + new Date() + ) + ).to.have.property('emailAddress'); + }); + + it('should have a delegationDateTime property', function () { + expect( + new Delegate( + DelegateType.External, + 'John Doe', + 'john.doe@email.com', + new Date(), + new Date() + ) + ).to.have.property('delegationDateTime'); + }); + + it('should have a delegationCompletedDateTime property', function () { + expect( + new Delegate( + DelegateType.External, + 'John Doe', + 'john.doe@email.com', + new Date(), + new Date() + ) + ).to.have.property('delegationCompletedDateTime'); + }); + + it('should have a constructor that sets its properties correctly', function () { + const delegateType = DelegateType.External; + const name = 'John Doe'; + const emailAddress = 'john.doe@email.com'; + const delegationDateTime = new Date(); + const delegationCompletedDateTime = new Date(); + + const delegate = new Delegate( + delegateType, + name, + emailAddress, + delegationDateTime, + delegationCompletedDateTime + ); + + expect(delegate).to.have.property('delegateType', delegateType); + expect(delegate).to.have.property('name', name); + expect(delegate).to.have.property('emailAddress', emailAddress); + expect(delegate).to.have.property('delegationDateTime', delegationDateTime); + expect(delegate).to.have.property( + 'delegationCompletedDateTime', + delegationCompletedDateTime + ); + }); +}); diff --git a/tests/GetPagedRecordsResponse.spec.ts b/tests/GetPagedRecordsResponse.spec.ts new file mode 100644 index 0000000..9c36273 --- /dev/null +++ b/tests/GetPagedRecordsResponse.spec.ts @@ -0,0 +1,68 @@ +import { GetPagedRecordsResponse } from '../src/models/GetPagedRecordsResponse'; +import { expect } from 'chai'; + +describe('GetPagedRecordsResponse', function () { + it('should be defined', function () { + expect(GetPagedRecordsResponse).to.not.be.undefined; + }); + + it('should have a constructor', function () { + expect(GetPagedRecordsResponse).to.have.property('constructor'); + }); + + it('should have a constructor that takes 5 parameters', function () { + expect(GetPagedRecordsResponse).to.have.lengthOf(5); + }); + + it('should have a items property', function () { + expect(new GetPagedRecordsResponse([], 1, 1, 1, 1)).to.have.property( + 'items' + ); + }); + + it('should have a pageNumber property', function () { + expect(new GetPagedRecordsResponse([], 1, 1, 1, 1)).to.have.property( + 'pageNumber' + ); + }); + + it('should have a pageSize property', function () { + expect(new GetPagedRecordsResponse([], 1, 1, 1, 1)).to.have.property( + 'pageSize' + ); + }); + + it('should have a totalPages property', function () { + expect(new GetPagedRecordsResponse([], 1, 1, 1, 1)).to.have.property( + 'totalPages' + ); + }); + + it('should have a totalRecords property', function () { + expect(new GetPagedRecordsResponse([], 1, 1, 1, 1)).to.have.property( + 'totalRecords' + ); + }); + + it('should have a constructor that sets the items property', function () { + const items = []; + const pageNumber = 1; + const pageSize = 1; + const totalPages = 1; + const totalRecords = 1; + + const response = new GetPagedRecordsResponse( + items, + pageNumber, + pageSize, + totalPages, + totalRecords + ); + + expect(response).to.have.property('items', items); + expect(response).to.have.property('pageNumber', pageNumber); + expect(response).to.have.property('pageSize', pageSize); + expect(response).to.have.property('totalPages', totalPages); + expect(response).to.have.property('totalRecords', totalRecords); + }); +}); diff --git a/tests/GetRecordRequest.spec.ts b/tests/GetRecordRequest.spec.ts new file mode 100644 index 0000000..14d49d9 --- /dev/null +++ b/tests/GetRecordRequest.spec.ts @@ -0,0 +1,55 @@ +import { GetRecordRequest } from '../src/models/GetRecordRequest'; +import { expect } from 'chai'; +import { DataFormat } from '../src/enums/DataFormat'; + +describe('GetRecordRequest', function () { + it('should be defined', function () { + expect(GetRecordRequest).to.not.be.undefined; + }); + + it('should have a constructor', function () { + expect(GetRecordRequest).to.have.property('constructor'); + }); + + it('should have a constructor that takes 2 parameter', function () { + expect(GetRecordRequest).to.have.lengthOf(2); + }); + + it('should have a appId property', function () { + expect(new GetRecordRequest(1, 1, [1, 2], DataFormat.Raw)).to.have.property( + 'appId' + ); + }); + + it('should have a recordId property', function () { + expect(new GetRecordRequest(1, 1, [1, 2], DataFormat.Raw)).to.have.property( + 'recordId' + ); + }); + + it('should have a fieldIds property', function () { + expect(new GetRecordRequest(1, 1, [1, 2], DataFormat.Raw)).to.have.property( + 'fieldIds' + ); + }); + + it('should have a dataFormat property', function () { + expect(new GetRecordRequest(1, 1, [1, 2], DataFormat.Raw)).to.have.property( + 'dataFormat' + ); + }); + + it('should have a constructor that sets its properties correctly', function () { + const appId = 1; + const recordId = 1; + const fieldIds = [1, 2]; + const dataFormat = DataFormat.Raw; + + const request = new GetRecordRequest(appId, recordId, fieldIds, dataFormat); + + expect(request).to.have.property('appId', appId); + expect(request).to.have.property('recordId', recordId); + expect(request).to.have.property('fieldIds', fieldIds); + expect(request).to.have.property('dataFormat', dataFormat); + }); +}); diff --git a/tests/OnspringClient.spec.ts b/tests/OnspringClient.spec.ts index 1df7461..3c42461 100644 --- a/tests/OnspringClient.spec.ts +++ b/tests/OnspringClient.spec.ts @@ -25,6 +25,9 @@ import { ReportData } from '../src/models/ReportData'; import fs from 'fs'; import path from 'path'; import * as sinon from 'sinon'; +import { GetRecordRequest } from '../src/models/GetRecordRequest'; +import { Record } from '../src/models/Record'; +import { RecordValue } from '../src/models/RecordValue'; describe('OnspringClient', function () { const baseUrl = 'https://api.onspring.dev'; @@ -2822,4 +2825,178 @@ describe('OnspringClient', function () { expect(result).to.have.property('data', null); }); }); + + describe('getRecordById', function () { + it('should be defined', function () { + expect(OnspringClient.prototype.getRecordById).to.not.be.undefined; + }); + + it('should be a function', function () { + expect(OnspringClient.prototype.getRecordById).to.be.a('function'); + }); + + it('should return a promise', function () { + expect( + new OnspringClient(baseUrl, apiKey).getRecordById( + new GetRecordRequest(1, 1) + ) + ).to.be.instanceOf(Promise); + }); + + it('should return a promise that resolves to an api response when 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, 'get').returns( + Promise.resolve({ + status: 200, + statusText: 'OK', + data: { + appId: 1, + recordId: 1, + fieldData: [ + { + type: 'Text', + fieldId: 1, + value: 'Test', + }, + { + type: 'Text', + fieldId: 2, + value: 'Test', + }, + ], + }, + headers: {}, + config: {} as InternalAxiosRequestConfig, + } as AxiosResponse) + ); + + sinon.stub(client, '_client' as any).value(mockAxiosClient); + + const result = await client.getRecordById(new GetRecordRequest(1, 1)); + + expect(result).to.be.instanceOf(ApiResponse); + expect(result).to.have.property('statusCode', 200); + 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(Record); + expect(result.data).to.have.property('appId', 1); + expect(result.data).to.have.property('recordId', 1); + expect(result.data).to.have.property('fieldData'); + + if (result.data != null) { + expect(result.data.fieldData).to.be.an('array').that.has.lengthOf(2); + result.data.fieldData.forEach((recordValue) => { + expect(recordValue).to.be.instanceOf(RecordValue); + expect(recordValue).to.have.property('type'); + expect(recordValue).to.have.property('fieldId'); + expect(recordValue).to.have.property('value'); + }); + } + }); + + 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, 'get').returns( + Promise.resolve({ + status: 401, + statusText: 'Unauthorized', + headers: {}, + config: {} as InternalAxiosRequestConfig, + } as AxiosResponse) + ); + + sinon.stub(client, '_client' as any).value(mockAxiosClient); + + const result = await client.getRecordById(new GetRecordRequest(1, 1)); + + expect(result).to.be.instanceOf(ApiResponse); + expect(result).to.have.property('statusCode', 401); + expect(result).to.have.property('isSuccessful', false); + expect(result).to.have.property('message', undefined); + expect(result).to.have.property('data', 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, 'get').returns( + Promise.resolve({ + status: 403, + statusText: 'Forbidden', + data: { message: 'Forbidden' }, + headers: {}, + config: {} as InternalAxiosRequestConfig, + } as AxiosResponse) + ); + + sinon.stub(client, '_client' as any).value(mockAxiosClient); + + const result = await client.getRecordById(new GetRecordRequest(1, 1)); + + expect(result).to.be.instanceOf(ApiResponse); + expect(result).to.have.property('statusCode', 403); + expect(result).to.have.property('isSuccessful', false); + expect(result).to.have.property('message', 'Forbidden'); + expect(result).to.have.property('data', 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, 'get').returns( + Promise.resolve({ + status: 404, + statusText: 'Not Found', + data: { message: 'Not Found' }, + headers: {}, + config: {} as InternalAxiosRequestConfig, + } as AxiosResponse) + ); + + sinon.stub(client, '_client' as any).value(mockAxiosClient); + + const result = await client.getRecordById(new GetRecordRequest(1, 1)); + + expect(result).to.be.instanceOf(ApiResponse); + expect(result).to.have.property('statusCode', 404); + expect(result).to.have.property('isSuccessful', false); + expect(result).to.have.property('message', 'Not Found'); + expect(result).to.have.property('data', null); + }); + }); }); diff --git a/tests/Record.spec.ts b/tests/Record.spec.ts index 37844b3..a89e945 100644 --- a/tests/Record.spec.ts +++ b/tests/Record.spec.ts @@ -1,6 +1,7 @@ import { Record } from '../src/models/Record'; import { expect } from 'chai'; import { RecordValueType } from '../src/enums/RecordValueType'; +import { RecordValue } from '../src/models/RecordValue'; describe('Record', function () { it('should be defined', function () { @@ -17,16 +18,8 @@ describe('Record', function () { it('should have a constructor that sets its properties correctly', function () { const record = new Record(1, 2, [ - { - type: RecordValueType.String, - fieldId: 1, - value: 'test', - }, - { - type: RecordValueType.String, - fieldId: 2, - value: 'test', - }, + new RecordValue(RecordValueType.String, 1, 'test'), + new RecordValue(RecordValueType.String, 2, 'test'), ]); expect(record).to.have.property('appId', 1); expect(record).to.have.property('recordId', 2); @@ -39,16 +32,8 @@ describe('Record', function () { it('should have an appId property', function () { expect( new Record(1, 2, [ - { - type: RecordValueType.String, - fieldId: 1, - value: 'test', - }, - { - type: RecordValueType.String, - fieldId: 2, - value: 'test', - }, + new RecordValue(RecordValueType.String, 1, 'test'), + new RecordValue(RecordValueType.String, 2, 'test'), ]) ).to.have.property('appId'); }); @@ -56,16 +41,8 @@ describe('Record', function () { it('should have a recordId property', function () { expect( new Record(1, 2, [ - { - type: RecordValueType.String, - fieldId: 1, - value: 'test', - }, - { - type: RecordValueType.String, - fieldId: 2, - value: 'test', - }, + new RecordValue(RecordValueType.String, 1, 'test'), + new RecordValue(RecordValueType.String, 2, 'test'), ]) ).to.have.property('recordId'); }); @@ -73,16 +50,8 @@ describe('Record', function () { it('should have a fieldData property', function () { expect( new Record(1, 2, [ - { - type: RecordValueType.String, - fieldId: 1, - value: 'test', - }, - { - type: RecordValueType.String, - fieldId: 2, - value: 'test', - }, + new RecordValue(RecordValueType.String, 1, 'test'), + new RecordValue(RecordValueType.String, 2, 'test'), ]) ).to.have.property('fieldData'); }); diff --git a/tests/RecordValue.spec.ts b/tests/RecordValue.spec.ts index f761866..486fe49 100644 --- a/tests/RecordValue.spec.ts +++ b/tests/RecordValue.spec.ts @@ -1,6 +1,10 @@ import { RecordValue } from '../src/models/RecordValue'; import { expect } from 'chai'; import { RecordValueType } from '../src/enums/RecordValueType'; +import { Attachment } from '../src/models/Attachment'; +import { Delegate } from '../src/models/Delegate'; +import { ScoringGroup } from '../src/models/ScoringGroup'; +import { TimeSpanData } from '../src/models/TimeSpanData'; describe('RecordValue', function () { it('should be defined', function () { @@ -43,4 +47,418 @@ describe('RecordValue', function () { new RecordValue(RecordValueType.Date, 2, new Date().toUTCString()) ).to.have.property('value'); }); + + describe('asString', function () { + it('should be defined', function () { + expect(RecordValue.prototype.asString).to.not.be.undefined; + }); + + it('should be a function', function () { + expect(RecordValue.prototype.asString).to.be.a('function'); + }); + + it('should return the value as a string for valid types', function () { + const value = 'test'; + const validTypes = [RecordValueType.String, RecordValueType.Guid]; + + validTypes.forEach((type) => { + expect(new RecordValue(type, 2, value).asString()) + .to.equal(value) + .and.to.be.a('string'); + }); + }); + + it('should throw an error if called on record value with incorrect type', function () { + expect(() => + new RecordValue(RecordValueType.Date, 2, 'test').asString() + ).to.throw(); + }); + }); + + describe('asNumber', function () { + it('should be defined', function () { + expect(RecordValue.prototype.asNumber).to.not.be.undefined; + }); + + it('should be a function', function () { + expect(RecordValue.prototype.asNumber).to.be.a('function'); + }); + + it('should return the value as a number for valid types', function () { + const value = 1; + const validTypes = [RecordValueType.Integer, RecordValueType.Decimal]; + + validTypes.forEach((type) => { + expect(new RecordValue(type, 2, value).asNumber()) + .to.equal(value) + .and.to.be.a('number'); + }); + }); + + it('should throw an error if called on record value with incorrect type', function () { + expect(() => + new RecordValue(RecordValueType.Date, 2, 2).asNumber() + ).to.throw(); + }); + }); + + describe('asDate', function () { + it('should be defined', function () { + expect(RecordValue.prototype.asDate).to.not.be.undefined; + }); + + it('should be a function', function () { + expect(RecordValue.prototype.asDate).to.be.a('function'); + }); + + it('should return the value as a date for valid type', function () { + const value = new Date().toUTCString(); + expect(new RecordValue(RecordValueType.Date, 2, value).asDate()) + .to.deep.equal(new Date(value)) + .and.to.be.a('date'); + }); + + it('should throw an error if called on record value with incorrect type', function () { + expect(() => + new RecordValue(RecordValueType.Integer, 2, 'test').asDate() + ).to.throw(); + }); + }); + + describe('asAttachmentArray', function () { + it('should be defined', function () { + expect(RecordValue.prototype.asAttachmentArray).to.not.be.undefined; + }); + + it('should be a function', function () { + expect(RecordValue.prototype.asAttachmentArray).to.be.a('function'); + }); + + it('should return the value as an array of attachments for valid type', function () { + const value = [ + { + fileId: 1, + fileName: 'test', + notes: 'test', + storageLocation: 'Internal', + }, + { + fileId: 1, + fileName: 'test', + storageLocation: 'Internal', + }, + { + fileId: 1, + fileName: 'test', + notes: null, + storageLocation: 'Internal', + }, + ]; + + const attachmentArray = new RecordValue( + RecordValueType.AttachmentList, + 2, + value + ).asAttachmentArray(); + + expect(attachmentArray).to.be.an('array'); + + attachmentArray.forEach((attachment) => { + expect(attachment).to.be.an.instanceOf(Attachment); + expect(attachment).to.have.property('fileId'); + expect(attachment).to.have.property('fileName'); + expect(attachment).to.have.property('notes'); + expect(attachment).to.have.property('storageLocation'); + }); + }); + + it('should throw an error if attachment has incorrect storage location', function () { + const value = [ + { + fileId: 1, + fileName: 'test', + notes: 'test', + storageLocation: 'Invalid', + }, + ]; + + expect(() => + new RecordValue( + RecordValueType.AttachmentList, + 2, + value + ).asAttachmentArray() + ).to.throw(); + }); + + it('should throw an error if called on record value with incorrect type', function () { + expect(() => + new RecordValue(RecordValueType.Integer, 2, []).asAttachmentArray() + ).to.throw(); + }); + }); + + describe('asNumberArray', function () { + it('should be defined', function () { + expect(RecordValue.prototype.asNumberArray).to.not.be.undefined; + }); + + it('should be a function', function () { + expect(RecordValue.prototype.asNumberArray).to.be.a('function'); + }); + + it('should return the value as an array of numbers for valid types', function () { + const value = [1, 2, 3]; + const validTypes = [ + RecordValueType.FileList, + RecordValueType.IntegerList, + ]; + + validTypes.forEach((type) => { + const recordValue = new RecordValue(type, 2, value).asNumberArray(); + expect(recordValue).to.deep.equal(value).and.to.be.an('array'); + + recordValue.forEach((item) => { + expect(item).to.be.a('number'); + }); + }); + }); + + it('should throw an error if called on record value with incorrect type', function () { + expect(() => + new RecordValue(RecordValueType.Integer, 2, []).asNumberArray() + ).to.throw(); + }); + }); + + describe('asStringArray', function () { + it('should be defined', function () { + expect(RecordValue.prototype.asStringArray).to.not.be.undefined; + }); + + it('should be a function', function () { + expect(RecordValue.prototype.asStringArray).to.be.a('function'); + }); + + it('should return the value as an array of strings for valid types', function () { + const value = ['test', 'test', 'test']; + const validTypes = [RecordValueType.StringList, RecordValueType.GuidList]; + + validTypes.forEach((type) => { + const recordValue = new RecordValue(type, 2, value).asStringArray(); + expect(recordValue).to.deep.equal(value).and.to.be.an('array'); + + recordValue.forEach((item) => { + expect(item).to.be.a('string'); + }); + }); + }); + + it('should throw an error if called on record value with incorrect type', function () { + expect(() => + new RecordValue(RecordValueType.Integer, 2, []).asStringArray() + ).to.throw(); + }); + }); + + describe('asDelegateArray', function () { + it('should be defined', function () { + expect(RecordValue.prototype.asDelegateArray).to.not.be.undefined; + }); + + it('should be a function', function () { + expect(RecordValue.prototype.asDelegateArray).to.be.a('function'); + }); + + it('should return the value as an array of delegates for valid type', function () { + const value = [ + { + delegateType: 'External', + name: 'test', + emailAddress: 'test@test.com', + delegationDateTime: '2019-01-01T00:00:00.000Z', + delegationCompletedDateTime: '2019-01-01T00:00:00.000Z', + }, + { + delegateType: 'External', + name: null, + emailAddress: 'test@test.com', + delegationDateTime: '2019-01-01T00:00:00.000Z', + delegationCompletedDateTime: null, + }, + { + delegateType: 'External', + emailAddress: 'test@test.com', + delegationDateTime: '2019-01-01T00:00:00.000Z', + }, + ]; + + const recordValue = new RecordValue( + RecordValueType.ScoringGroupList, + 2, + value + ).asDelegateArray(); + + expect(recordValue).to.be.an('array'); + recordValue.forEach((item) => { + expect(item).to.be.an.instanceOf(Delegate); + expect(item).to.have.property('delegateType'); + expect(item).to.have.property('name'); + expect(item).to.have.property('emailAddress'); + expect(item).to.have.property('delegationDateTime'); + expect(item).to.have.property('delegationCompletedDateTime'); + }); + }); + + it('should throw an error if called on record value with incorrect type', function () { + expect(() => + new RecordValue(RecordValueType.Integer, 2, []).asDelegateArray() + ).to.throw(); + }); + + it('should throw an error if delegate has incorrect delegate type', function () { + const value = [ + { + delegateType: 'Invalid', + name: 'test', + emailAddress: 'test@test.com', + delegationDateTime: '2019-01-01T00:00:00.000Z', + delegationCompletedDateTime: '2019-01-01T00:00:00.000Z', + }, + ]; + + expect(() => + new RecordValue( + RecordValueType.ScoringGroupList, + 2, + value + ).asDelegateArray() + ).to.throw(); + }); + }); + + describe('asScoringGroupArray', function () { + it('should be defined', function () { + expect(RecordValue.prototype.asScoringGroupArray).to.not.be.undefined; + }); + + it('should be a function', function () { + expect(RecordValue.prototype.asScoringGroupArray).to.be.a('function'); + }); + + it('should return the value as an array of scoring groups for valid type', function () { + const value = [ + { + listValueId: 'test', + name: 'test', + score: 1, + maximumScore: 1, + }, + ]; + + const recordValue = new RecordValue( + RecordValueType.ScoringGroupList, + 2, + value + ).asScoringGroupArray(); + + expect(recordValue).to.deep.equal(value).and.to.be.an('array'); + + recordValue.forEach((item) => { + expect(item).to.be.an.instanceOf(ScoringGroup); + expect(item).to.have.property('listValueId'); + expect(item).to.have.property('name'); + expect(item).to.have.property('score'); + expect(item).to.have.property('maximumScore'); + }); + }); + + it('should throw an error if called on record value with incorrect type', function () { + expect(() => + new RecordValue(RecordValueType.Integer, 2, []).asScoringGroupArray() + ).to.throw(); + }); + }); + + describe('asTimeSpanData', function () { + it('should be defined', function () { + expect(RecordValue.prototype.asTimeSpanData).to.not.be.undefined; + }); + + it('should be a function', function () { + expect(RecordValue.prototype.asTimeSpanData).to.be.a('function'); + }); + + it('should return the value as a TimeSpanData for valid type', function () { + const cases = [ + { + quantity: 1, + increment: 'Days', + recurrence: 'None', + endAfterOccurrences: 1, + endByDate: '2019-01-01T00:00:00.000Z', + }, + { + quantity: 1, + increment: 'Days', + recurrence: null, + endAfterOccurrences: null, + endByDate: null, + }, + { + quantity: 1, + increment: 'Days', + }, + ]; + + cases.forEach((value) => { + const recordValue = new RecordValue( + RecordValueType.TimeSpan, + 2, + value + ).asTimeSpanData(); + + expect(recordValue).to.be.an.instanceOf(TimeSpanData); + expect(recordValue).to.have.property('quantity'); + expect(recordValue).to.have.property('increment'); + expect(recordValue).to.have.property('recurrence'); + expect(recordValue).to.have.property('endAfterOccurrences'); + expect(recordValue).to.have.property('endByDate'); + }); + }); + + it('should throw an error if called on record value with incorrect type', function () { + expect(() => + new RecordValue(RecordValueType.Integer, 2, []).asTimeSpanData() + ).to.throw(); + }); + + it('should throw an error if timespan has incorrect increment', function () { + const value = { + quantity: 1, + increment: 'Invalid', + recurrence: 'None', + endAfterOccurrences: 1, + endByDate: '2019-01-01T00:00:00.000Z', + }; + + expect(() => + new RecordValue(RecordValueType.TimeSpan, 2, value).asTimeSpanData() + ).to.throw(); + }); + + it('should throw an error if timespan has incorrect recurrence', function () { + const value = { + quantity: 1, + increment: 'Days', + recurrence: 'Invalid', + endAfterOccurrences: 1, + endByDate: '2019-01-01T00:00:00.000Z', + }; + + expect(() => + new RecordValue(RecordValueType.TimeSpan, 2, value).asTimeSpanData() + ).to.throw(); + }); + }); }); diff --git a/tests/ScoringGroup.spec.ts b/tests/ScoringGroup.spec.ts index 0106ec5..519ce49 100644 --- a/tests/ScoringGroup.spec.ts +++ b/tests/ScoringGroup.spec.ts @@ -2,5 +2,58 @@ import { ScoringGroup } from '../src/models/ScoringGroup'; import { expect } from 'chai'; describe('ScoringGroup', function () { - throw new Error('Not implemented'); + it('should be defined', function () { + expect(ScoringGroup).to.not.be.undefined; + }); + + it('should have a constructor', function () { + expect(ScoringGroup).to.have.property('constructor'); + }); + + it('should have a constructor that takes 4 parameters', function () { + expect(ScoringGroup).to.have.lengthOf(4); + }); + + it('should have a listValueId property', function () { + expect( + new ScoringGroup('7c9e6679-7425-40de-944b-e07fc1f90ae7', 'test', 1, 1) + ).to.have.property('listValueId'); + }); + + it('should have a name property', function () { + expect( + new ScoringGroup('7c9e6679-7425-40de-944b-e07fc1f90ae7', 'test', 1, 1) + ).to.have.property('name'); + }); + + it('should have a score property', function () { + expect( + new ScoringGroup('7c9e6679-7425-40de-944b-e07fc1f90ae7', 'test', 1, 1) + ).to.have.property('score'); + }); + + it('should have a maximumScore property', function () { + expect( + new ScoringGroup('7c9e6679-7425-40de-944b-e07fc1f90ae7', 'test', 1, 1) + ).to.have.property('maximumScore'); + }); + + it('should have a constructor that sets its properties correctly', function () { + const listValueId = '7c9e6679-7425-40de-944b-e07fc1f90ae7'; + const name = 'test'; + const score = 1; + const maximumScore = 1; + + const scoringGroup = new ScoringGroup( + listValueId, + name, + score, + maximumScore + ); + + expect(scoringGroup).to.have.property('listValueId', listValueId); + expect(scoringGroup).to.have.property('name', name); + expect(scoringGroup).to.have.property('score', score); + expect(scoringGroup).to.have.property('maximumScore', maximumScore); + }); }); diff --git a/tests/TimeSpanData.spec.ts b/tests/TimeSpanData.spec.ts index 61cd9a4..457d222 100644 --- a/tests/TimeSpanData.spec.ts +++ b/tests/TimeSpanData.spec.ts @@ -1,6 +1,102 @@ import { TimeSpanData } from '../src/models/TimeSpanData'; import { expect } from 'chai'; +import { TimeSpanIncrement } from '../src/enums/TimeSpanIncrement'; +import { TimeSpanRecurrenceType } from '../src/enums/TimeSpanRecurrenceType'; describe('TimeSpanData', function () { - throw new Error('Not implemented'); + it('should be defined', function () { + expect(TimeSpanData).to.not.be.undefined; + }); + + it('should have a constructor', function () { + expect(TimeSpanData).to.have.property('constructor'); + }); + + it('should have a constructor that takes 5 parameters', function () { + expect(TimeSpanData).to.have.lengthOf(5); + }); + + it('should have a quantity property', function () { + expect( + new TimeSpanData( + 1, + TimeSpanIncrement.Days, + TimeSpanRecurrenceType.None, + 1, + new Date() + ) + ).to.have.property('quantity'); + }); + + it('should have an increment property', function () { + expect( + new TimeSpanData( + 1, + TimeSpanIncrement.Days, + TimeSpanRecurrenceType.None, + 1, + new Date() + ) + ).to.have.property('increment'); + }); + + it('should have a recurrence property', function () { + expect( + new TimeSpanData( + 1, + TimeSpanIncrement.Days, + TimeSpanRecurrenceType.None, + 1, + new Date() + ) + ).to.have.property('recurrence'); + }); + + it('should have an endAfterOccurrences property', function () { + expect( + new TimeSpanData( + 1, + TimeSpanIncrement.Days, + TimeSpanRecurrenceType.None, + 1, + new Date() + ) + ).to.have.property('endAfterOccurrences'); + }); + + it('should have an endByDate property', function () { + expect( + new TimeSpanData( + 1, + TimeSpanIncrement.Days, + TimeSpanRecurrenceType.None, + 1, + new Date() + ) + ).to.have.property('endByDate'); + }); + + it('should have a constructor that sets its properties correctly', function () { + const quantity = 1; + const increment = TimeSpanIncrement.Days; + const recurrence = TimeSpanRecurrenceType.None; + const endAfterOccurrences = 1; + const endByDate = new Date(); + + const timeSpanData = new TimeSpanData( + quantity, + increment, + recurrence, + endAfterOccurrences, + endByDate + ); + expect(timeSpanData).to.have.property('quantity', quantity); + expect(timeSpanData).to.have.property('increment', increment); + expect(timeSpanData).to.have.property('recurrence', recurrence); + expect(timeSpanData).to.have.property( + 'endAfterOccurrences', + endAfterOccurrences + ); + expect(timeSpanData).to.have.property('endByDate', endByDate); + }); });