diff --git a/src/enums/FieldType.ts b/src/enums/FieldType.ts index 581099e..a3cc9d9 100644 --- a/src/enums/FieldType.ts +++ b/src/enums/FieldType.ts @@ -68,6 +68,11 @@ export enum FieldType { */ SurveyUnifiedAnswer = 'SurveyUnifiedAnswer', + /** + * @constant SurveyDelegation - The field is a survey delegation field. + */ + SurveyDelegation = 'SurveyDelegation', + /** * @constant Attachment - The field is a attachment field. * @type {string} diff --git a/src/models/ApiResponse.ts b/src/models/ApiResponse.ts index 9965142..b94506b 100644 --- a/src/models/ApiResponse.ts +++ b/src/models/ApiResponse.ts @@ -1,10 +1,15 @@ +import { FieldType } from '../enums/FieldType'; import { App } from './App'; import { CollectionResponse } from './CollectionResponse'; import { CreatedWithIdResponse } from './CreatedWithIdResponse'; import { Field } from './Field'; import { FileInfo } from './FileInfo'; +import { FormulaField } from './FormulaField'; import { GetPagedAppsResponse } from './GetPagedAppsResponse'; import { GetPagedFieldsResponse } from './GetPagedFieldsResponse'; +import { ListField } from './ListField'; +import { ListValue } from './ListValue'; +import { ReferenceField } from './ReferenceField'; /** * @class ApiResponse - A generic response object for API requests. @@ -119,16 +124,7 @@ export class ApiResponse { */ public asFieldType(): ApiResponse { const apiResponse = this as ApiResponse; - - const field = new Field( - apiResponse.data.id, - apiResponse.data.appId, - apiResponse.data.name, - apiResponse.data.type, - apiResponse.data.status, - apiResponse.data.isRequired, - apiResponse.data.isUnique - ); + const field = ApiResponse.getFieldByType(apiResponse.data); return new ApiResponse( apiResponse.statusCode, @@ -144,17 +140,9 @@ export class ApiResponse { public asFieldCollectionType(): ApiResponse> { const apiResponse = this as ApiResponse; - const fields = apiResponse.data.items.map((item: any) => { - return new Field( - item.id, - item.appId, - item.name, - item.type, - item.status, - item.isRequired, - item.isUnique - ); - }); + const fields = apiResponse.data.items.map((item: any) => + ApiResponse.getFieldByType(item) + ); const collectionResponse = new CollectionResponse( apiResponse.data.count, @@ -175,17 +163,9 @@ export class ApiResponse { public asGetPagedFieldsResponseType(): ApiResponse { const apiResponse = this as ApiResponse; - const fields = apiResponse.data.items.map((item: any) => { - return new Field( - item.id, - item.appId, - item.name, - item.type, - item.status, - item.isRequired, - item.isUnique - ); - }); + const fields = apiResponse.data.items.map((item: any) => + ApiResponse.getFieldByType(item) + ); const getPagedFieldsResponse = new GetPagedFieldsResponse( fields, @@ -220,7 +200,7 @@ export class ApiResponse { ); } - asFileInfoType(): ApiResponse { + public asFileInfoType(): ApiResponse { const apiResponse = this as ApiResponse; const fileInfo = new FileInfo( @@ -240,4 +220,86 @@ export class ApiResponse { fileInfo ); } + + /** + * @method asFileCollectionType - Converts the field item to the appropriate field object based upon the field item's type. + * @param fieldItem - The field item to convert. + * @returns {Field} - The converted field object. + */ + private static getFieldByType(fieldItem: any): Field { + switch (fieldItem.type) { + case FieldType.Reference: { + return new ReferenceField( + fieldItem.id, + fieldItem.appId, + fieldItem.name, + fieldItem.type, + fieldItem.status, + fieldItem.isRequired, + fieldItem.isUnique, + fieldItem.multiplicity, + fieldItem.referencedAppId + ); + } + case FieldType.List: { + const values = ApiResponse.getListValues(fieldItem); + + return new ListField( + fieldItem.id, + fieldItem.appId, + fieldItem.name, + fieldItem.type, + fieldItem.status, + fieldItem.isRequired, + fieldItem.isUnique, + fieldItem.multiplicity, + fieldItem.listId, + values + ); + } + case FieldType.Formula: { + const values = ApiResponse.getListValues(fieldItem); + + return new FormulaField( + fieldItem.id, + fieldItem.appId, + fieldItem.name, + fieldItem.type, + fieldItem.status, + fieldItem.isRequired, + fieldItem.isUnique, + fieldItem.outputType, + values + ); + } + default: { + return new Field( + fieldItem.id, + fieldItem.appId, + fieldItem.name, + fieldItem.type, + fieldItem.status, + fieldItem.isRequired, + fieldItem.isUnique + ); + } + } + } + + /** + * @method getListValues - Converts the field items list values to a ListValue[]. + * @param fieldItem - The field item whose values should be converted. + * @returns {ListValue[]} - The converted list values. + */ + private static getListValues(fieldItem: any): ListValue[] { + return fieldItem.values.map((listValue: any) => { + return new ListValue( + listValue.id, + listValue.name, + listValue.sortOrder, + listValue.numericValue, + listValue.color + ); + }); + } } diff --git a/src/models/FormulaField.ts b/src/models/FormulaField.ts new file mode 100644 index 0000000..f11dcd2 --- /dev/null +++ b/src/models/FormulaField.ts @@ -0,0 +1,31 @@ +import { FormulaOutputType } from '../enums/FormulaOutputType'; +import { Field } from './Field'; +import { type ListValue } from './ListValue'; + +export class FormulaField extends Field { + public outputType: FormulaOutputType; + public values: ListValue[]; + + constructor( + id: number, + appId: number, + name: string, + type: string, + status: string, + isRequired: boolean, + isUnique: boolean, + outputType: string, + values: ListValue[] + ) { + super(id, appId, name, type, status, isRequired, isUnique); + + if (FormulaOutputType[outputType] === undefined) { + throw new Error( + `The outputType ${outputType} is not a valid FormulaOutputType.` + ); + } + + this.outputType = FormulaOutputType[outputType]; + this.values = values; + } +} diff --git a/src/models/ListField.ts b/src/models/ListField.ts new file mode 100644 index 0000000..0aa4593 --- /dev/null +++ b/src/models/ListField.ts @@ -0,0 +1,34 @@ +import { Multiplicity } from '../enums/Multiplicity'; +import { Field } from './Field'; +import { type ListValue } from './ListValue'; + +export class ListField extends Field { + public multiplicity: Multiplicity; + public listId: number; + public values: ListValue[]; + + constructor( + id: number, + appId: number, + name: string, + type: string, + status: string, + isRequired: boolean, + isUnique: boolean, + multiplicity: string, + listId: number, + values: ListValue[] + ) { + super(id, appId, name, type, status, isRequired, isUnique); + + if (Multiplicity[multiplicity] === undefined) { + throw new Error( + `The multiplicity ${multiplicity} is not a valid Multiplicity.` + ); + } + + this.multiplicity = Multiplicity[multiplicity]; + this.listId = listId; + this.values = values; + } +} diff --git a/src/models/ListValue.ts b/src/models/ListValue.ts new file mode 100644 index 0000000..ebc12e5 --- /dev/null +++ b/src/models/ListValue.ts @@ -0,0 +1,21 @@ +export class ListValue { + public id: string; + public name: string; + public sortOrder: number; + public numericValue: number; + public color: string; + + constructor( + id: string, + name: string, + sortOrder: number, + numericValue: number, + color: string + ) { + this.id = id; + this.name = name; + this.sortOrder = sortOrder; + this.numericValue = numericValue; + this.color = color; + } +} diff --git a/src/models/ReferenceField.ts b/src/models/ReferenceField.ts new file mode 100644 index 0000000..a5fc590 --- /dev/null +++ b/src/models/ReferenceField.ts @@ -0,0 +1,30 @@ +import { Multiplicity } from '../enums/Multiplicity'; +import { Field } from './Field'; + +export class ReferenceField extends Field { + public multiplicity: Multiplicity; + public referencedAppId: number; + + constructor( + id: number, + appId: number, + name: string, + type: string, + status: string, + isRequired: boolean, + isUnique: boolean, + multiplicity: string, + referencedAppId: number + ) { + super(id, appId, name, type, status, isRequired, isUnique); + + if (Multiplicity[multiplicity] === undefined) { + throw new Error( + `The multiplicity ${multiplicity} is not a valid Multiplicity.` + ); + } + + this.multiplicity = Multiplicity[multiplicity]; + this.referencedAppId = referencedAppId; + } +} diff --git a/tests/ApiResponse.spec.ts b/tests/ApiResponse.spec.ts index af495a7..cfb24b2 100644 --- a/tests/ApiResponse.spec.ts +++ b/tests/ApiResponse.spec.ts @@ -8,6 +8,12 @@ import { FieldStatus } from '../src/enums/FieldStatus'; import { FieldType } from '../src/enums/FieldType'; import { GetPagedFieldsResponse } from '../src/models/GetPagedFieldsResponse'; import { CreatedWithIdResponse } from '../src/models/CreatedWithIdResponse'; +import { FormulaField } from '../src/models/FormulaField'; +import { FormulaOutputType } from '../src/enums/FormulaOutputType'; +import { ListValue } from '../src/models/ListValue'; +import { ReferenceField } from '../src/models/ReferenceField'; +import { Multiplicity } from '../src/enums/Multiplicity'; +import { ListField } from '../src/models/ListField'; describe('ApiResponse', function () { it('should be defined', function () { @@ -247,7 +253,7 @@ describe('ApiResponse', function () { expect(ApiResponse.prototype.asFieldType).to.have.lengthOf(0); }); - it('should return an ApiResponse when data contain a field', function () { + it('should return an ApiResponse when data contains a field', function () { const mockResponseData = { id: 1, appId: 1, @@ -274,6 +280,200 @@ describe('ApiResponse', function () { expect(fieldResponse.data.isUnique).to.equal(false); } }); + + it('should return an ApiResponse when data contains a list field', function () { + const mockResponseData = { + multiplicity: 'SingleSelect', + listId: 1581, + values: [ + { + id: 'e4ee09cf-f93c-40c8-89a4-070514acb25b', + name: 'List Value 1', + sortOrder: 1, + numericValue: 1, + color: '#ffffff', + }, + { + id: 'a44fbfb0-6fa9-4d9d-912a-b1807bb1693c', + name: 'List Value 2', + sortOrder: 2, + numericValue: 2, + color: '#ffffff', + }, + { + id: '27021e2c-b27a-4fab-84f6-570a5a83a1cd', + name: 'List Value 3', + sortOrder: 3, + numericValue: 3, + color: '#ffffff', + }, + ], + id: 11929, + appId: 373, + name: 'single-select list field', + type: 'List', + status: 'Enabled', + isRequired: false, + isUnique: false, + }; + + const apiResponse = new ApiResponse(200, 'OK', mockResponseData); + const fieldResponse = apiResponse.asFieldType(); + + expect(fieldResponse).to.be.instanceOf(ApiResponse); + expect(fieldResponse.data).to.be.instanceOf(Field); + expect(fieldResponse.data).to.be.instanceOf(ListField); + expect(fieldResponse.data).to.not.be.null; + if (fieldResponse.data != null) { + const listField = fieldResponse.data as ListField; + expect(listField.id).to.equal(11929); + expect(listField.appId).to.equal(373); + expect(listField.name).to.equal('single-select list field'); + expect(listField.type).to.equal(FieldType.List); + expect(listField.status).to.equal(FieldStatus.Enabled); + expect(listField.isRequired).to.equal(false); + expect(listField.isUnique).to.equal(false); + expect(listField.multiplicity).to.equal(Multiplicity.SingleSelect); + expect(listField.listId).to.equal(1581); + expect(listField.values).to.be.instanceOf(Array); + expect(listField.values).to.have.lengthOf(3); + listField.values.forEach((value) => { + expect(value).to.be.instanceOf(ListValue); + expect(value).to.have.property('id'); + expect(value).to.have.property('name'); + expect(value).to.have.property('sortOrder'); + expect(value).to.have.property('numericValue'); + expect(value).to.have.property('color'); + }); + } + }); + + it('should return an ApiResponse when data contains a reference field', function () { + const mockResponseData = { + multiplicity: 'SingleSelect', + referencedAppId: 2, + id: 11866, + appId: 373, + name: 'Created By', + type: 'Reference', + status: 'Enabled', + isRequired: false, + isUnique: false, + }; + + const apiResponse = new ApiResponse(200, 'OK', mockResponseData); + const fieldResponse = apiResponse.asFieldType(); + + expect(fieldResponse).to.be.instanceOf(ApiResponse); + expect(fieldResponse.data).to.be.instanceOf(Field); + expect(fieldResponse.data).to.be.instanceOf(ReferenceField); + expect(fieldResponse.data).to.not.be.null; + if (fieldResponse.data != null) { + const referenceField = fieldResponse.data as ReferenceField; + expect(referenceField.id).to.equal(11866); + expect(referenceField.appId).to.equal(373); + expect(referenceField.name).to.equal('Created By'); + expect(referenceField.type).to.equal(FieldType.Reference); + expect(referenceField.status).to.equal(FieldStatus.Enabled); + expect(referenceField.isRequired).to.equal(false); + expect(referenceField.isUnique).to.equal(false); + expect(referenceField.multiplicity).to.equal(Multiplicity.SingleSelect); + expect(referenceField.referencedAppId).to.equal(2); + } + }); + + it('should return an ApiResponse when data contains a list formula field', function () { + const mockResponseData = { + outputType: 'ListValue', + values: [ + { + id: '2dcc75c2-cd96-4bbc-babb-be78fb465e02', + name: 'List Value 1', + sortOrder: 1, + numericValue: 1, + color: '#d64646', + }, + { + id: '1f537f54-bf27-446b-a6a5-76aad5d3b5f6', + name: 'List Value 2', + sortOrder: 2, + numericValue: 1, + color: '#d64646', + }, + ], + id: 12680, + appId: 373, + name: 'List Formula Field', + type: 'Formula', + status: 'Enabled', + isRequired: false, + isUnique: false, + }; + + const apiResponse = new ApiResponse(200, 'OK', mockResponseData); + const fieldResponse = apiResponse.asFieldType(); + + expect(fieldResponse).to.be.instanceOf(ApiResponse); + expect(fieldResponse.data).to.be.instanceOf(Field); + expect(fieldResponse.data).to.be.instanceOf(FormulaField); + expect(fieldResponse.data).to.not.be.null; + if (fieldResponse.data != null) { + const formulaField = fieldResponse.data as FormulaField; + expect(formulaField.id).to.equal(12680); + expect(formulaField.appId).to.equal(373); + expect(formulaField.name).to.equal('List Formula Field'); + expect(formulaField.type).to.equal(FieldType.Formula); + expect(formulaField.status).to.equal(FieldStatus.Enabled); + expect(formulaField.isRequired).to.equal(false); + expect(formulaField.isUnique).to.equal(false); + expect(formulaField.outputType).to.equal(FormulaOutputType.ListValue); + expect(formulaField.values).to.be.instanceOf(Array); + expect(formulaField.values).to.have.lengthOf(2); + formulaField.values.forEach((value) => { + expect(value).to.be.instanceOf(ListValue); + expect(value).to.have.property('id'); + expect(value).to.have.property('name'); + expect(value).to.have.property('sortOrder'); + expect(value).to.have.property('numericValue'); + expect(value).to.have.property('color'); + }); + } + }); + + it('should return an ApiResponse when data contains a text formula field', function () { + const mockResponseData = { + outputType: 'Text', + values: [], + id: 12060, + appId: 373, + name: 'GetWeekOfYear', + type: 'Formula', + status: 'Enabled', + isRequired: false, + isUnique: false, + }; + + const apiResponse = new ApiResponse(200, 'OK', mockResponseData); + const fieldResponse = apiResponse.asFieldType(); + + expect(fieldResponse).to.be.instanceOf(ApiResponse); + expect(fieldResponse.data).to.be.instanceOf(Field); + expect(fieldResponse.data).to.be.instanceOf(FormulaField); + expect(fieldResponse.data).to.not.be.null; + if (fieldResponse.data != null) { + const formulaField = fieldResponse.data as FormulaField; + expect(formulaField.id).to.equal(12060); + expect(formulaField.appId).to.equal(373); + expect(formulaField.name).to.equal('GetWeekOfYear'); + expect(formulaField.type).to.equal(FieldType.Formula); + expect(formulaField.status).to.equal(FieldStatus.Enabled); + expect(formulaField.isRequired).to.equal(false); + expect(formulaField.isUnique).to.equal(false); + expect(formulaField.outputType).to.equal(FormulaOutputType.Text); + expect(formulaField.values).to.be.instanceOf(Array); + expect(formulaField.values).to.have.lengthOf(0); + } + }); }); describe('asFieldCollectionType', function () { diff --git a/tests/FormulaField.spec.ts b/tests/FormulaField.spec.ts new file mode 100644 index 0000000..47e2f57 --- /dev/null +++ b/tests/FormulaField.spec.ts @@ -0,0 +1,78 @@ +import { FormulaField } from '../src/models/FormulaField'; +import { expect } from 'chai'; + +describe('FormulaField', function () { + it('should be defined', function () { + expect(FormulaField).to.not.be.undefined; + }); + + it('should be a function', function () { + expect(FormulaField).to.be.a('function'); + }); + + it('should have a constructor', function () { + expect(FormulaField).to.have.property('constructor'); + }); + + it('should throw an error if the outputType is not a valid FormulaOutputType', function () { + expect( + () => + new FormulaField( + 1, + 1, + 'Formula Field', + 'Formula', + 'Enabled', + false, + false, + 'NotAType', + [] + ) + ).to.throw(); + }); + + it('should create a new FormulaField', function () { + const formulaField = new FormulaField( + 1, + 1, + 'Formula Field', + 'Formula', + 'Enabled', + false, + false, + 'Text', + [] + ); + expect(formulaField).to.be.an.instanceOf(FormulaField); + }); + + it('should have a outputType property', function () { + const formulaField = new FormulaField( + 1, + 1, + 'Formula Field', + 'Formula', + 'Enabled', + false, + false, + 'Text', + [] + ); + expect(formulaField).to.have.property('outputType'); + }); + + it('should have a values property', function () { + const formulaField = new FormulaField( + 1, + 1, + 'Formula Field', + 'Formula', + 'Enabled', + false, + false, + 'Text', + [] + ); + expect(formulaField).to.have.property('values'); + }); +}); diff --git a/tests/ListField.spec.ts b/tests/ListField.spec.ts new file mode 100644 index 0000000..ed2a725 --- /dev/null +++ b/tests/ListField.spec.ts @@ -0,0 +1,98 @@ +import { ListField } from '../src/models/ListField'; +import { expect } from 'chai'; + +describe('ListField', function () { + it('should be defined', function () { + expect(ListField).to.not.be.undefined; + }); + + it('should be a function', function () { + expect(ListField).to.be.a('function'); + }); + + it('should have a constructor', function () { + expect(ListField).to.have.property('constructor'); + }); + + it('should throw an error if the multiplicity is not valid', function () { + expect( + () => + new ListField( + 1, + 1, + 'List Field', + 'List', + 'Enabled', + false, + false, + 'Alone', + 1, + [] + ) + ).to.throw(); + }); + + it('should create a new ListField', function () { + const listField = new ListField( + 1, + 1, + 'List Field', + 'List', + 'Enabled', + false, + false, + 'SingleSelect', + 1, + [] + ); + expect(listField).to.be.an.instanceOf(ListField); + }); + + it('should have a multiplicity property', function () { + const listField = new ListField( + 1, + 1, + 'List Field', + 'List', + 'Enabled', + false, + false, + 'SingleSelect', + 1, + [] + ); + expect(listField).to.have.property('multiplicity'); + }); + + it('should have a listId property', function () { + const listField = new ListField( + 1, + 1, + 'List Field', + 'List', + 'Enabled', + false, + false, + 'SingleSelect', + 1, + [] + ); + expect(listField).to.have.property('listId'); + }); + + it('should have a values property', function () { + const listField = new ListField( + 1, + 1, + 'List Field', + 'List', + 'Enabled', + false, + false, + 'SingleSelect', + 1, + [] + ); + expect(listField).to.have.property('values'); + }); +}); diff --git a/tests/ListValue.spec.ts b/tests/ListValue.spec.ts new file mode 100644 index 0000000..35e79a8 --- /dev/null +++ b/tests/ListValue.spec.ts @@ -0,0 +1,46 @@ +import { ListValue } from '../src/models/ListValue'; +import { expect } from 'chai'; + +describe('ListValue', function () { + it('should be defined', function () { + expect(ListValue).to.not.be.undefined; + }); + + it('should be a function', function () { + expect(ListValue).to.be.a('function'); + }); + + it('should have a constructor', function () { + expect(ListValue).to.have.property('constructor'); + }); + + it('should create a new ListValue', function () { + const listValue = new ListValue('1', 'List Value', 1, 1, 'red'); + expect(listValue).to.be.an.instanceOf(ListValue); + }); + + it('should have an id property', function () { + const listValue = new ListValue('1', 'List Value', 1, 1, 'red'); + expect(listValue).to.have.property('id'); + }); + + it('should have a name property', function () { + const listValue = new ListValue('1', 'List Value', 1, 1, 'red'); + expect(listValue).to.have.property('name'); + }); + + it('should have a sortOrder property', function () { + const listValue = new ListValue('1', 'List Value', 1, 1, 'red'); + expect(listValue).to.have.property('sortOrder'); + }); + + it('should have a numericValue property', function () { + const listValue = new ListValue('1', 'List Value', 1, 1, 'red'); + expect(listValue).to.have.property('numericValue'); + }); + + it('should have a color property', function () { + const listValue = new ListValue('1', 'List Value', 1, 1, 'red'); + expect(listValue).to.have.property('color'); + }); +}); diff --git a/tests/ReferenceField.spec.ts b/tests/ReferenceField.spec.ts new file mode 100644 index 0000000..859d33b --- /dev/null +++ b/tests/ReferenceField.spec.ts @@ -0,0 +1,78 @@ +import { ReferenceField } from '../src/models/ReferenceField'; +import { expect } from 'chai'; + +describe('ReferenceField', function () { + it('should be defined', function () { + expect(ReferenceField).to.not.be.undefined; + }); + + it('should be a function', function () { + expect(ReferenceField).to.be.a('function'); + }); + + it('should have a constructor', function () { + expect(ReferenceField).to.have.property('constructor'); + }); + + it('should throw an error if the multiplicity is not valid', function () { + expect( + () => + new ReferenceField( + 1, + 1, + 'Reference Field', + 'Reference', + 'Enabled', + false, + false, + 'Alone', + 1 + ) + ).to.throw(); + }); + + it('should create a new ReferenceField', function () { + const referenceField = new ReferenceField( + 1, + 1, + 'Reference Field', + 'Reference', + 'Enabled', + false, + false, + 'SingleSelect', + 1 + ); + expect(referenceField).to.be.an.instanceOf(ReferenceField); + }); + + it('should have a multiplicity property', function () { + const referenceField = new ReferenceField( + 1, + 1, + 'Reference Field', + 'Reference', + 'Enabled', + false, + false, + 'SingleSelect', + 1 + ); + expect(referenceField).to.have.property('multiplicity'); + }); + + it('should have a referencedAppId property', function () { + const referenceField = new ReferenceField( + 1, + 1, + 'Reference Field', + 'Reference', + 'Enabled', + false, + false, + 'SingleSelect', + 1 + ); + expect(referenceField).to.have.property('referencedAppId'); + }); +});