src/app/common/util.service.spec.ts
import should from 'should';
import { utilService } from '../../dependencies';
/**
* Globals
*/
// eslint-disable-next-line @typescript-eslint/no-empty-function
const emptyFn = () => {};
/**
* Unit tests
*/
describe('Utils:', () => {
describe('toMongoose:', () => {
it('should convert $date : {""} to new Date("")', () => {
const input = {
hello: {
there: 'you are',
when: [{}, { something: 0 }, { $date: '2015-01-01T00:00:00.000Z' }]
},
date: { $date: '2015-07-01T00:00:00.000Z' }
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const output = utilService.toMongoose(input) as any;
output.hello.should.be.a.Object();
output.hello.there.should.equal('you are');
output.hello.when.should.be.a.Array();
output.hello.when.length.should.equal(3);
output.hello.when[0].should.be.a.Object();
output.hello.when[1].something.should.equal(0);
output.hello.when[2].getTime().should.equal(1420070400000);
output.date.getTime().should.equal(1435708800000);
});
it('should convert $obj : {""} to new mongoose.Types.ObjectId("")', () => {
const input = {
hello: {
there: 'you are',
when: [{}, { something: 0 }, { $obj: '000000000000000000000000' }]
},
obj: { $obj: '000000000000000000000001' }
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const output = utilService.toMongoose(input) as any;
output.hello.should.be.a.Object();
output.hello.there.should.equal('you are');
output.hello.when.should.be.a.Array();
output.hello.when.length.should.equal(3);
output.hello.when[0].should.be.a.Object();
output.hello.when[1].something.should.equal(0);
output.hello.when[2]._bsontype.should.equal('ObjectId');
output.hello.when[2]
.toHexString()
.should.equal('000000000000000000000000');
output.obj._bsontype.should.equal('ObjectId');
output.obj.toHexString().should.equal('000000000000000000000001');
});
});
describe('Date Parse:', () => {
it('returns null if null', () => {
should.equal(utilService.dateParse(null), null);
});
it('returns null if undefined', () => {
should.equal(utilService.dateParse(undefined), null);
});
it('returns null if object', () => {
should.equal(utilService.dateParse({ test: 'test' }), null);
});
it('returns null if array', () => {
should.equal(utilService.dateParse([]), null);
});
it('returns null if function', () => {
should.equal(utilService.dateParse(emptyFn), null);
});
it('returns number if number', () => {
should.equal(utilService.dateParse(0), 0);
should.equal(utilService.dateParse(12345), 12345);
should.equal(utilService.dateParse(-12345), -12345);
});
it('returns number if string is a number', () => {
should.equal(utilService.dateParse('0'), 0);
should.equal(utilService.dateParse('12345'), 12345);
should.equal(utilService.dateParse('-12345'), -12345);
});
it('returns null if string is bad', () => {
should.equal(utilService.dateParse('2017-0000000000000'), null);
should.equal(utilService.dateParse('Hello'), null);
});
it('returns number if string is a date', () => {
should.equal(utilService.dateParse('1970-01-01'), 0);
should.equal(utilService.dateParse('1970-01-01T00:00:00.000Z'), 0);
should.equal(
utilService.dateParse('2017-06-19T20:41:45.000Z'),
1497904905000
);
});
it('returns number if date', () => {
should.equal(utilService.dateParse(new Date(0)), 0);
should.equal(utilService.dateParse(new Date(12345)), 12345);
const now = new Date();
should.equal(utilService.dateParse(now), now.getTime());
});
});
describe('getPage:', () => {
[
{
input: null,
expected: 0,
name: 'should handle null values with default 0'
},
{
input: 6,
expected: 0,
name: 'should handle number inputs with default 0'
},
{
input: 'test',
expected: 0,
name: 'should handle string inputs with default 0'
},
{
input: true,
expected: 0,
name: 'should handle boolean inputs with default 0'
},
{
input: { limit: 50 },
expected: 0,
name: 'should handle empty values with default 0'
},
{
input: { page: -5 },
expected: 0,
name: 'should return 0 for negative values'
},
{
input: { page: 1 },
expected: 1,
name: 'should return value for positive input'
},
{
input: { page: 'first' },
expected: 0,
name: 'should return default value 0 for string'
},
{
input: { page: 10000000 },
expected: 10000000,
name: 'should return large, positive input'
}
].forEach((test) => {
it(test.name, () => {
const actual = utilService.getPage(test.input);
should(actual).equal(test.expected);
});
});
});
describe('getLimit:', () => {
const defaultLimit = 20,
defaultMax = 100;
[
{
inputQueryParams: null,
expected: defaultLimit,
name: 'should handle null values with default'
},
{
inputQueryParams: {},
expected: defaultLimit,
name: 'should handle empty values with default'
},
{
inputQueryParams: { size: -5 },
expected: 1,
name: 'should return 1 for negative values'
},
{
inputQueryParams: { size: 0 },
expected: 1,
name: 'should return 1 for zero values'
},
{
inputQueryParams: { size: 5 },
expected: 5,
name: 'should return value for positive input'
},
{
inputQueryParams: { size: 'twenty' },
expected: defaultLimit,
name: 'should return default for string'
},
{
inputQueryParams: { size: 10000000 },
expected: defaultMax,
name: 'should cap limit to default max'
},
{
inputQueryParams: { size: 10000000 },
inputMaxSize: 50,
expected: 50,
name: 'should cap limit to input max'
}
].forEach((test) => {
it(test.name, () => {
const actual = utilService.getLimit(
test.inputQueryParams,
test.inputMaxSize
);
should(actual).equal(test.expected);
});
});
});
describe('getSort:', () => {
[
{
input: null,
expected: null,
name: 'should return null for null params '
},
{
input: {},
expected: null,
name: 'should return null for empty params'
}
].forEach((test) => {
it(test.name, () => {
const actual = utilService.getSort(test.input);
should(actual).equal(test.expected);
});
});
[
{
input: { sort: 'field1', dir: 'DESC' },
expected: [{ property: 'field1', direction: 'DESC' }],
name: 'should create sort array from request parameters'
},
{
input: { sort: 'field1' },
expected: [{ property: 'field1', direction: 'ASC' }],
name: 'should use default sort'
},
{
input: { sort: 'field1' },
defaultDir: 'DESC',
expected: [{ property: 'field1', direction: 'DESC' }],
name: 'should use override default dir'
},
{
input: {},
defaultSort: 'field1',
expected: [{ property: 'field1', direction: 'ASC' }],
name: 'should use override default sort'
},
{
input: {},
defaultDir: 'DESC',
defaultSort: 'field1',
expected: [{ property: 'field1', direction: 'DESC' }],
name: 'should use override default sort and dir'
}
].forEach((test) => {
it(test.name, () => {
const actual = utilService.getSort(
test.input,
test.defaultDir,
test.defaultSort
);
should.exist(actual);
actual.should.be.Array();
test.expected.forEach((item, index) => {
item.property.should.equal(actual[index].property);
item.direction.should.equal(actual[index].direction);
});
});
});
});
describe('getSortObj:', () => {
[
{
input: null,
expected: null,
name: 'should return null for null params '
},
{
input: {},
expected: null,
name: 'should return null for empty params'
}
].forEach((test) => {
it(test.name, () => {
const actual = utilService.getSortObj(test.input);
should(actual).equal(test.expected);
});
});
[
{
input: { sort: 'field1', dir: 'DESC' },
expected: { field1: -1 },
name: 'should create sort array from request parameters'
},
{
input: { sort: 'field1' },
expected: { field1: 1 },
name: 'should use default sort'
},
{
input: { sort: 'field1' },
defaultDir: 'DESC',
expected: { field1: -1 },
name: 'should use override default dir'
},
{
input: {},
defaultSort: 'field1',
expected: { field1: 1 },
name: 'should use override default sort'
},
{
input: {},
defaultDir: 'DESC',
defaultSort: 'field1',
expected: { field1: -1 },
name: 'should use override default sort and dir'
},
{
input: {},
defaultDir: 'invalid',
defaultSort: 'field1',
expected: { field1: -1 },
name: 'should default to DESC sort for invalid dir value'
}
].forEach((test) => {
it(test.name, () => {
const actual = utilService.getSortObj(
test.input,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
test.defaultDir,
test.defaultSort
);
should.exist(actual);
actual.should.containEql(test.expected);
});
});
});
describe('contains:', () => {
[
{
inputArray: [1, 2, 3],
inputElement: 2,
expected: true,
name: 'should return true for number in array'
},
{
inputArray: [{ id: 1 }, { id: 2 }, { id: 3 }],
inputElement: { id: 2 },
expected: true,
name: 'should return true for object with same values'
},
{
inputArray: [{ id: 1 }, { id: 2 }, { id: 3 }],
inputElement: { id: 2, name: 'Test' },
expected: false,
name: 'should return false for object with additional attributes'
},
{
inputArray: [false, false, false],
inputElement: false,
expected: true,
name: 'should return true for boolean in array'
},
{
inputArray: [true, false],
inputElement: true,
expected: true,
name: 'should return true for boolean in array'
},
{
inputArray: [true, true],
inputElement: false,
expected: false,
name: 'should return false for boolean not in array'
},
{
inputArray: ['test', 'it', { id: 3 }],
inputElement: 'it',
expected: true,
name: 'should return true for string in array'
},
{
inputArray: ['testing', 'it out', 45, false, { id: 5 }],
inputElement: true,
expected: false,
name: 'should return false for boolean not in array'
}
].forEach((test) => {
it(test.name, () => {
const actual = utilService.contains(test.inputArray, test.inputElement);
should(actual).equal(test.expected);
});
});
});
describe('validateNonEmpty:', () => {
[
{ input: null, expected: false, name: 'should return false for null' },
{
input: undefined,
expected: false,
name: 'should return false for undefined'
},
{
input: emptyFn,
expected: false,
name: 'should return false for function'
},
{ input: {}, expected: false, name: 'should return false for object' },
{
input: [],
expected: false,
name: 'should return false for empty array'
},
{
input: '',
expected: false,
name: 'should return false for empty string'
},
{ input: 'Hello', expected: true, name: 'should return true for string' },
{ input: 1, expected: false, name: 'should return false for number' }
].forEach((test) => {
it(test.name, () => {
const actual = utilService.validateNonEmpty(test.input);
should(actual).equal(test.expected);
});
});
});
describe('getPagingResults:', () => {
[
{
expected: {
pageSize: 20,
pageNumber: 0,
totalSize: 0,
totalPages: 0,
elements: []
},
name: 'should handle undefined values with defaults'
},
{
pageSize: 10,
pageNumber: 10,
totalSize: 0,
elements: [],
expected: {
pageSize: 10,
pageNumber: 0,
totalSize: 0,
totalPages: 0,
elements: []
},
name: 'should set pageNumber to 0 if totalSize is 0'
},
{
pageSize: 10,
pageNumber: 10,
totalSize: 42,
elements: [1, 2],
expected: {
pageSize: 10,
pageNumber: 10,
totalSize: 42,
totalPages: 5,
elements: [1, 2]
},
name: 'should correctly calculate totalPages'
}
].forEach((test) => {
it(test.name, () => {
const actual = utilService.getPagingResults(
test.pageSize,
test.pageNumber,
test.totalSize,
test.elements
);
Object.keys(actual).forEach((key) => {
if (key === 'elements') {
should(actual[key]).containDeep(test.expected[key]);
} else {
should(actual[key]).equal(test.expected[key]);
}
});
});
});
});
describe('removeStringsEndingWithWildcard:', () => {
[
{
input: null,
name: 'should handle null input with default',
expected: {
input: null,
output: []
}
},
{
input: ['foo'],
name: 'should leave original list as is and return empty list if no strings ending in wildcard',
expected: {
input: ['foo'],
output: []
}
},
{
input: ['foo*', 'bar'],
name: 'should remove strings ending with wildcard from input and add them to output list',
expected: {
input: ['bar'],
output: ['foo*']
}
}
].forEach((test) => {
it(test.name, () => {
const actual = utilService.removeStringsEndingWithWildcard(test.input);
should(test.input).containDeep(test.expected.input);
should(actual).containDeep(test.expected.output);
});
});
});
describe('escapeRegex:', () => {
const tests = [
{
input: 'abcdef',
expected: 'abcdef',
description: 'Nothing to escape'
},
{
input: '.?*+^$[]\\(){}|-',
expected: '\\.\\?\\*\\+\\^\\$\\[\\]\\\\\\(\\)\\{\\}\\|\\-',
description: 'All of the characters to escape'
}
];
tests.forEach((test) => {
it(test.description, () => {
const result = utilService.escapeRegex(test.input);
should(result).equal(test.expected);
});
});
});
});