diff --git a/README.md b/README.md index 461bfa84..41ff23b1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Codacy grade](https://img.shields.io/codacy/grade/87f68ffeb2524c1fb0991d544e6afffb)](https://app.codacy.com/gh/cityssm/lot-occupancy-system/dashboard?branch=main) [![Code Climate maintainability](https://img.shields.io/codeclimate/maintainability/cityssm/lot-occupancy-system)](https://codeclimate.com/github/cityssm/lot-occupancy-system) -[![Code Climate coverage](https://img.shields.io/codeclimate/coverage/cityssm/lot-occupancy-system)](https://codeclimate.com/github/cityssm/lot-occupancy-system) +[![codecov](https://codecov.io/gh/cityssm/lot-occupancy-system/branch/main/graph/badge.svg?token=1M38ZVCLKE)](https://codecov.io/gh/cityssm/lot-occupancy-system) [![Snyk Vulnerabilities for GitHub Repo](https://img.shields.io/snyk/vulnerabilities/github/cityssm/lot-occupancy-system)](https://app.snyk.io/org/cityssm/project/ea456d07-9674-4c74-b3d1-1452a8183153) [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/cityssm/lot-occupancy-system/coverage.yml?branch=main)](https://github.com/cityssm/lot-occupancy-system/actions/workflows/coverage.yml) [![lot-occupancy-system](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/simple/xya1fn&style=flat&logo=cypress)](https://dashboard.cypress.io/projects/xya1fn/runs) diff --git a/handlers/workOrders-post/doDeleteWorkOrderLotOccupancy.js b/handlers/workOrders-post/doDeleteWorkOrderLotOccupancy.js index e462e4a8..3fbdd4b1 100644 --- a/handlers/workOrders-post/doDeleteWorkOrderLotOccupancy.js +++ b/handlers/workOrders-post/doDeleteWorkOrderLotOccupancy.js @@ -7,7 +7,9 @@ export async function handler(request, response) { }, { limit: -1, offset: 0, - includeOccupants: true + includeOccupants: true, + includeFees: false, + includeTransactions: false }); response.json({ success, diff --git a/handlers/workOrders-post/doDeleteWorkOrderLotOccupancy.ts b/handlers/workOrders-post/doDeleteWorkOrderLotOccupancy.ts index eab0fffe..ed53d2da 100644 --- a/handlers/workOrders-post/doDeleteWorkOrderLotOccupancy.ts +++ b/handlers/workOrders-post/doDeleteWorkOrderLotOccupancy.ts @@ -17,7 +17,9 @@ export async function handler(request: Request, response: Response): Promise; export declare function getWorkOrderTypeById(workOrderTypeId: number): Promise; export declare function getWorkOrderMilestoneTypes(): Promise; -export declare function getWorkOrderMilestoneTypeByWorkOrderMilestoneTypeId(workOrderMilestoneTypeId: number): Promise; +export declare function getWorkOrderMilestoneTypeById(workOrderMilestoneTypeId: number): Promise; export declare function getWorkOrderMilestoneTypeByWorkOrderMilestoneType(workOrderMilestoneTypeString: string): Promise; export declare function clearCacheByTableName(tableName: string): void; diff --git a/helpers/functions.cache.js b/helpers/functions.cache.js index 0d0cc9b5..ff225f3b 100644 --- a/helpers/functions.cache.js +++ b/helpers/functions.cache.js @@ -142,7 +142,7 @@ export async function getWorkOrderMilestoneTypes() { } return workOrderMilestoneTypes; } -export async function getWorkOrderMilestoneTypeByWorkOrderMilestoneTypeId(workOrderMilestoneTypeId) { +export async function getWorkOrderMilestoneTypeById(workOrderMilestoneTypeId) { const cachedWorkOrderMilestoneTypes = await getWorkOrderMilestoneTypes(); return cachedWorkOrderMilestoneTypes.find((currentWorkOrderMilestoneType) => { return (currentWorkOrderMilestoneType.workOrderMilestoneTypeId === diff --git a/helpers/functions.cache.ts b/helpers/functions.cache.ts index 1846491b..2bbb64cd 100644 --- a/helpers/functions.cache.ts +++ b/helpers/functions.cache.ts @@ -263,7 +263,7 @@ export async function getWorkOrderMilestoneTypes(): Promise< return workOrderMilestoneTypes } -export async function getWorkOrderMilestoneTypeByWorkOrderMilestoneTypeId( +export async function getWorkOrderMilestoneTypeById( workOrderMilestoneTypeId: number ): Promise { const cachedWorkOrderMilestoneTypes = await getWorkOrderMilestoneTypes() diff --git a/helpers/lotOccupancyDB/getWorkOrder.js b/helpers/lotOccupancyDB/getWorkOrder.js index 029310bd..6b4d1e2f 100644 --- a/helpers/lotOccupancyDB/getWorkOrder.js +++ b/helpers/lotOccupancyDB/getWorkOrder.js @@ -33,7 +33,9 @@ async function _getWorkOrder(sql, workOrderIdOrWorkOrderNumber, options, connect }, { limit: -1, offset: 0, - includeOccupants: true + includeOccupants: true, + includeFees: false, + includeTransactions: false }, database); workOrder.workOrderLotOccupancies = workOrderLotOccupanciesResults.lotOccupancies; diff --git a/helpers/lotOccupancyDB/getWorkOrder.ts b/helpers/lotOccupancyDB/getWorkOrder.ts index ba768f2f..56d1c4fb 100644 --- a/helpers/lotOccupancyDB/getWorkOrder.ts +++ b/helpers/lotOccupancyDB/getWorkOrder.ts @@ -65,7 +65,9 @@ async function _getWorkOrder( { limit: -1, offset: 0, - includeOccupants: true + includeOccupants: true, + includeFees: false, + includeTransactions: false }, database ) diff --git a/helpers/lotOccupancyDB/getWorkOrderMilestones.js b/helpers/lotOccupancyDB/getWorkOrderMilestones.js index d289374f..0434c603 100644 --- a/helpers/lotOccupancyDB/getWorkOrderMilestones.js +++ b/helpers/lotOccupancyDB/getWorkOrderMilestones.js @@ -115,7 +115,9 @@ export async function getWorkOrderMilestones(filters, options, connectedDatabase }, { limit: -1, offset: 0, - includeOccupants: true + includeOccupants: true, + includeFees: false, + includeTransactions: false }, database); workOrderMilestone.workOrderLotOccupancies = lotOccupancies.lotOccupancies; } diff --git a/helpers/lotOccupancyDB/getWorkOrderMilestones.ts b/helpers/lotOccupancyDB/getWorkOrderMilestones.ts index e121ebf1..385eedc6 100644 --- a/helpers/lotOccupancyDB/getWorkOrderMilestones.ts +++ b/helpers/lotOccupancyDB/getWorkOrderMilestones.ts @@ -198,7 +198,9 @@ export async function getWorkOrderMilestones( { limit: -1, offset: 0, - includeOccupants: true + includeOccupants: true, + includeFees: false, + includeTransactions: false }, database ) diff --git a/helpers/lotOccupancyDB/getWorkOrders.js b/helpers/lotOccupancyDB/getWorkOrders.js index 6650f834..21c7d2bb 100644 --- a/helpers/lotOccupancyDB/getWorkOrders.js +++ b/helpers/lotOccupancyDB/getWorkOrders.js @@ -108,7 +108,9 @@ export async function getWorkOrders(filters, options, connectedDatabase) { }, { limit: -1, offset: 0, - includeOccupants: true + includeOccupants: true, + includeFees: false, + includeTransactions: false }, database); workOrder.workOrderLotOccupancies = lotOccupancies.lotOccupancies; } diff --git a/helpers/lotOccupancyDB/getWorkOrders.ts b/helpers/lotOccupancyDB/getWorkOrders.ts index dbedbed3..10dd6704 100644 --- a/helpers/lotOccupancyDB/getWorkOrders.ts +++ b/helpers/lotOccupancyDB/getWorkOrders.ts @@ -180,7 +180,9 @@ export async function getWorkOrders( { limit: -1, offset: 0, - includeOccupants: true + includeOccupants: true, + includeFees: false, + includeTransactions: false }, database ) diff --git a/temp/legacy.importFromCSV.js b/temp/legacy.importFromCSV.js index 985982dd..13b81694 100644 --- a/temp/legacy.importFromCSV.js +++ b/temp/legacy.importFromCSV.js @@ -457,6 +457,8 @@ async function importFromPrepaidCSV() { occupancyStartDateString }, { includeOccupants: false, + includeFees: false, + includeTransactions: false, limit: -1, offset: 0 }); diff --git a/temp/legacy.importFromCSV.ts b/temp/legacy.importFromCSV.ts index c058d12f..7c95a702 100644 --- a/temp/legacy.importFromCSV.ts +++ b/temp/legacy.importFromCSV.ts @@ -882,6 +882,8 @@ async function importFromPrepaidCSV(): Promise { }, { includeOccupants: false, + includeFees: false, + includeTransactions: false, limit: -1, offset: 0 } diff --git a/test/functions.js b/test/functions.js index b6840188..aae05a0f 100644 --- a/test/functions.js +++ b/test/functions.js @@ -1,8 +1,212 @@ import * as assert from 'node:assert'; import fs from 'node:fs'; -import * as userFunctions from '../helpers/functions.user.js'; -import * as sqlFilterFunctions from '../helpers/functions.sqlFilters.js'; +import * as cacheFunctions from '../helpers/functions.cache.js'; import * as iconFunctions from '../helpers/functions.icons.js'; +import * as sqlFilterFunctions from '../helpers/functions.sqlFilters.js'; +import * as userFunctions from '../helpers/functions.user.js'; +describe('functions.cache', () => { + const badId = -3; + const badName = 'qwertyuiopasdfghjklzxcvbnm'; + describe('Lot Occupant Types', () => { + it('returns Lot Occupant Types', async () => { + cacheFunctions.clearCacheByTableName('LotOccupantTypes'); + const lotOccupantTypes = await cacheFunctions.getLotOccupantTypes(); + assert.ok(lotOccupantTypes.length > 0); + for (const lotOccupantType of lotOccupantTypes) { + const byId = await cacheFunctions.getLotOccupantTypeById(lotOccupantType.lotOccupantTypeId); + assert.strictEqual(lotOccupantType.lotOccupantTypeId, byId?.lotOccupantTypeId); + const byName = await cacheFunctions.getLotOccupantTypeByLotOccupantType(lotOccupantType.lotOccupantType); + assert.strictEqual(lotOccupantType.lotOccupantType, byName?.lotOccupantType); + } + }); + it('returns undefined with a bad lotOccupantTypeId', async () => { + const byBadId = await cacheFunctions.getLotOccupantTypeById(badId); + assert.ok(byBadId === undefined); + }); + it('returns undefined with a bad lotOccupantType', async () => { + const byBadName = await cacheFunctions.getLotOccupantTypeByLotOccupantType(badName); + assert.ok(byBadName === undefined); + }); + }); + describe('Lot Statuses', () => { + it('returns Lot Statuses', async () => { + cacheFunctions.clearCacheByTableName('LotStatuses'); + const lotStatuses = await cacheFunctions.getLotStatuses(); + assert.ok(lotStatuses.length > 0); + for (const lotStatus of lotStatuses) { + const byId = await cacheFunctions.getLotStatusById(lotStatus.lotStatusId); + assert.strictEqual(lotStatus.lotStatusId, byId?.lotStatusId); + const byName = await cacheFunctions.getLotStatusByLotStatus(lotStatus.lotStatus); + assert.strictEqual(lotStatus.lotStatus, byName?.lotStatus); + } + }); + it('returns undefined with a bad lotStatusId', async () => { + const byBadId = await cacheFunctions.getLotStatusById(badId); + assert.ok(byBadId === undefined); + }); + it('returns undefined with a bad lotStatus', async () => { + const byBadName = await cacheFunctions.getLotStatusByLotStatus(badName); + assert.ok(byBadName === undefined); + }); + }); + describe('Lot Types', () => { + it('returns Lot Types', async () => { + cacheFunctions.clearCacheByTableName('LotTypes'); + const lotTypes = await cacheFunctions.getLotTypes(); + assert.ok(lotTypes.length > 0); + for (const lotType of lotTypes) { + const byId = await cacheFunctions.getLotTypeById(lotType.lotTypeId); + assert.strictEqual(lotType.lotTypeId, byId?.lotTypeId); + const byName = await cacheFunctions.getLotTypesByLotType(lotType.lotType); + assert.strictEqual(lotType.lotType, byName?.lotType); + } + }); + it('returns undefined with a bad lotTypeId', async () => { + const byBadId = await cacheFunctions.getLotTypeById(badId); + assert.ok(byBadId === undefined); + }); + it('returns undefined with a bad lotType', async () => { + const byBadName = await cacheFunctions.getLotTypesByLotType(badName); + assert.ok(byBadName === undefined); + }); + }); + describe('Occupancy Types', () => { + it('returns Occupancy Types', async () => { + cacheFunctions.clearCacheByTableName('OccupancyTypes'); + const occupancyTypes = await cacheFunctions.getOccupancyTypes(); + assert.ok(occupancyTypes.length > 0); + for (const occupancyType of occupancyTypes) { + const byId = await cacheFunctions.getOccupancyTypeById(occupancyType.occupancyTypeId); + assert.strictEqual(occupancyType.occupancyTypeId, byId?.occupancyTypeId); + const byName = await cacheFunctions.getOccupancyTypeByOccupancyType(occupancyType.occupancyType); + assert.strictEqual(occupancyType.occupancyType, byName?.occupancyType); + } + }); + it('returns undefined with a bad occupancyTypeId', async () => { + const byBadId = await cacheFunctions.getOccupancyTypeById(badId); + assert.ok(byBadId === undefined); + }); + it('returns undefined with a bad occupancyType', async () => { + const byBadName = await cacheFunctions.getOccupancyTypeByOccupancyType(badName); + assert.ok(byBadName === undefined); + }); + }); + describe('Work Order Types', () => { + it('returns Work Order Types', async () => { + cacheFunctions.clearCacheByTableName('WorkOrderTypes'); + const workOrderTypes = await cacheFunctions.getWorkOrderTypes(); + assert.ok(workOrderTypes.length > 0); + for (const workOrderType of workOrderTypes) { + const byId = await cacheFunctions.getWorkOrderTypeById(workOrderType.workOrderTypeId); + assert.strictEqual(workOrderType.workOrderTypeId, byId?.workOrderTypeId); + } + }); + it('returns undefined with a bad workOrderTypeId', async () => { + const byBadId = await cacheFunctions.getWorkOrderTypeById(badId); + assert.ok(byBadId === undefined); + }); + }); + describe('Work Order Milestone Types', () => { + it('returns Work Order Milestone Types', async () => { + cacheFunctions.clearCacheByTableName('WorkOrderMilestoneTypes'); + const workOrderMilestoneTypes = await cacheFunctions.getWorkOrderMilestoneTypes(); + assert.ok(workOrderMilestoneTypes.length > 0); + for (const workOrderMilestoneType of workOrderMilestoneTypes) { + const byId = await cacheFunctions.getWorkOrderMilestoneTypeById(workOrderMilestoneType.workOrderMilestoneTypeId); + assert.strictEqual(workOrderMilestoneType.workOrderMilestoneTypeId, byId?.workOrderMilestoneTypeId); + const byName = await cacheFunctions.getWorkOrderMilestoneTypeByWorkOrderMilestoneType(workOrderMilestoneType.workOrderMilestoneType); + assert.strictEqual(workOrderMilestoneType.workOrderMilestoneType, byName?.workOrderMilestoneType); + } + }); + it('returns undefined with a bad workOrderMilestoneTypeId', async () => { + const byBadId = await cacheFunctions.getWorkOrderMilestoneTypeById(badId); + assert.ok(byBadId === undefined); + }); + it('returns undefined with a bad workOrderMilestoneType', async () => { + const byBadName = await cacheFunctions.getWorkOrderMilestoneTypeByWorkOrderMilestoneType(badName); + assert.ok(byBadName === undefined); + }); + }); +}); +describe('functions.icons', () => { + it('returns a list of icon classes', async () => { + const iconClasses = await iconFunctions.getSolidIconClasses(); + assert.ok(iconClasses.includes('save')); + }); +}); +describe('functions.sqlFilters', () => { + describe('LotName filter', () => { + it('returns startsWith filter', () => { + const filter = sqlFilterFunctions.getLotNameWhereClause('TEST1 TEST2', 'startsWith', 'l'); + assert.strictEqual(filter.sqlWhereClause, " and l.lotName like ? || '%'"); + assert.strictEqual(filter.sqlParameters.length, 1); + assert.ok(filter.sqlParameters.includes('TEST1 TEST2')); + }); + it('returns endsWith filter', () => { + const filter = sqlFilterFunctions.getLotNameWhereClause('TEST1 TEST2', 'endsWith', 'l'); + assert.strictEqual(filter.sqlWhereClause, " and l.lotName like '%' || ?"); + assert.strictEqual(filter.sqlParameters.length, 1); + assert.strictEqual(filter.sqlParameters[0], 'TEST1 TEST2'); + }); + it('returns contains filter', () => { + const filter = sqlFilterFunctions.getLotNameWhereClause('TEST1 TEST2', '', 'l'); + assert.strictEqual(filter.sqlWhereClause, ' and instr(lower(l.lotName), ?) and instr(lower(l.lotName), ?)'); + assert.ok(filter.sqlParameters.includes('test1')); + assert.ok(filter.sqlParameters.includes('test2')); + }); + it('handles empty filter', () => { + const filter = sqlFilterFunctions.getLotNameWhereClause('', ''); + assert.strictEqual(filter.sqlWhereClause, ''); + assert.strictEqual(filter.sqlParameters.length, 0); + }); + it('handles undefined filter', () => { + const filter = sqlFilterFunctions.getLotNameWhereClause(undefined, undefined, 'l'); + assert.strictEqual(filter.sqlWhereClause, ''); + assert.strictEqual(filter.sqlParameters.length, 0); + }); + }); + describe('OccupancyTime filter', () => { + it('creates three different filters', () => { + const currentFilter = sqlFilterFunctions.getOccupancyTimeWhereClause('current'); + assert.notStrictEqual(currentFilter.sqlWhereClause, ''); + const pastFilter = sqlFilterFunctions.getOccupancyTimeWhereClause('past'); + assert.notStrictEqual(pastFilter.sqlWhereClause, ''); + const futureFilter = sqlFilterFunctions.getOccupancyTimeWhereClause('future'); + assert.notStrictEqual(futureFilter, ''); + assert.notStrictEqual(currentFilter.sqlWhereClause, pastFilter.sqlWhereClause); + assert.notStrictEqual(currentFilter.sqlWhereClause, futureFilter.sqlWhereClause); + assert.notStrictEqual(pastFilter.sqlWhereClause, futureFilter.sqlWhereClause); + }); + it('handles empty filter', () => { + const filter = sqlFilterFunctions.getOccupancyTimeWhereClause(''); + assert.strictEqual(filter.sqlWhereClause, ''); + assert.strictEqual(filter.sqlParameters.length, 0); + }); + it('handles undefined filter', () => { + const filter = sqlFilterFunctions.getOccupancyTimeWhereClause(undefined, 'o'); + assert.strictEqual(filter.sqlWhereClause, ''); + assert.strictEqual(filter.sqlParameters.length, 0); + }); + }); + describe('OccupantName filter', () => { + it('returns filter', () => { + const filter = sqlFilterFunctions.getOccupantNameWhereClause('TEST1 TEST2', 'o'); + assert.strictEqual(filter.sqlWhereClause, ' and instr(lower(o.occupantName), ?) and instr(lower(o.occupantName), ?)'); + assert.ok(filter.sqlParameters.includes('test1')); + assert.ok(filter.sqlParameters.includes('test2')); + }); + it('handles empty filter', () => { + const filter = sqlFilterFunctions.getOccupantNameWhereClause(''); + assert.strictEqual(filter.sqlWhereClause, ''); + assert.strictEqual(filter.sqlParameters.length, 0); + }); + it('handles undefined filter', () => { + const filter = sqlFilterFunctions.getOccupantNameWhereClause(undefined, 'o'); + assert.strictEqual(filter.sqlWhereClause, ''); + assert.strictEqual(filter.sqlParameters.length, 0); + }); + }); +}); describe('functions.user', () => { describe('unauthenticated, no user in session', () => { const noUserRequest = { @@ -122,82 +326,3 @@ describe('functions.user', () => { }); }); }); -describe('functions.sqlFilters', () => { - describe('LotName filter', () => { - it('returns startsWith filter', () => { - const filter = sqlFilterFunctions.getLotNameWhereClause('TEST1 TEST2', 'startsWith', 'l'); - assert.strictEqual(filter.sqlWhereClause, " and l.lotName like ? || '%'"); - assert.strictEqual(filter.sqlParameters.length, 1); - assert.ok(filter.sqlParameters.includes('TEST1 TEST2')); - }); - it('returns endsWith filter', () => { - const filter = sqlFilterFunctions.getLotNameWhereClause('TEST1 TEST2', 'endsWith', 'l'); - assert.strictEqual(filter.sqlWhereClause, " and l.lotName like '%' || ?"); - assert.strictEqual(filter.sqlParameters.length, 1); - assert.strictEqual(filter.sqlParameters[0], 'TEST1 TEST2'); - }); - it('returns contains filter', () => { - const filter = sqlFilterFunctions.getLotNameWhereClause('TEST1 TEST2', '', 'l'); - assert.strictEqual(filter.sqlWhereClause, ' and instr(lower(l.lotName), ?) and instr(lower(l.lotName), ?)'); - assert.ok(filter.sqlParameters.includes('test1')); - assert.ok(filter.sqlParameters.includes('test2')); - }); - it('handles empty filter', () => { - const filter = sqlFilterFunctions.getLotNameWhereClause('', ''); - assert.strictEqual(filter.sqlWhereClause, ''); - assert.strictEqual(filter.sqlParameters.length, 0); - }); - it('handles undefined filter', () => { - const filter = sqlFilterFunctions.getLotNameWhereClause(undefined, undefined, 'l'); - assert.strictEqual(filter.sqlWhereClause, ''); - assert.strictEqual(filter.sqlParameters.length, 0); - }); - }); - describe('OccupancyTime filter', () => { - it('creates three different filters', () => { - const currentFilter = sqlFilterFunctions.getOccupancyTimeWhereClause('current'); - assert.notStrictEqual(currentFilter.sqlWhereClause, ''); - const pastFilter = sqlFilterFunctions.getOccupancyTimeWhereClause('past'); - assert.notStrictEqual(pastFilter.sqlWhereClause, ''); - const futureFilter = sqlFilterFunctions.getOccupancyTimeWhereClause('future'); - assert.notStrictEqual(futureFilter, ''); - assert.notStrictEqual(currentFilter.sqlWhereClause, pastFilter.sqlWhereClause); - assert.notStrictEqual(currentFilter.sqlWhereClause, futureFilter.sqlWhereClause); - assert.notStrictEqual(pastFilter.sqlWhereClause, futureFilter.sqlWhereClause); - }); - it('handles empty filter', () => { - const filter = sqlFilterFunctions.getOccupancyTimeWhereClause(''); - assert.strictEqual(filter.sqlWhereClause, ''); - assert.strictEqual(filter.sqlParameters.length, 0); - }); - it('handles undefined filter', () => { - const filter = sqlFilterFunctions.getOccupancyTimeWhereClause(undefined, 'o'); - assert.strictEqual(filter.sqlWhereClause, ''); - assert.strictEqual(filter.sqlParameters.length, 0); - }); - }); - describe('OccupantName filter', () => { - it('returns filter', () => { - const filter = sqlFilterFunctions.getOccupantNameWhereClause('TEST1 TEST2', 'o'); - assert.strictEqual(filter.sqlWhereClause, ' and instr(lower(o.occupantName), ?) and instr(lower(o.occupantName), ?)'); - assert.ok(filter.sqlParameters.includes('test1')); - assert.ok(filter.sqlParameters.includes('test2')); - }); - it('handles empty filter', () => { - const filter = sqlFilterFunctions.getOccupantNameWhereClause(''); - assert.strictEqual(filter.sqlWhereClause, ''); - assert.strictEqual(filter.sqlParameters.length, 0); - }); - it('handles undefined filter', () => { - const filter = sqlFilterFunctions.getOccupantNameWhereClause(undefined, 'o'); - assert.strictEqual(filter.sqlWhereClause, ''); - assert.strictEqual(filter.sqlParameters.length, 0); - }); - }); -}); -describe('functions.icons', () => { - it('returns a list of icon classes', async () => { - const iconClasses = await iconFunctions.getSolidIconClasses(); - assert.ok(iconClasses.includes('save')); - }); -}); diff --git a/test/functions.ts b/test/functions.ts index 500363ac..622849e5 100644 --- a/test/functions.ts +++ b/test/functions.ts @@ -2,9 +2,361 @@ import * as assert from 'node:assert' import fs from 'node:fs' -import * as userFunctions from '../helpers/functions.user.js' -import * as sqlFilterFunctions from '../helpers/functions.sqlFilters.js' +import * as cacheFunctions from '../helpers/functions.cache.js' import * as iconFunctions from '../helpers/functions.icons.js' +import * as sqlFilterFunctions from '../helpers/functions.sqlFilters.js' +import * as userFunctions from '../helpers/functions.user.js' + +describe('functions.cache', () => { + const badId = -3 + const badName = 'qwertyuiopasdfghjklzxcvbnm' + + describe('Lot Occupant Types', () => { + it('returns Lot Occupant Types', async () => { + cacheFunctions.clearCacheByTableName('LotOccupantTypes') + + const lotOccupantTypes = await cacheFunctions.getLotOccupantTypes() + + assert.ok(lotOccupantTypes.length > 0) + + for (const lotOccupantType of lotOccupantTypes) { + const byId = await cacheFunctions.getLotOccupantTypeById( + lotOccupantType.lotOccupantTypeId + ) + assert.strictEqual( + lotOccupantType.lotOccupantTypeId, + byId?.lotOccupantTypeId + ) + + const byName = await cacheFunctions.getLotOccupantTypeByLotOccupantType( + lotOccupantType.lotOccupantType + ) + assert.strictEqual( + lotOccupantType.lotOccupantType, + byName?.lotOccupantType + ) + } + }) + + it('returns undefined with a bad lotOccupantTypeId', async () => { + const byBadId = await cacheFunctions.getLotOccupantTypeById(badId) + assert.ok(byBadId === undefined) + }) + + it('returns undefined with a bad lotOccupantType', async () => { + const byBadName = + await cacheFunctions.getLotOccupantTypeByLotOccupantType(badName) + assert.ok(byBadName === undefined) + }) + }) + + describe('Lot Statuses', () => { + it('returns Lot Statuses', async () => { + cacheFunctions.clearCacheByTableName('LotStatuses') + + const lotStatuses = await cacheFunctions.getLotStatuses() + + assert.ok(lotStatuses.length > 0) + + for (const lotStatus of lotStatuses) { + const byId = await cacheFunctions.getLotStatusById( + lotStatus.lotStatusId + ) + assert.strictEqual(lotStatus.lotStatusId, byId?.lotStatusId) + + const byName = await cacheFunctions.getLotStatusByLotStatus( + lotStatus.lotStatus + ) + assert.strictEqual(lotStatus.lotStatus, byName?.lotStatus) + } + }) + + it('returns undefined with a bad lotStatusId', async () => { + const byBadId = await cacheFunctions.getLotStatusById(badId) + assert.ok(byBadId === undefined) + }) + + it('returns undefined with a bad lotStatus', async () => { + const byBadName = await cacheFunctions.getLotStatusByLotStatus(badName) + assert.ok(byBadName === undefined) + }) + }) + + describe('Lot Types', () => { + it('returns Lot Types', async () => { + cacheFunctions.clearCacheByTableName('LotTypes') + + const lotTypes = await cacheFunctions.getLotTypes() + + assert.ok(lotTypes.length > 0) + + for (const lotType of lotTypes) { + const byId = await cacheFunctions.getLotTypeById(lotType.lotTypeId) + assert.strictEqual(lotType.lotTypeId, byId?.lotTypeId) + + const byName = await cacheFunctions.getLotTypesByLotType( + lotType.lotType + ) + assert.strictEqual(lotType.lotType, byName?.lotType) + } + }) + + it('returns undefined with a bad lotTypeId', async () => { + const byBadId = await cacheFunctions.getLotTypeById(badId) + assert.ok(byBadId === undefined) + }) + + it('returns undefined with a bad lotType', async () => { + const byBadName = await cacheFunctions.getLotTypesByLotType(badName) + assert.ok(byBadName === undefined) + }) + }) + + describe('Occupancy Types', () => { + it('returns Occupancy Types', async () => { + cacheFunctions.clearCacheByTableName('OccupancyTypes') + + const occupancyTypes = await cacheFunctions.getOccupancyTypes() + + assert.ok(occupancyTypes.length > 0) + + for (const occupancyType of occupancyTypes) { + const byId = await cacheFunctions.getOccupancyTypeById( + occupancyType.occupancyTypeId + ) + assert.strictEqual(occupancyType.occupancyTypeId, byId?.occupancyTypeId) + + const byName = await cacheFunctions.getOccupancyTypeByOccupancyType( + occupancyType.occupancyType + ) + assert.strictEqual(occupancyType.occupancyType, byName?.occupancyType) + } + }) + + it('returns undefined with a bad occupancyTypeId', async () => { + const byBadId = await cacheFunctions.getOccupancyTypeById(badId) + assert.ok(byBadId === undefined) + }) + + it('returns undefined with a bad occupancyType', async () => { + const byBadName = await cacheFunctions.getOccupancyTypeByOccupancyType( + badName + ) + assert.ok(byBadName === undefined) + }) + }) + + describe('Work Order Types', () => { + it('returns Work Order Types', async () => { + cacheFunctions.clearCacheByTableName('WorkOrderTypes') + + const workOrderTypes = await cacheFunctions.getWorkOrderTypes() + + assert.ok(workOrderTypes.length > 0) + + for (const workOrderType of workOrderTypes) { + const byId = await cacheFunctions.getWorkOrderTypeById( + workOrderType.workOrderTypeId + ) + assert.strictEqual(workOrderType.workOrderTypeId, byId?.workOrderTypeId) + } + }) + + it('returns undefined with a bad workOrderTypeId', async () => { + const byBadId = await cacheFunctions.getWorkOrderTypeById(badId) + assert.ok(byBadId === undefined) + }) + }) + + describe('Work Order Milestone Types', () => { + it('returns Work Order Milestone Types', async () => { + cacheFunctions.clearCacheByTableName('WorkOrderMilestoneTypes') + + const workOrderMilestoneTypes = + await cacheFunctions.getWorkOrderMilestoneTypes() + + assert.ok(workOrderMilestoneTypes.length > 0) + + for (const workOrderMilestoneType of workOrderMilestoneTypes) { + const byId = await cacheFunctions.getWorkOrderMilestoneTypeById( + workOrderMilestoneType.workOrderMilestoneTypeId + ) + assert.strictEqual( + workOrderMilestoneType.workOrderMilestoneTypeId, + byId?.workOrderMilestoneTypeId + ) + + const byName = + await cacheFunctions.getWorkOrderMilestoneTypeByWorkOrderMilestoneType( + workOrderMilestoneType.workOrderMilestoneType + ) + assert.strictEqual( + workOrderMilestoneType.workOrderMilestoneType, + byName?.workOrderMilestoneType + ) + } + }) + + it('returns undefined with a bad workOrderMilestoneTypeId', async () => { + const byBadId = await cacheFunctions.getWorkOrderMilestoneTypeById(badId) + assert.ok(byBadId === undefined) + }) + + it('returns undefined with a bad workOrderMilestoneType', async () => { + const byBadName = + await cacheFunctions.getWorkOrderMilestoneTypeByWorkOrderMilestoneType( + badName + ) + assert.ok(byBadName === undefined) + }) + }) +}) + +describe('functions.icons', () => { + it('returns a list of icon classes', async () => { + const iconClasses = await iconFunctions.getSolidIconClasses() + + assert.ok(iconClasses.includes('save')) + }) +}) + +describe('functions.sqlFilters', () => { + describe('LotName filter', () => { + it('returns startsWith filter', () => { + const filter = sqlFilterFunctions.getLotNameWhereClause( + 'TEST1 TEST2', + 'startsWith', + 'l' + ) + + assert.strictEqual(filter.sqlWhereClause, " and l.lotName like ? || '%'") + assert.strictEqual(filter.sqlParameters.length, 1) + assert.ok(filter.sqlParameters.includes('TEST1 TEST2')) + }) + + it('returns endsWith filter', () => { + const filter = sqlFilterFunctions.getLotNameWhereClause( + 'TEST1 TEST2', + 'endsWith', + 'l' + ) + + assert.strictEqual(filter.sqlWhereClause, " and l.lotName like '%' || ?") + assert.strictEqual(filter.sqlParameters.length, 1) + assert.strictEqual(filter.sqlParameters[0], 'TEST1 TEST2') + }) + + it('returns contains filter', () => { + const filter = sqlFilterFunctions.getLotNameWhereClause( + 'TEST1 TEST2', + '', + 'l' + ) + assert.strictEqual( + filter.sqlWhereClause, + ' and instr(lower(l.lotName), ?) and instr(lower(l.lotName), ?)' + ) + + assert.ok(filter.sqlParameters.includes('test1')) + assert.ok(filter.sqlParameters.includes('test2')) + }) + + it('handles empty filter', () => { + const filter = sqlFilterFunctions.getLotNameWhereClause('', '') + + assert.strictEqual(filter.sqlWhereClause, '') + assert.strictEqual(filter.sqlParameters.length, 0) + }) + + it('handles undefined filter', () => { + const filter = sqlFilterFunctions.getLotNameWhereClause( + undefined, + undefined, + 'l' + ) + + assert.strictEqual(filter.sqlWhereClause, '') + assert.strictEqual(filter.sqlParameters.length, 0) + }) + }) + + describe('OccupancyTime filter', () => { + it('creates three different filters', () => { + const currentFilter = + sqlFilterFunctions.getOccupancyTimeWhereClause('current') + assert.notStrictEqual(currentFilter.sqlWhereClause, '') + + const pastFilter = sqlFilterFunctions.getOccupancyTimeWhereClause('past') + assert.notStrictEqual(pastFilter.sqlWhereClause, '') + + const futureFilter = + sqlFilterFunctions.getOccupancyTimeWhereClause('future') + assert.notStrictEqual(futureFilter, '') + + assert.notStrictEqual( + currentFilter.sqlWhereClause, + pastFilter.sqlWhereClause + ) + assert.notStrictEqual( + currentFilter.sqlWhereClause, + futureFilter.sqlWhereClause + ) + assert.notStrictEqual( + pastFilter.sqlWhereClause, + futureFilter.sqlWhereClause + ) + }) + + it('handles empty filter', () => { + const filter = sqlFilterFunctions.getOccupancyTimeWhereClause('') + assert.strictEqual(filter.sqlWhereClause, '') + assert.strictEqual(filter.sqlParameters.length, 0) + }) + + it('handles undefined filter', () => { + const filter = sqlFilterFunctions.getOccupancyTimeWhereClause( + undefined, + 'o' + ) + assert.strictEqual(filter.sqlWhereClause, '') + assert.strictEqual(filter.sqlParameters.length, 0) + }) + }) + + describe('OccupantName filter', () => { + it('returns filter', () => { + const filter = sqlFilterFunctions.getOccupantNameWhereClause( + 'TEST1 TEST2', + 'o' + ) + + assert.strictEqual( + filter.sqlWhereClause, + ' and instr(lower(o.occupantName), ?) and instr(lower(o.occupantName), ?)' + ) + + assert.ok(filter.sqlParameters.includes('test1')) + assert.ok(filter.sqlParameters.includes('test2')) + }) + + it('handles empty filter', () => { + const filter = sqlFilterFunctions.getOccupantNameWhereClause('') + + assert.strictEqual(filter.sqlWhereClause, '') + assert.strictEqual(filter.sqlParameters.length, 0) + }) + + it('handles undefined filter', () => { + const filter = sqlFilterFunctions.getOccupantNameWhereClause( + undefined, + 'o' + ) + + assert.strictEqual(filter.sqlWhereClause, '') + assert.strictEqual(filter.sqlParameters.length, 0) + }) + }) +}) describe('functions.user', () => { describe('unauthenticated, no user in session', () => { @@ -149,149 +501,3 @@ describe('functions.user', () => { }) }) }) - -describe('functions.sqlFilters', () => { - describe('LotName filter', () => { - it('returns startsWith filter', () => { - const filter = sqlFilterFunctions.getLotNameWhereClause( - 'TEST1 TEST2', - 'startsWith', - 'l' - ) - - assert.strictEqual(filter.sqlWhereClause, " and l.lotName like ? || '%'") - assert.strictEqual(filter.sqlParameters.length, 1) - assert.ok(filter.sqlParameters.includes('TEST1 TEST2')) - }) - - it('returns endsWith filter', () => { - const filter = sqlFilterFunctions.getLotNameWhereClause( - 'TEST1 TEST2', - 'endsWith', - 'l' - ) - - assert.strictEqual(filter.sqlWhereClause, " and l.lotName like '%' || ?") - assert.strictEqual(filter.sqlParameters.length, 1) - assert.strictEqual(filter.sqlParameters[0], 'TEST1 TEST2') - }) - - it('returns contains filter', () => { - const filter = sqlFilterFunctions.getLotNameWhereClause( - 'TEST1 TEST2', - '', - 'l' - ) - assert.strictEqual( - filter.sqlWhereClause, - ' and instr(lower(l.lotName), ?) and instr(lower(l.lotName), ?)' - ) - - assert.ok(filter.sqlParameters.includes('test1')) - assert.ok(filter.sqlParameters.includes('test2')) - }) - - it('handles empty filter', () => { - const filter = sqlFilterFunctions.getLotNameWhereClause('', '') - - assert.strictEqual(filter.sqlWhereClause, '') - assert.strictEqual(filter.sqlParameters.length, 0) - }) - - it('handles undefined filter', () => { - const filter = sqlFilterFunctions.getLotNameWhereClause( - undefined, - undefined, - 'l' - ) - - assert.strictEqual(filter.sqlWhereClause, '') - assert.strictEqual(filter.sqlParameters.length, 0) - }) - }) - - describe('OccupancyTime filter', () => { - it('creates three different filters', () => { - const currentFilter = - sqlFilterFunctions.getOccupancyTimeWhereClause('current') - assert.notStrictEqual(currentFilter.sqlWhereClause, '') - - const pastFilter = sqlFilterFunctions.getOccupancyTimeWhereClause('past') - assert.notStrictEqual(pastFilter.sqlWhereClause, '') - - const futureFilter = - sqlFilterFunctions.getOccupancyTimeWhereClause('future') - assert.notStrictEqual(futureFilter, '') - - assert.notStrictEqual( - currentFilter.sqlWhereClause, - pastFilter.sqlWhereClause - ) - assert.notStrictEqual( - currentFilter.sqlWhereClause, - futureFilter.sqlWhereClause - ) - assert.notStrictEqual( - pastFilter.sqlWhereClause, - futureFilter.sqlWhereClause - ) - }) - - it('handles empty filter', () => { - const filter = sqlFilterFunctions.getOccupancyTimeWhereClause('') - assert.strictEqual(filter.sqlWhereClause, '') - assert.strictEqual(filter.sqlParameters.length, 0) - }) - - it('handles undefined filter', () => { - const filter = sqlFilterFunctions.getOccupancyTimeWhereClause( - undefined, - 'o' - ) - assert.strictEqual(filter.sqlWhereClause, '') - assert.strictEqual(filter.sqlParameters.length, 0) - }) - }) - - describe('OccupantName filter', () => { - it('returns filter', () => { - const filter = sqlFilterFunctions.getOccupantNameWhereClause( - 'TEST1 TEST2', - 'o' - ) - - assert.strictEqual( - filter.sqlWhereClause, - ' and instr(lower(o.occupantName), ?) and instr(lower(o.occupantName), ?)' - ) - - assert.ok(filter.sqlParameters.includes('test1')) - assert.ok(filter.sqlParameters.includes('test2')) - }) - - it('handles empty filter', () => { - const filter = sqlFilterFunctions.getOccupantNameWhereClause('') - - assert.strictEqual(filter.sqlWhereClause, '') - assert.strictEqual(filter.sqlParameters.length, 0) - }) - - it('handles undefined filter', () => { - const filter = sqlFilterFunctions.getOccupantNameWhereClause( - undefined, - 'o' - ) - - assert.strictEqual(filter.sqlWhereClause, '') - assert.strictEqual(filter.sqlParameters.length, 0) - }) - }) -}) - -describe('functions.icons', () => { - it('returns a list of icon classes', async () => { - const iconClasses = await iconFunctions.getSolidIconClasses() - - assert.ok(iconClasses.includes('save')) - }) -}) diff --git a/types/recordTypes.d.ts b/types/recordTypes.d.ts index 29151544..d4e10cea 100644 --- a/types/recordTypes.d.ts +++ b/types/recordTypes.d.ts @@ -202,7 +202,7 @@ export interface LotOccupancy extends Record { workOrders?: WorkOrder[]; } export interface WorkOrderType extends Record { - workOrderTypeId?: number; + workOrderTypeId: number; workOrderType?: string; orderNumber?: number; } diff --git a/types/recordTypes.ts b/types/recordTypes.ts index b94771ab..21d0f0ca 100644 --- a/types/recordTypes.ts +++ b/types/recordTypes.ts @@ -271,7 +271,7 @@ export interface LotOccupancy extends Record { */ export interface WorkOrderType extends Record { - workOrderTypeId?: number + workOrderTypeId: number workOrderType?: string orderNumber?: number }