From 7499002a9dc81f40fd577d355f3a4279ba40fc8c Mon Sep 17 00:00:00 2001 From: Mike Sears Date: Fri, 3 Nov 2023 17:35:03 -0700 Subject: [PATCH 01/21] initial commit --- backend/src/app.module.ts | 2 ++ .../code-table/code-table.controller.spec.ts | 20 +++++++++++++ .../v1/code-table/code-table.controller.ts | 28 +++++++++++++++++++ .../src/v1/code-table/code-table.module.ts | 9 ++++++ .../v1/code-table/code-table.service.spec.ts | 18 ++++++++++++ .../src/v1/code-table/code-table.service.ts | 24 ++++++++++++++++ .../code-table/dto/create-code-table.dto.ts | 1 + .../code-table/dto/update-code-table.dto.ts | 4 +++ .../code-table/entities/code-table.entity.ts | 1 + .../src/v1/code-table/models/code-table.ts | 0 10 files changed, 107 insertions(+) create mode 100644 backend/src/v1/code-table/code-table.controller.spec.ts create mode 100644 backend/src/v1/code-table/code-table.controller.ts create mode 100644 backend/src/v1/code-table/code-table.module.ts create mode 100644 backend/src/v1/code-table/code-table.service.spec.ts create mode 100644 backend/src/v1/code-table/code-table.service.ts create mode 100644 backend/src/v1/code-table/dto/create-code-table.dto.ts create mode 100644 backend/src/v1/code-table/dto/update-code-table.dto.ts create mode 100644 backend/src/v1/code-table/entities/code-table.entity.ts create mode 100644 backend/src/v1/code-table/models/code-table.ts diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index ba7d5d1c4..072936510 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -28,6 +28,7 @@ import { PersonComplaintXrefCodeModule } from "./v1/person_complaint_xref_code/p import { BcGeoCoderModule } from "./external_api/bc_geo_coder/bc_geo_coder.module"; import { ConfigurationModule } from './v1/configuration/configuration.module'; import { ComplaintTypeCodeModule } from "./v1/complaint_type_code/complaint_type_code.module"; +import { CodeTableModule } from './v1/code-table/code-table.module'; console.log("Var check - POSTGRESQL_HOST", process.env.POSTGRESQL_HOST); @@ -78,6 +79,7 @@ if (process.env.POSTGRESQL_PASSWORD != null ){ BcGeoCoderModule, ConfigurationModule, ComplaintTypeCodeModule, + CodeTableModule, ], controllers: [AppController], providers: [AppService], diff --git a/backend/src/v1/code-table/code-table.controller.spec.ts b/backend/src/v1/code-table/code-table.controller.spec.ts new file mode 100644 index 000000000..143395cc7 --- /dev/null +++ b/backend/src/v1/code-table/code-table.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { CodeTableController } from './code-table.controller'; +import { CodeTableService } from './code-table.service'; + +describe('CodeTableController', () => { + let controller: CodeTableController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [CodeTableController], + providers: [CodeTableService], + }).compile(); + + controller = module.get(CodeTableController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/backend/src/v1/code-table/code-table.controller.ts b/backend/src/v1/code-table/code-table.controller.ts new file mode 100644 index 000000000..76c6f7276 --- /dev/null +++ b/backend/src/v1/code-table/code-table.controller.ts @@ -0,0 +1,28 @@ +import { + Controller, + Get, + Post, + Body, + Patch, + Param, + Delete, + UseGuards, +} from "@nestjs/common"; +import { ApiTags } from "@nestjs/swagger"; + +import { CodeTableService } from "./code-table.service"; +import { CreateCodeTableDto } from "./dto/create-code-table.dto"; +import { UpdateCodeTableDto } from "./dto/update-code-table.dto"; +import { JwtRoleGuard } from "src/auth/jwtrole.guard"; + +@UseGuards(JwtRoleGuard) +@ApiTags("code-table") +@Controller({ path: "code-table", version: "1" }) +export class CodeTableController { + constructor(private readonly service: CodeTableService) {} + + @Get() + findAll() { + return this.service.findAll(); + } +} diff --git a/backend/src/v1/code-table/code-table.module.ts b/backend/src/v1/code-table/code-table.module.ts new file mode 100644 index 000000000..2246ae70c --- /dev/null +++ b/backend/src/v1/code-table/code-table.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { CodeTableService } from './code-table.service'; +import { CodeTableController } from './code-table.controller'; + +@Module({ + controllers: [CodeTableController], + providers: [CodeTableService] +}) +export class CodeTableModule {} diff --git a/backend/src/v1/code-table/code-table.service.spec.ts b/backend/src/v1/code-table/code-table.service.spec.ts new file mode 100644 index 000000000..adad9e5df --- /dev/null +++ b/backend/src/v1/code-table/code-table.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { CodeTableService } from './code-table.service'; + +describe('CodeTableService', () => { + let service: CodeTableService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [CodeTableService], + }).compile(); + + service = module.get(CodeTableService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/backend/src/v1/code-table/code-table.service.ts b/backend/src/v1/code-table/code-table.service.ts new file mode 100644 index 000000000..d0c8da3c2 --- /dev/null +++ b/backend/src/v1/code-table/code-table.service.ts @@ -0,0 +1,24 @@ +import { Injectable } from "@nestjs/common"; + +@Injectable() +export class CodeTableService { + findAll() { + return `This action returns all codeTable`; + } + + // create(createCodeTableDto: CreateCodeTableDto) { + // return 'This action adds a new codeTable'; + // } + + // findOne(id: number) { + // return `This action returns a #${id} codeTable`; + // } + + // update(id: number, updateCodeTableDto: UpdateCodeTableDto) { + // return `This action updates a #${id} codeTable`; + // } + + // remove(id: number) { + // return `This action removes a #${id} codeTable`; + // } +} diff --git a/backend/src/v1/code-table/dto/create-code-table.dto.ts b/backend/src/v1/code-table/dto/create-code-table.dto.ts new file mode 100644 index 000000000..103f585e1 --- /dev/null +++ b/backend/src/v1/code-table/dto/create-code-table.dto.ts @@ -0,0 +1 @@ +export class CreateCodeTableDto {} diff --git a/backend/src/v1/code-table/dto/update-code-table.dto.ts b/backend/src/v1/code-table/dto/update-code-table.dto.ts new file mode 100644 index 000000000..38858191f --- /dev/null +++ b/backend/src/v1/code-table/dto/update-code-table.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/swagger'; +import { CreateCodeTableDto } from './create-code-table.dto'; + +export class UpdateCodeTableDto extends PartialType(CreateCodeTableDto) {} diff --git a/backend/src/v1/code-table/entities/code-table.entity.ts b/backend/src/v1/code-table/entities/code-table.entity.ts new file mode 100644 index 000000000..bdfd4301b --- /dev/null +++ b/backend/src/v1/code-table/entities/code-table.entity.ts @@ -0,0 +1 @@ +export class CodeTable {} diff --git a/backend/src/v1/code-table/models/code-table.ts b/backend/src/v1/code-table/models/code-table.ts new file mode 100644 index 000000000..e69de29bb From 7545b079580a1d5ec0c1e71cbc3c8d044a097cab Mon Sep 17 00:00:00 2001 From: Mike Sears Date: Sat, 4 Nov 2023 16:40:56 -0700 Subject: [PATCH 02/21] agency code implemented, service unit test started --- .../src/types/models/code-tables/agency.ts | 5 +++ .../types/models/code-tables/code-table.ts | 6 +++ backend/src/types/models/code-tables/index.ts | 18 ++++++++ .../v1/code-table/code-table.controller.ts | 31 ++++++------- .../src/v1/code-table/code-table.module.ts | 3 ++ .../v1/code-table/code-table.service.spec.ts | 33 +++++++++++--- .../src/v1/code-table/code-table.service.ts | 43 +++++++++++-------- .../code-table/dto/create-code-table.dto.ts | 1 - .../code-table/dto/update-code-table.dto.ts | 4 -- .../code-table/entities/code-table.entity.ts | 1 - .../src/v1/code-table/models/code-table.ts | 0 .../mocks/mock-code-table-repositories.ts | 34 +++++++++++++++ backend/test/mocks/mock-office-repository.ts | 6 --- 13 files changed, 136 insertions(+), 49 deletions(-) create mode 100644 backend/src/types/models/code-tables/agency.ts create mode 100644 backend/src/types/models/code-tables/code-table.ts create mode 100644 backend/src/types/models/code-tables/index.ts delete mode 100644 backend/src/v1/code-table/dto/create-code-table.dto.ts delete mode 100644 backend/src/v1/code-table/dto/update-code-table.dto.ts delete mode 100644 backend/src/v1/code-table/entities/code-table.entity.ts delete mode 100644 backend/src/v1/code-table/models/code-table.ts create mode 100644 backend/test/mocks/mock-code-table-repositories.ts diff --git a/backend/src/types/models/code-tables/agency.ts b/backend/src/types/models/code-tables/agency.ts new file mode 100644 index 000000000..7a06180c9 --- /dev/null +++ b/backend/src/types/models/code-tables/agency.ts @@ -0,0 +1,5 @@ +import { CodeTable } from "../../models/code-tables/code-table"; + +export interface Agency extends CodeTable { + agencyCode: string +} \ No newline at end of file diff --git a/backend/src/types/models/code-tables/code-table.ts b/backend/src/types/models/code-tables/code-table.ts new file mode 100644 index 000000000..6bf46f7a0 --- /dev/null +++ b/backend/src/types/models/code-tables/code-table.ts @@ -0,0 +1,6 @@ +export interface CodeTable { + shortDescription: string; + longDescription: string; + displayOrder: number; + isActive: boolean; +} diff --git a/backend/src/types/models/code-tables/index.ts b/backend/src/types/models/code-tables/index.ts new file mode 100644 index 000000000..7099498ed --- /dev/null +++ b/backend/src/types/models/code-tables/index.ts @@ -0,0 +1,18 @@ +import { CodeTable } from "./code-table"; +import { Agency } from "./agency"; + +export const AvailableCodeTables = [ + "agency", + "attractant", + "complaint-status", + "complaint-type", + "nature-of-complaint", + "organization-unit-type", + "organization-unit", + "person-complaint", + "species", + "violation", +]; + +export default CodeTable; +export { Agency }; diff --git a/backend/src/v1/code-table/code-table.controller.ts b/backend/src/v1/code-table/code-table.controller.ts index 76c6f7276..de038b5fb 100644 --- a/backend/src/v1/code-table/code-table.controller.ts +++ b/backend/src/v1/code-table/code-table.controller.ts @@ -1,19 +1,12 @@ -import { - Controller, - Get, - Post, - Body, - Patch, - Param, - Delete, - UseGuards, -} from "@nestjs/common"; +import { Controller, Get, NotFoundException, Param, UseGuards } from "@nestjs/common"; import { ApiTags } from "@nestjs/swagger"; import { CodeTableService } from "./code-table.service"; -import { CreateCodeTableDto } from "./dto/create-code-table.dto"; -import { UpdateCodeTableDto } from "./dto/update-code-table.dto"; import { JwtRoleGuard } from "src/auth/jwtrole.guard"; +import { Roles } from "src/auth/decorators/roles.decorator"; +import { Role } from "src/enum/role.enum"; +import CodeTable, { AvailableCodeTables } from "../../types/models/code-tables" + @UseGuards(JwtRoleGuard) @ApiTags("code-table") @@ -21,8 +14,16 @@ import { JwtRoleGuard } from "src/auth/jwtrole.guard"; export class CodeTableController { constructor(private readonly service: CodeTableService) {} - @Get() - findAll() { - return this.service.findAll(); + @Get(":table") + @Roles(Role.COS_OFFICER) + async getCodeTableByName( + @Param("table") table: string + ): Promise { + if(!AvailableCodeTables.includes(table)){ + throw new NotFoundException(); + } + + const result = await this.service.getCodeTableByName(table); + return result; } } diff --git a/backend/src/v1/code-table/code-table.module.ts b/backend/src/v1/code-table/code-table.module.ts index 2246ae70c..a49bcef58 100644 --- a/backend/src/v1/code-table/code-table.module.ts +++ b/backend/src/v1/code-table/code-table.module.ts @@ -1,8 +1,11 @@ import { Module } from '@nestjs/common'; import { CodeTableService } from './code-table.service'; import { CodeTableController } from './code-table.controller'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { AgencyCode } from '../agency_code/entities/agency_code.entity'; @Module({ + imports: [TypeOrmModule.forFeature([AgencyCode])], controllers: [CodeTableController], providers: [CodeTableService] }) diff --git a/backend/src/v1/code-table/code-table.service.spec.ts b/backend/src/v1/code-table/code-table.service.spec.ts index adad9e5df..b92dee9d7 100644 --- a/backend/src/v1/code-table/code-table.service.spec.ts +++ b/backend/src/v1/code-table/code-table.service.spec.ts @@ -1,18 +1,41 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { CodeTableService } from './code-table.service'; +import { Test, TestingModule } from "@nestjs/testing"; +import { CodeTableService } from "./code-table.service"; +import { getRepositoryToken } from "@nestjs/typeorm"; +import { AgencyCode } from "../agency_code/entities/agency_code.entity"; -describe('CodeTableService', () => { +import { MockAgencyCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; + +describe("Testing: CodeTable Service", () => { let service: CodeTableService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [CodeTableService], + providers: [ + CodeTableService, + { + provide: getRepositoryToken(AgencyCode), + useFactory: MockAgencyCodeTableRepository, + }, + ], }).compile(); service = module.get(CodeTableService); }); - it('should be defined', () => { + it("should be defined", () => { expect(service).toBeDefined(); }); + + it("should return collection of agency codes", async () => { + //-- arrange + const _tableName = "agency"; + + //-- act + const results = await service.getCodeTableByName(_tableName); + + //-- assert + expect(results).not.toBe(null); + expect(results.length).not.toBe(0); + expect(results.length).toBe(8); + }); }); diff --git a/backend/src/v1/code-table/code-table.service.ts b/backend/src/v1/code-table/code-table.service.ts index d0c8da3c2..4af36ecfc 100644 --- a/backend/src/v1/code-table/code-table.service.ts +++ b/backend/src/v1/code-table/code-table.service.ts @@ -1,24 +1,33 @@ -import { Injectable } from "@nestjs/common"; +import { Injectable, Logger } from "@nestjs/common"; +import CodeTable, { Agency } from "../../types/models/code-tables"; +import { InjectRepository } from "@nestjs/typeorm"; +import { AgencyCode } from "../agency_code/entities/agency_code.entity"; +import { Repository } from "typeorm"; @Injectable() export class CodeTableService { - findAll() { - return `This action returns all codeTable`; - } + private readonly logger = new Logger(CodeTableService.name); - // create(createCodeTableDto: CreateCodeTableDto) { - // return 'This action adds a new codeTable'; - // } + @InjectRepository(AgencyCode) + private _agencyRepository: Repository; - // findOne(id: number) { - // return `This action returns a #${id} codeTable`; - // } + getCodeTableByName = async (table: string): Promise => { + switch (table) { + case "agency": { + const data = await this._agencyRepository.find(); + let results = data.map(({agency_code, short_description, long_description, display_order, active_ind }) => { + let table: Agency = { + agencyCode: agency_code, + shortDescription: short_description, + longDescription: long_description, + displayOrder: display_order, + isActive: active_ind + } + return table + }) - // update(id: number, updateCodeTableDto: UpdateCodeTableDto) { - // return `This action updates a #${id} codeTable`; - // } - - // remove(id: number) { - // return `This action removes a #${id} codeTable`; - // } + return results; + } + } + }; } diff --git a/backend/src/v1/code-table/dto/create-code-table.dto.ts b/backend/src/v1/code-table/dto/create-code-table.dto.ts deleted file mode 100644 index 103f585e1..000000000 --- a/backend/src/v1/code-table/dto/create-code-table.dto.ts +++ /dev/null @@ -1 +0,0 @@ -export class CreateCodeTableDto {} diff --git a/backend/src/v1/code-table/dto/update-code-table.dto.ts b/backend/src/v1/code-table/dto/update-code-table.dto.ts deleted file mode 100644 index 38858191f..000000000 --- a/backend/src/v1/code-table/dto/update-code-table.dto.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { PartialType } from '@nestjs/swagger'; -import { CreateCodeTableDto } from './create-code-table.dto'; - -export class UpdateCodeTableDto extends PartialType(CreateCodeTableDto) {} diff --git a/backend/src/v1/code-table/entities/code-table.entity.ts b/backend/src/v1/code-table/entities/code-table.entity.ts deleted file mode 100644 index bdfd4301b..000000000 --- a/backend/src/v1/code-table/entities/code-table.entity.ts +++ /dev/null @@ -1 +0,0 @@ -export class CodeTable {} diff --git a/backend/src/v1/code-table/models/code-table.ts b/backend/src/v1/code-table/models/code-table.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/backend/test/mocks/mock-code-table-repositories.ts b/backend/test/mocks/mock-code-table-repositories.ts new file mode 100644 index 000000000..ec36772a9 --- /dev/null +++ b/backend/test/mocks/mock-code-table-repositories.ts @@ -0,0 +1,34 @@ +import { randomUUID } from "crypto"; + +const agencyCollection = [ + { "agency_code": "BCWF", "short_description": "BCWF", "long_description": "BC Wildlife Federation", "display_order": 1, "active_ind": true }, + { "agency_code": "BYLAW", "short_description": "Bylaw Enforcement", "long_description": "Bylaw Enforcement", "display_order": 2, "active_ind": true }, + { "agency_code": "COS", "short_description": "COS", "long_description": "Conservation Officer Service", "display_order": 3, "active_ind": true }, + { "agency_code": "DFO", "short_description": "DFO", "long_description": "Department of Fisheries and Oceans", "display_order": 4, "active_ind": true }, + { "agency_code": "EPO", "short_description": "EPO", "long_description": "Environmental Protection Office", "display_order": 5, "active_ind": true }, + { "agency_code": "CEB", "short_description": "FOR", "long_description": "Forestry Compliance and Enforcement Branch", "display_order": 6, "active_ind": true }, + { "agency_code": "LE", "short_description": "Police", "long_description": "Municipal Police or RCMP", "display_order": 7, "active_ind": true }, + { "agency_code": "OTHER", "short_description": "Other", "long_description": "Other", "display_order": 8, "active_ind": true } +] + +const single = (name: string = "default", idx: number = 0): any => { + switch (name) { + case "agency": { + return idx <= agencyCollection.length + ? agencyCollection[idx] + : agencyCollection[0]; + } + case "default": + default: + return null; + } +}; + +export const MockAgencyCodeTableRepository = () => ({ + find: jest.fn().mockResolvedValue(agencyCollection), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(agencyCollection), + })), +}); diff --git a/backend/test/mocks/mock-office-repository.ts b/backend/test/mocks/mock-office-repository.ts index 8867cef89..d164dd441 100644 --- a/backend/test/mocks/mock-office-repository.ts +++ b/backend/test/mocks/mock-office-repository.ts @@ -47,9 +47,3 @@ export const MockOfficeRepository = () => ({ getMany: jest.fn().mockResolvedValue(collection), })), }); - -/* - - - -*/ From 7dc5423fece826cf3b8ed8121eb70d0b4a12087a Mon Sep 17 00:00:00 2001 From: Mike Sears Date: Sat, 4 Nov 2023 16:52:06 -0700 Subject: [PATCH 03/21] code-table controller unit tests created --- .../code-table/code-table.controller.spec.ts | 50 ++++++++++++++++--- .../v1/code-table/code-table.controller.ts | 8 +-- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/backend/src/v1/code-table/code-table.controller.spec.ts b/backend/src/v1/code-table/code-table.controller.spec.ts index 143395cc7..443088e5d 100644 --- a/backend/src/v1/code-table/code-table.controller.spec.ts +++ b/backend/src/v1/code-table/code-table.controller.spec.ts @@ -1,20 +1,56 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { CodeTableController } from './code-table.controller'; -import { CodeTableService } from './code-table.service'; +import { Test, TestingModule } from "@nestjs/testing"; +import { getRepositoryToken } from "@nestjs/typeorm"; +import { INestApplication } from "@nestjs/common"; +import * as request from "supertest"; -describe('CodeTableController', () => { +import { authGuardMock } from "../../../test/mocks/authGuardMock"; +import { roleGuardMock } from "../../../test/mocks/roleGuardMock"; +import { JwtAuthGuard } from "../../auth/jwtauth.guard"; +import { JwtRoleGuard } from "../../auth/jwtrole.guard"; + +import { CodeTableController } from "./code-table.controller"; +import { CodeTableService } from "./code-table.service"; +import { MockAgencyCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; +import { AgencyCode } from "../agency_code/entities/agency_code.entity"; + +describe("Testing: CodeTable Controller", () => { + let app: INestApplication; let controller: CodeTableController; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [CodeTableController], - providers: [CodeTableService], - }).compile(); + providers: [ + CodeTableService, + { + provide: getRepositoryToken(AgencyCode), + useFactory: MockAgencyCodeTableRepository, + }, + ], + }) .overrideGuard(JwtAuthGuard) + .useValue({ authGuardMock }) + .overrideGuard(JwtRoleGuard) + .useValue({ roleGuardMock }) + .compile(); + + app = module.createNestApplication(); + await app.init(); controller = module.get(CodeTableController); }); - it('should be defined', () => { + it("should be defined", () => { expect(controller).toBeDefined(); }); + + it("should return 200 when a GET is called successfully", async () => { + //-- arrange + const _tableName = "agency"; + + //-- act + let response = await request(app.getHttpServer()).get( + `/code-table/${_tableName}` + ); + expect(response.statusCode).toBe(200); + }); }); diff --git a/backend/src/v1/code-table/code-table.controller.ts b/backend/src/v1/code-table/code-table.controller.ts index de038b5fb..688fb637c 100644 --- a/backend/src/v1/code-table/code-table.controller.ts +++ b/backend/src/v1/code-table/code-table.controller.ts @@ -2,11 +2,11 @@ import { Controller, Get, NotFoundException, Param, UseGuards } from "@nestjs/co import { ApiTags } from "@nestjs/swagger"; import { CodeTableService } from "./code-table.service"; -import { JwtRoleGuard } from "src/auth/jwtrole.guard"; -import { Roles } from "src/auth/decorators/roles.decorator"; -import { Role } from "src/enum/role.enum"; -import CodeTable, { AvailableCodeTables } from "../../types/models/code-tables" +import { Role } from '../../enum/role.enum'; +import { Roles } from '../../auth/decorators/roles.decorator'; +import { JwtRoleGuard } from '../../auth/jwtrole.guard'; +import CodeTable, { AvailableCodeTables } from "../../types/models/code-tables" @UseGuards(JwtRoleGuard) @ApiTags("code-table") From eb7b75e6b8916aca8205759753e32e84c676ad8f Mon Sep 17 00:00:00 2001 From: Mike Sears Date: Sat, 4 Nov 2023 16:54:22 -0700 Subject: [PATCH 04/21] added test to check for 404 --- .../src/v1/code-table/code-table.controller.spec.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/backend/src/v1/code-table/code-table.controller.spec.ts b/backend/src/v1/code-table/code-table.controller.spec.ts index 443088e5d..1f13ecdd3 100644 --- a/backend/src/v1/code-table/code-table.controller.spec.ts +++ b/backend/src/v1/code-table/code-table.controller.spec.ts @@ -53,4 +53,15 @@ describe("Testing: CodeTable Controller", () => { ); expect(response.statusCode).toBe(200); }); + + it("should return 404 when a requesting code table that doesn't exist", async () => { + //-- arrange + const _tableName = "test"; + + //-- act + let response = await request(app.getHttpServer()).get( + `/code-table/${_tableName}` + ); + expect(response.statusCode).toBe(404); + }); }); From 06038eadc4ca4401adffbf92ce378922fde01927 Mon Sep 17 00:00:00 2001 From: Mike Sears Date: Sat, 4 Nov 2023 17:18:18 -0700 Subject: [PATCH 05/21] added attractants --- .../types/models/code-tables/attractant.ts | 5 ++ backend/src/types/models/code-tables/index.ts | 3 +- .../code-table/code-table.controller.spec.ts | 7 ++- .../src/v1/code-table/code-table.module.ts | 3 +- .../v1/code-table/code-table.service.spec.ts | 24 +++++++++- .../src/v1/code-table/code-table.service.ts | 48 ++++++++++++++++--- .../mocks/mock-code-table-repositories.ts | 27 +++++++++++ 7 files changed, 106 insertions(+), 11 deletions(-) create mode 100644 backend/src/types/models/code-tables/attractant.ts diff --git a/backend/src/types/models/code-tables/attractant.ts b/backend/src/types/models/code-tables/attractant.ts new file mode 100644 index 000000000..ae8498af9 --- /dev/null +++ b/backend/src/types/models/code-tables/attractant.ts @@ -0,0 +1,5 @@ +import { CodeTable } from "../../models/code-tables/code-table"; + +export interface Attractant extends CodeTable { + attractantCode: string +} \ No newline at end of file diff --git a/backend/src/types/models/code-tables/index.ts b/backend/src/types/models/code-tables/index.ts index 7099498ed..54d4b361f 100644 --- a/backend/src/types/models/code-tables/index.ts +++ b/backend/src/types/models/code-tables/index.ts @@ -1,5 +1,6 @@ import { CodeTable } from "./code-table"; import { Agency } from "./agency"; +import { Attractant } from "./attractant"; export const AvailableCodeTables = [ "agency", @@ -15,4 +16,4 @@ export const AvailableCodeTables = [ ]; export default CodeTable; -export { Agency }; +export { Agency, Attractant }; diff --git a/backend/src/v1/code-table/code-table.controller.spec.ts b/backend/src/v1/code-table/code-table.controller.spec.ts index 1f13ecdd3..62496c079 100644 --- a/backend/src/v1/code-table/code-table.controller.spec.ts +++ b/backend/src/v1/code-table/code-table.controller.spec.ts @@ -10,8 +10,9 @@ import { JwtRoleGuard } from "../../auth/jwtrole.guard"; import { CodeTableController } from "./code-table.controller"; import { CodeTableService } from "./code-table.service"; -import { MockAgencyCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; +import { MockAgencyCodeTableRepository, MockAttractantCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; +import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; describe("Testing: CodeTable Controller", () => { let app: INestApplication; @@ -26,6 +27,10 @@ describe("Testing: CodeTable Controller", () => { provide: getRepositoryToken(AgencyCode), useFactory: MockAgencyCodeTableRepository, }, + { + provide: getRepositoryToken(AttractantCode), + useFactory: MockAttractantCodeTableRepository, + }, ], }) .overrideGuard(JwtAuthGuard) .useValue({ authGuardMock }) diff --git a/backend/src/v1/code-table/code-table.module.ts b/backend/src/v1/code-table/code-table.module.ts index a49bcef58..f9a821ab1 100644 --- a/backend/src/v1/code-table/code-table.module.ts +++ b/backend/src/v1/code-table/code-table.module.ts @@ -3,9 +3,10 @@ import { CodeTableService } from './code-table.service'; import { CodeTableController } from './code-table.controller'; import { TypeOrmModule } from '@nestjs/typeorm'; import { AgencyCode } from '../agency_code/entities/agency_code.entity'; +import { AttractantCode } from '../attractant_code/entities/attractant_code.entity'; @Module({ - imports: [TypeOrmModule.forFeature([AgencyCode])], + imports: [TypeOrmModule.forFeature([AgencyCode]), TypeOrmModule.forFeature([AttractantCode])], controllers: [CodeTableController], providers: [CodeTableService] }) diff --git a/backend/src/v1/code-table/code-table.service.spec.ts b/backend/src/v1/code-table/code-table.service.spec.ts index b92dee9d7..d882b6237 100644 --- a/backend/src/v1/code-table/code-table.service.spec.ts +++ b/backend/src/v1/code-table/code-table.service.spec.ts @@ -3,7 +3,12 @@ import { CodeTableService } from "./code-table.service"; import { getRepositoryToken } from "@nestjs/typeorm"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; -import { MockAgencyCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; +import { + MockAgencyCodeTableRepository, + MockAttractantCodeTableRepository, +} from "../../../test/mocks/mock-code-table-repositories"; + +import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; describe("Testing: CodeTable Service", () => { let service: CodeTableService; @@ -16,6 +21,10 @@ describe("Testing: CodeTable Service", () => { provide: getRepositoryToken(AgencyCode), useFactory: MockAgencyCodeTableRepository, }, + { + provide: getRepositoryToken(AttractantCode), + useFactory: MockAttractantCodeTableRepository, + }, ], }).compile(); @@ -38,4 +47,17 @@ describe("Testing: CodeTable Service", () => { expect(results.length).not.toBe(0); expect(results.length).toBe(8); }); + + it("should return collection of attractants", async () => { + //-- arrange + const _tableName = "attractant"; + + //-- act + const results = await service.getCodeTableByName(_tableName); + + //-- assert + expect(results).not.toBe(null); + expect(results.length).not.toBe(0); + expect(results.length).toBe(8); + }); }); diff --git a/backend/src/v1/code-table/code-table.service.ts b/backend/src/v1/code-table/code-table.service.ts index 4af36ecfc..0e492f433 100644 --- a/backend/src/v1/code-table/code-table.service.ts +++ b/backend/src/v1/code-table/code-table.service.ts @@ -1,33 +1,67 @@ import { Injectable, Logger } from "@nestjs/common"; -import CodeTable, { Agency } from "../../types/models/code-tables"; import { InjectRepository } from "@nestjs/typeorm"; -import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { Repository } from "typeorm"; +import CodeTable, { Agency, Attractant } from "../../types/models/code-tables"; +import { AgencyCode } from "../agency_code/entities/agency_code.entity"; +import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; + @Injectable() export class CodeTableService { private readonly logger = new Logger(CodeTableService.name); @InjectRepository(AgencyCode) private _agencyRepository: Repository; + @InjectRepository(AttractantCode) + private _attractantRepository: Repository; getCodeTableByName = async (table: string): Promise => { switch (table) { case "agency": { const data = await this._agencyRepository.find(); - let results = data.map(({agency_code, short_description, long_description, display_order, active_ind }) => { - let table: Agency = { + let results = data.map( + ({ + agency_code, + short_description, + long_description, + display_order, + active_ind, + }) => { + let table: Agency = { agencyCode: agency_code, shortDescription: short_description, longDescription: long_description, displayOrder: display_order, - isActive: active_ind + isActive: active_ind, + }; + return table; } - return table - }) + ); return results; } + case "attractant": { + const data = await this._attractantRepository.find(); + let results = data.map( + ({ + attractant_code, + short_description, + long_description, + display_order, + active_ind, + }) => { + let table: Attractant = { + attractantCode: attractant_code, + shortDescription: short_description, + longDescription: long_description, + displayOrder: display_order, + isActive: active_ind, + }; + return table; + } + ); + return results; + } } }; } diff --git a/backend/test/mocks/mock-code-table-repositories.ts b/backend/test/mocks/mock-code-table-repositories.ts index ec36772a9..548aad006 100644 --- a/backend/test/mocks/mock-code-table-repositories.ts +++ b/backend/test/mocks/mock-code-table-repositories.ts @@ -11,6 +11,17 @@ const agencyCollection = [ { "agency_code": "OTHER", "short_description": "Other", "long_description": "Other", "display_order": 8, "active_ind": true } ] +const attractants = [ + { "attractantCode": "BEEHIVE", "shortDescription": "Beehive", "longDescription": "Beehive", "displayOrder": 2, "isActive": true}, + { "attractantCode": "BIRD FDR", "shortDescription": "Bird Feeder", "longDescription": "Bird Feeder", "displayOrder": 3, "isActive": true }, + { "attractantCode": "CAMP FD", "shortDescription": "Campground Food", "longDescription": "Campground Food", "displayOrder": 4, "isActive": true }, + { "attractantCode": "COMPOST", "shortDescription": "Compost", "longDescription": "Compost", "displayOrder": 5, "isActive": true }, + { "attractantCode": "CROPS", "shortDescription": "Crops", "longDescription": "Crops", "displayOrder": 6, "isActive": true }, + { "attractantCode": "FREEZER", "shortDescription": "Freezer", "longDescription": "Freezer", "displayOrder": 7, "isActive": true }, + { "attractantCode": "BBQ", "shortDescription": "BBQ", "longDescription": "Barbeque", "displayOrder": 1, "isActive": true }, + { "attractantCode": "RESFRUIT", "shortDescription": "Fruit/Berries", "longDescription": "Residential Fruit/Berries", "displayOrder": 8, "isActive": true } +]; + const single = (name: string = "default", idx: number = 0): any => { switch (name) { case "agency": { @@ -18,6 +29,11 @@ const single = (name: string = "default", idx: number = 0): any => { ? agencyCollection[idx] : agencyCollection[0]; } + case "attractant": { + return idx <= attractants.length + ? attractants[idx] + : attractants[0]; + } case "default": default: return null; @@ -32,3 +48,14 @@ export const MockAgencyCodeTableRepository = () => ({ getMany: jest.fn().mockResolvedValue(agencyCollection), })), }); + + +export const MockAttractantCodeTableRepository = () => ({ + find: jest.fn().mockResolvedValue(attractants), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(attractants), + })), + }); + \ No newline at end of file From 06d927b351e9818db6fe242c02e5aee713132920 Mon Sep 17 00:00:00 2001 From: Mike Sears Date: Sat, 4 Nov 2023 20:28:42 -0700 Subject: [PATCH 06/21] added complaint-type code table --- .../src/types/models/code-tables/agency.ts | 2 +- .../types/models/code-tables/attractant.ts | 2 +- .../models/code-tables/complaint-status.ts | 5 +++ backend/src/types/models/code-tables/index.ts | 6 +++- .../code-table/code-table.controller.spec.ts | 7 +++- .../src/v1/code-table/code-table.module.ts | 21 ++++++----- .../v1/code-table/code-table.service.spec.ts | 22 ++++++++++-- .../src/v1/code-table/code-table.service.ts | 31 ++++++++++++++-- .../mocks/mock-code-table-repositories.ts | 35 +++++++++++++------ 9 files changed, 103 insertions(+), 28 deletions(-) create mode 100644 backend/src/types/models/code-tables/complaint-status.ts diff --git a/backend/src/types/models/code-tables/agency.ts b/backend/src/types/models/code-tables/agency.ts index 7a06180c9..5b7adb539 100644 --- a/backend/src/types/models/code-tables/agency.ts +++ b/backend/src/types/models/code-tables/agency.ts @@ -1,5 +1,5 @@ import { CodeTable } from "../../models/code-tables/code-table"; export interface Agency extends CodeTable { - agencyCode: string + agency: string } \ No newline at end of file diff --git a/backend/src/types/models/code-tables/attractant.ts b/backend/src/types/models/code-tables/attractant.ts index ae8498af9..28f3d0042 100644 --- a/backend/src/types/models/code-tables/attractant.ts +++ b/backend/src/types/models/code-tables/attractant.ts @@ -1,5 +1,5 @@ import { CodeTable } from "../../models/code-tables/code-table"; export interface Attractant extends CodeTable { - attractantCode: string + attractant: string } \ No newline at end of file diff --git a/backend/src/types/models/code-tables/complaint-status.ts b/backend/src/types/models/code-tables/complaint-status.ts new file mode 100644 index 000000000..fa0d39dbe --- /dev/null +++ b/backend/src/types/models/code-tables/complaint-status.ts @@ -0,0 +1,5 @@ +import { CodeTable } from "../../models/code-tables/code-table"; + +export interface ComplaintStatus extends CodeTable { + complaintStatus: string +} \ No newline at end of file diff --git a/backend/src/types/models/code-tables/index.ts b/backend/src/types/models/code-tables/index.ts index 54d4b361f..442be4cb6 100644 --- a/backend/src/types/models/code-tables/index.ts +++ b/backend/src/types/models/code-tables/index.ts @@ -1,6 +1,10 @@ import { CodeTable } from "./code-table"; import { Agency } from "./agency"; import { Attractant } from "./attractant"; +import { ComplaintStatus } from "./complaint-status"; + + + export const AvailableCodeTables = [ "agency", @@ -16,4 +20,4 @@ export const AvailableCodeTables = [ ]; export default CodeTable; -export { Agency, Attractant }; +export { Agency, Attractant, ComplaintStatus }; diff --git a/backend/src/v1/code-table/code-table.controller.spec.ts b/backend/src/v1/code-table/code-table.controller.spec.ts index 62496c079..0f130c2ab 100644 --- a/backend/src/v1/code-table/code-table.controller.spec.ts +++ b/backend/src/v1/code-table/code-table.controller.spec.ts @@ -10,9 +10,10 @@ import { JwtRoleGuard } from "../../auth/jwtrole.guard"; import { CodeTableController } from "./code-table.controller"; import { CodeTableService } from "./code-table.service"; -import { MockAgencyCodeTableRepository, MockAttractantCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; +import { MockAgencyCodeTableRepository, MockAttractantCodeTableRepository, MockComplaintStatusCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; +import { ComplaintStatusCode } from "../complaint_status_code/entities/complaint_status_code.entity"; describe("Testing: CodeTable Controller", () => { let app: INestApplication; @@ -31,6 +32,10 @@ describe("Testing: CodeTable Controller", () => { provide: getRepositoryToken(AttractantCode), useFactory: MockAttractantCodeTableRepository, }, + { + provide: getRepositoryToken(ComplaintStatusCode), + useFactory: MockComplaintStatusCodeTableRepository, + }, ], }) .overrideGuard(JwtAuthGuard) .useValue({ authGuardMock }) diff --git a/backend/src/v1/code-table/code-table.module.ts b/backend/src/v1/code-table/code-table.module.ts index f9a821ab1..221372fbe 100644 --- a/backend/src/v1/code-table/code-table.module.ts +++ b/backend/src/v1/code-table/code-table.module.ts @@ -1,13 +1,18 @@ -import { Module } from '@nestjs/common'; -import { CodeTableService } from './code-table.service'; -import { CodeTableController } from './code-table.controller'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { AgencyCode } from '../agency_code/entities/agency_code.entity'; -import { AttractantCode } from '../attractant_code/entities/attractant_code.entity'; +import { Module } from "@nestjs/common"; +import { CodeTableService } from "./code-table.service"; +import { CodeTableController } from "./code-table.controller"; +import { TypeOrmModule } from "@nestjs/typeorm"; +import { AgencyCode } from "../agency_code/entities/agency_code.entity"; +import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; +import { ComplaintStatusCode } from "../complaint_status_code/entities/complaint_status_code.entity"; @Module({ - imports: [TypeOrmModule.forFeature([AgencyCode]), TypeOrmModule.forFeature([AttractantCode])], + imports: [ + TypeOrmModule.forFeature([AgencyCode]), + TypeOrmModule.forFeature([AttractantCode]), + TypeOrmModule.forFeature([ComplaintStatusCode]), + ], controllers: [CodeTableController], - providers: [CodeTableService] + providers: [CodeTableService], }) export class CodeTableModule {} diff --git a/backend/src/v1/code-table/code-table.service.spec.ts b/backend/src/v1/code-table/code-table.service.spec.ts index d882b6237..7ba57ab59 100644 --- a/backend/src/v1/code-table/code-table.service.spec.ts +++ b/backend/src/v1/code-table/code-table.service.spec.ts @@ -2,14 +2,15 @@ import { Test, TestingModule } from "@nestjs/testing"; import { CodeTableService } from "./code-table.service"; import { getRepositoryToken } from "@nestjs/typeorm"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; +import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; +import { ComplaintStatusCode } from "../complaint_status_code/entities/complaint_status_code.entity"; import { MockAgencyCodeTableRepository, MockAttractantCodeTableRepository, + MockComplaintStatusCodeTableRepository, } from "../../../test/mocks/mock-code-table-repositories"; -import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; - describe("Testing: CodeTable Service", () => { let service: CodeTableService; @@ -25,6 +26,10 @@ describe("Testing: CodeTable Service", () => { provide: getRepositoryToken(AttractantCode), useFactory: MockAttractantCodeTableRepository, }, + { + provide: getRepositoryToken(ComplaintStatusCode), + useFactory: MockComplaintStatusCodeTableRepository, + }, ], }).compile(); @@ -60,4 +65,17 @@ describe("Testing: CodeTable Service", () => { expect(results.length).not.toBe(0); expect(results.length).toBe(8); }); + + it("should return collection of complaint status types", async () => { + //-- arrange + const _tableName = "complaint-status"; + + //-- act + const results = await service.getCodeTableByName(_tableName); + + //-- assert + expect(results).not.toBe(null); + expect(results.length).not.toBe(0); + expect(results.length).toBe(2); + }); }); diff --git a/backend/src/v1/code-table/code-table.service.ts b/backend/src/v1/code-table/code-table.service.ts index 0e492f433..d7d29b907 100644 --- a/backend/src/v1/code-table/code-table.service.ts +++ b/backend/src/v1/code-table/code-table.service.ts @@ -2,9 +2,10 @@ import { Injectable, Logger } from "@nestjs/common"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import CodeTable, { Agency, Attractant } from "../../types/models/code-tables"; +import CodeTable, { Agency, Attractant, ComplaintStatus } from "../../types/models/code-tables"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; +import { ComplaintStatusCode } from "../complaint_status_code/entities/complaint_status_code.entity"; @Injectable() export class CodeTableService { @@ -14,6 +15,8 @@ export class CodeTableService { private _agencyRepository: Repository; @InjectRepository(AttractantCode) private _attractantRepository: Repository; + @InjectRepository(ComplaintStatusCode) + private _complaintStatusRepository: Repository; getCodeTableByName = async (table: string): Promise => { switch (table) { @@ -28,7 +31,7 @@ export class CodeTableService { active_ind, }) => { let table: Agency = { - agencyCode: agency_code, + agency: agency_code, shortDescription: short_description, longDescription: long_description, displayOrder: display_order, @@ -51,7 +54,29 @@ export class CodeTableService { active_ind, }) => { let table: Attractant = { - attractantCode: attractant_code, + attractant: attractant_code, + shortDescription: short_description, + longDescription: long_description, + displayOrder: display_order, + isActive: active_ind, + }; + return table; + } + ); + return results; + } + case "complaint-status": { + const data = await this._complaintStatusRepository.find(); + let results = data.map( + ({ + complaint_status_code, + short_description, + long_description, + display_order, + active_ind, + }) => { + let table: ComplaintStatus = { + complaintStatus: complaint_status_code, shortDescription: short_description, longDescription: long_description, displayOrder: display_order, diff --git a/backend/test/mocks/mock-code-table-repositories.ts b/backend/test/mocks/mock-code-table-repositories.ts index 548aad006..d0eeb9703 100644 --- a/backend/test/mocks/mock-code-table-repositories.ts +++ b/backend/test/mocks/mock-code-table-repositories.ts @@ -12,22 +12,27 @@ const agencyCollection = [ ] const attractants = [ - { "attractantCode": "BEEHIVE", "shortDescription": "Beehive", "longDescription": "Beehive", "displayOrder": 2, "isActive": true}, - { "attractantCode": "BIRD FDR", "shortDescription": "Bird Feeder", "longDescription": "Bird Feeder", "displayOrder": 3, "isActive": true }, - { "attractantCode": "CAMP FD", "shortDescription": "Campground Food", "longDescription": "Campground Food", "displayOrder": 4, "isActive": true }, - { "attractantCode": "COMPOST", "shortDescription": "Compost", "longDescription": "Compost", "displayOrder": 5, "isActive": true }, - { "attractantCode": "CROPS", "shortDescription": "Crops", "longDescription": "Crops", "displayOrder": 6, "isActive": true }, - { "attractantCode": "FREEZER", "shortDescription": "Freezer", "longDescription": "Freezer", "displayOrder": 7, "isActive": true }, - { "attractantCode": "BBQ", "shortDescription": "BBQ", "longDescription": "Barbeque", "displayOrder": 1, "isActive": true }, - { "attractantCode": "RESFRUIT", "shortDescription": "Fruit/Berries", "longDescription": "Residential Fruit/Berries", "displayOrder": 8, "isActive": true } + { "attractant_code": "BEEHIVE", "short_description": "Beehive", "long_description": "Beehive", "display_order": 2, "active_ind": true}, + { "attractant_code": "BIRD FDR", "short_description": "Bird Feeder", "long_description": "Bird Feeder", "display_order": 3, "active_ind": true }, + { "attractant_code": "CAMP FD", "short_description": "Campground Food", "long_description": "Campground Food", "display_order": 4, "active_ind": true }, + { "attractant_code": "COMPOST", "short_description": "Compost", "long_description": "Compost", "display_order": 5, "active_ind": true }, + { "attractant_code": "CROPS", "short_description": "Crops", "long_description": "Crops", "display_order": 6, "active_ind": true }, + { "attractant_code": "FREEZER", "short_description": "Freezer", "long_description": "Freezer", "display_order": 7, "active_ind": true }, + { "attractant_code": "BBQ", "short_description": "BBQ", "long_description": "Barbeque", "display_order": 1, "active_ind": true }, + { "attractant_code": "RESFRUIT", "short_description": "Fruit/Berries", "long_description": "Residential Fruit/Berries", "display_order": 8, "active_ind": true } ]; +const complaitStatus = [ + { "complaint_status_code": "OPEN", "short_description": "OPEN", "long_description": "Open", "display_order": 1, "active_ind": true }, + { "complaint_status_code": "CLOSED", "short_description": "CLOSED", "long_description": "Closed", "display_order": 1, "active_ind": true } +] + const single = (name: string = "default", idx: number = 0): any => { switch (name) { case "agency": { return idx <= agencyCollection.length - ? agencyCollection[idx] - : agencyCollection[0]; + ? agencyCollection[idx] + : agencyCollection[0]; } case "attractant": { return idx <= attractants.length @@ -58,4 +63,12 @@ export const MockAttractantCodeTableRepository = () => ({ getMany: jest.fn().mockResolvedValue(attractants), })), }); - \ No newline at end of file + + export const MockComplaintStatusCodeTableRepository = () => ({ + find: jest.fn().mockResolvedValue(complaitStatus), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(complaitStatus), + })), + }); \ No newline at end of file From 98697cd2dec4f54777ddc8028953d7b073b645af Mon Sep 17 00:00:00 2001 From: Mike Sears Date: Sat, 4 Nov 2023 20:49:21 -0700 Subject: [PATCH 07/21] nature of complaints code table added --- backend/src/types/models/code-tables/index.ts | 4 +-- .../models/code-tables/nature-of-complaint.ts | 5 ++++ .../code-table/code-table.controller.spec.ts | 7 ++++- .../src/v1/code-table/code-table.module.ts | 2 ++ .../v1/code-table/code-table.service.spec.ts | 19 +++++++++++++ .../src/v1/code-table/code-table.service.ts | 27 +++++++++++++++++- .../mocks/mock-code-table-repositories.ts | 28 +++++++++++++++++++ 7 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 backend/src/types/models/code-tables/nature-of-complaint.ts diff --git a/backend/src/types/models/code-tables/index.ts b/backend/src/types/models/code-tables/index.ts index 442be4cb6..83bbd1374 100644 --- a/backend/src/types/models/code-tables/index.ts +++ b/backend/src/types/models/code-tables/index.ts @@ -2,7 +2,7 @@ import { CodeTable } from "./code-table"; import { Agency } from "./agency"; import { Attractant } from "./attractant"; import { ComplaintStatus } from "./complaint-status"; - +import { NatureOfComplaint } from "./nature-of-complaint"; @@ -20,4 +20,4 @@ export const AvailableCodeTables = [ ]; export default CodeTable; -export { Agency, Attractant, ComplaintStatus }; +export { Agency, Attractant, ComplaintStatus, NatureOfComplaint }; diff --git a/backend/src/types/models/code-tables/nature-of-complaint.ts b/backend/src/types/models/code-tables/nature-of-complaint.ts new file mode 100644 index 000000000..8386f176c --- /dev/null +++ b/backend/src/types/models/code-tables/nature-of-complaint.ts @@ -0,0 +1,5 @@ +import { CodeTable } from "../../models/code-tables/code-table"; + +export interface NatureOfComplaint extends CodeTable { + natureOfComplaint: string +} \ No newline at end of file diff --git a/backend/src/v1/code-table/code-table.controller.spec.ts b/backend/src/v1/code-table/code-table.controller.spec.ts index 0f130c2ab..4a70f1f1d 100644 --- a/backend/src/v1/code-table/code-table.controller.spec.ts +++ b/backend/src/v1/code-table/code-table.controller.spec.ts @@ -10,10 +10,11 @@ import { JwtRoleGuard } from "../../auth/jwtrole.guard"; import { CodeTableController } from "./code-table.controller"; import { CodeTableService } from "./code-table.service"; -import { MockAgencyCodeTableRepository, MockAttractantCodeTableRepository, MockComplaintStatusCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; +import { MockAgencyCodeTableRepository, MockAttractantCodeTableRepository, MockComplaintStatusCodeTableRepository, MockNatureOfComplaintCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; import { ComplaintStatusCode } from "../complaint_status_code/entities/complaint_status_code.entity"; +import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; describe("Testing: CodeTable Controller", () => { let app: INestApplication; @@ -36,6 +37,10 @@ describe("Testing: CodeTable Controller", () => { provide: getRepositoryToken(ComplaintStatusCode), useFactory: MockComplaintStatusCodeTableRepository, }, + { + provide: getRepositoryToken(HwcrComplaintNatureCode), + useFactory: MockNatureOfComplaintCodeTableRepository, + }, ], }) .overrideGuard(JwtAuthGuard) .useValue({ authGuardMock }) diff --git a/backend/src/v1/code-table/code-table.module.ts b/backend/src/v1/code-table/code-table.module.ts index 221372fbe..793d1a736 100644 --- a/backend/src/v1/code-table/code-table.module.ts +++ b/backend/src/v1/code-table/code-table.module.ts @@ -5,12 +5,14 @@ import { TypeOrmModule } from "@nestjs/typeorm"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; import { ComplaintStatusCode } from "../complaint_status_code/entities/complaint_status_code.entity"; +import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; @Module({ imports: [ TypeOrmModule.forFeature([AgencyCode]), TypeOrmModule.forFeature([AttractantCode]), TypeOrmModule.forFeature([ComplaintStatusCode]), + TypeOrmModule.forFeature([HwcrComplaintNatureCode]), ], controllers: [CodeTableController], providers: [CodeTableService], diff --git a/backend/src/v1/code-table/code-table.service.spec.ts b/backend/src/v1/code-table/code-table.service.spec.ts index 7ba57ab59..388d75501 100644 --- a/backend/src/v1/code-table/code-table.service.spec.ts +++ b/backend/src/v1/code-table/code-table.service.spec.ts @@ -9,7 +9,9 @@ import { MockAgencyCodeTableRepository, MockAttractantCodeTableRepository, MockComplaintStatusCodeTableRepository, + MockNatureOfComplaintCodeTableRepository, } from "../../../test/mocks/mock-code-table-repositories"; +import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; describe("Testing: CodeTable Service", () => { let service: CodeTableService; @@ -30,6 +32,10 @@ describe("Testing: CodeTable Service", () => { provide: getRepositoryToken(ComplaintStatusCode), useFactory: MockComplaintStatusCodeTableRepository, }, + { + provide: getRepositoryToken(HwcrComplaintNatureCode), + useFactory: MockNatureOfComplaintCodeTableRepository, + }, ], }).compile(); @@ -78,4 +84,17 @@ describe("Testing: CodeTable Service", () => { expect(results.length).not.toBe(0); expect(results.length).toBe(2); }); + + it("should return collection of nature of complaints", async () => { + //-- arrange + const _tableName = "nature-of-complaint"; + + //-- act + const results = await service.getCodeTableByName(_tableName); + + //-- assert + expect(results).not.toBe(null); + expect(results.length).not.toBe(0); + expect(results.length).toBe(6); + }); }); diff --git a/backend/src/v1/code-table/code-table.service.ts b/backend/src/v1/code-table/code-table.service.ts index d7d29b907..601279c80 100644 --- a/backend/src/v1/code-table/code-table.service.ts +++ b/backend/src/v1/code-table/code-table.service.ts @@ -2,10 +2,11 @@ import { Injectable, Logger } from "@nestjs/common"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import CodeTable, { Agency, Attractant, ComplaintStatus } from "../../types/models/code-tables"; +import CodeTable, { Agency, Attractant, ComplaintStatus, NatureOfComplaint } from "../../types/models/code-tables"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; import { ComplaintStatusCode } from "../complaint_status_code/entities/complaint_status_code.entity"; +import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; @Injectable() export class CodeTableService { @@ -17,6 +18,8 @@ export class CodeTableService { private _attractantRepository: Repository; @InjectRepository(ComplaintStatusCode) private _complaintStatusRepository: Repository; + @InjectRepository(HwcrComplaintNatureCode) + private _natureOfComplaintRepository: Repository; getCodeTableByName = async (table: string): Promise => { switch (table) { @@ -87,6 +90,28 @@ export class CodeTableService { ); return results; } + case "nature-of-complaint": { + const data = await this._natureOfComplaintRepository.find(); + let results = data.map( + ({ + hwcr_complaint_nature_code, + short_description, + long_description, + display_order, + active_ind, + }) => { + let table: NatureOfComplaint = { + natureOfComplaint: hwcr_complaint_nature_code, + shortDescription: short_description, + longDescription: long_description, + displayOrder: display_order, + isActive: active_ind, + }; + return table; + } + ); + return results; + } } }; } diff --git a/backend/test/mocks/mock-code-table-repositories.ts b/backend/test/mocks/mock-code-table-repositories.ts index d0eeb9703..b829a4db2 100644 --- a/backend/test/mocks/mock-code-table-repositories.ts +++ b/backend/test/mocks/mock-code-table-repositories.ts @@ -27,6 +27,15 @@ const complaitStatus = [ { "complaint_status_code": "CLOSED", "short_description": "CLOSED", "long_description": "Closed", "display_order": 1, "active_ind": true } ] +const natureOfComplaints = [ + { "hwcr_complaint_nature_code": "AGGNOT", "short_description": "AGGNOT", "long_description": "Aggressive - not present", "display_order": 1, "active_ind": true }, + { "hwcr_complaint_nature_code": "AGGPRES", "short_description": "AGGPRES", "long_description": "Aggressive - present/recent", "display_order": 2, "active_ind": true }, + { "hwcr_complaint_nature_code": "CONFINED", "short_description": "CONFINED", "long_description": "Confined", "display_order": 3, "active_ind": true }, + { "hwcr_complaint_nature_code": "COUGARN", "short_description": "COUGARN", "long_description": "Cougar suspected - killed/injured livestock/pets - not present", "display_order": 4, "active_ind": true }, + { "hwcr_complaint_nature_code": "DAMNP", "short_description": "DAMNP", "long_description": "Damage to property - not present", "display_order": 5, "active_ind": true }, + { "hwcr_complaint_nature_code": "DEADNV", "short_description": "DEADNV", "long_description": "Dead wildlife - no violation suspected", "display_order": 6, "active_ind": true } +] + const single = (name: string = "default", idx: number = 0): any => { switch (name) { case "agency": { @@ -39,6 +48,16 @@ const single = (name: string = "default", idx: number = 0): any => { ? attractants[idx] : attractants[0]; } + case "complaint-status": { + return idx <= complaitStatus.length + ? complaitStatus[idx] + : complaitStatus[0]; + } + case "nature-of-complaint": { + return idx <= natureOfComplaints.length + ? natureOfComplaints[idx] + : natureOfComplaints[0]; + } case "default": default: return null; @@ -71,4 +90,13 @@ export const MockAttractantCodeTableRepository = () => ({ where: jest.fn().mockReturnThis(), getMany: jest.fn().mockResolvedValue(complaitStatus), })), + }); + + export const MockNatureOfComplaintCodeTableRepository = () => ({ + find: jest.fn().mockResolvedValue(natureOfComplaints), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(natureOfComplaints), + })), }); \ No newline at end of file From f35dcaad0b8b03d1c2670caef4f8cdcc48b4a25c Mon Sep 17 00:00:00 2001 From: Mike Sears Date: Sat, 4 Nov 2023 21:00:35 -0700 Subject: [PATCH 08/21] organization unit type added --- backend/src/types/models/code-tables/index.ts | 4 +-- .../code-tables/organization-unit-type.ts | 5 ++++ .../code-table/code-table.controller.spec.ts | 7 ++++- .../src/v1/code-table/code-table.module.ts | 2 ++ .../v1/code-table/code-table.service.spec.ts | 19 +++++++++++++ .../src/v1/code-table/code-table.service.ts | 27 ++++++++++++++++++- .../mocks/mock-code-table-repositories.ts | 16 +++++++++++ 7 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 backend/src/types/models/code-tables/organization-unit-type.ts diff --git a/backend/src/types/models/code-tables/index.ts b/backend/src/types/models/code-tables/index.ts index 83bbd1374..3c920dcba 100644 --- a/backend/src/types/models/code-tables/index.ts +++ b/backend/src/types/models/code-tables/index.ts @@ -3,7 +3,7 @@ import { Agency } from "./agency"; import { Attractant } from "./attractant"; import { ComplaintStatus } from "./complaint-status"; import { NatureOfComplaint } from "./nature-of-complaint"; - +import { OrganizationUnitType } from "./organization-unit-type"; export const AvailableCodeTables = [ @@ -20,4 +20,4 @@ export const AvailableCodeTables = [ ]; export default CodeTable; -export { Agency, Attractant, ComplaintStatus, NatureOfComplaint }; +export { Agency, Attractant, ComplaintStatus, NatureOfComplaint, OrganizationUnitType }; diff --git a/backend/src/types/models/code-tables/organization-unit-type.ts b/backend/src/types/models/code-tables/organization-unit-type.ts new file mode 100644 index 000000000..b813c32d4 --- /dev/null +++ b/backend/src/types/models/code-tables/organization-unit-type.ts @@ -0,0 +1,5 @@ +import { CodeTable } from "../../models/code-tables/code-table"; + +export interface OrganizationUnitType extends CodeTable { + organizationUnitType: string +} \ No newline at end of file diff --git a/backend/src/v1/code-table/code-table.controller.spec.ts b/backend/src/v1/code-table/code-table.controller.spec.ts index 4a70f1f1d..73272dfcc 100644 --- a/backend/src/v1/code-table/code-table.controller.spec.ts +++ b/backend/src/v1/code-table/code-table.controller.spec.ts @@ -10,11 +10,12 @@ import { JwtRoleGuard } from "../../auth/jwtrole.guard"; import { CodeTableController } from "./code-table.controller"; import { CodeTableService } from "./code-table.service"; -import { MockAgencyCodeTableRepository, MockAttractantCodeTableRepository, MockComplaintStatusCodeTableRepository, MockNatureOfComplaintCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; +import { MockAgencyCodeTableRepository, MockAttractantCodeTableRepository, MockComplaintStatusCodeTableRepository, MockNatureOfComplaintCodeTableRepository, MockOrganizationUnitTypeCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; import { ComplaintStatusCode } from "../complaint_status_code/entities/complaint_status_code.entity"; import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; +import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; describe("Testing: CodeTable Controller", () => { let app: INestApplication; @@ -41,6 +42,10 @@ describe("Testing: CodeTable Controller", () => { provide: getRepositoryToken(HwcrComplaintNatureCode), useFactory: MockNatureOfComplaintCodeTableRepository, }, + { + provide: getRepositoryToken(GeoOrgUnitTypeCode), + useFactory: MockOrganizationUnitTypeCodeTableRepository, + }, ], }) .overrideGuard(JwtAuthGuard) .useValue({ authGuardMock }) diff --git a/backend/src/v1/code-table/code-table.module.ts b/backend/src/v1/code-table/code-table.module.ts index 793d1a736..2bbdf50d9 100644 --- a/backend/src/v1/code-table/code-table.module.ts +++ b/backend/src/v1/code-table/code-table.module.ts @@ -6,6 +6,7 @@ import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; import { ComplaintStatusCode } from "../complaint_status_code/entities/complaint_status_code.entity"; import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; +import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; @Module({ imports: [ @@ -13,6 +14,7 @@ import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/ TypeOrmModule.forFeature([AttractantCode]), TypeOrmModule.forFeature([ComplaintStatusCode]), TypeOrmModule.forFeature([HwcrComplaintNatureCode]), + TypeOrmModule.forFeature([GeoOrgUnitTypeCode]), ], controllers: [CodeTableController], providers: [CodeTableService], diff --git a/backend/src/v1/code-table/code-table.service.spec.ts b/backend/src/v1/code-table/code-table.service.spec.ts index 388d75501..b049f5932 100644 --- a/backend/src/v1/code-table/code-table.service.spec.ts +++ b/backend/src/v1/code-table/code-table.service.spec.ts @@ -10,8 +10,10 @@ import { MockAttractantCodeTableRepository, MockComplaintStatusCodeTableRepository, MockNatureOfComplaintCodeTableRepository, + MockOrganizationUnitTypeCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; +import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; describe("Testing: CodeTable Service", () => { let service: CodeTableService; @@ -36,6 +38,10 @@ describe("Testing: CodeTable Service", () => { provide: getRepositoryToken(HwcrComplaintNatureCode), useFactory: MockNatureOfComplaintCodeTableRepository, }, + { + provide: getRepositoryToken(GeoOrgUnitTypeCode), + useFactory: MockOrganizationUnitTypeCodeTableRepository, + }, ], }).compile(); @@ -97,4 +103,17 @@ describe("Testing: CodeTable Service", () => { expect(results.length).not.toBe(0); expect(results.length).toBe(6); }); + + it("should return collection of organization types", async () => { + //-- arrange + const _tableName = "organization-unit-type"; + + //-- act + const results = await service.getCodeTableByName(_tableName); + + //-- assert + expect(results).not.toBe(null); + expect(results.length).not.toBe(0); + expect(results.length).toBe(4); + }); }); diff --git a/backend/src/v1/code-table/code-table.service.ts b/backend/src/v1/code-table/code-table.service.ts index 601279c80..b5377397b 100644 --- a/backend/src/v1/code-table/code-table.service.ts +++ b/backend/src/v1/code-table/code-table.service.ts @@ -2,11 +2,12 @@ import { Injectable, Logger } from "@nestjs/common"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import CodeTable, { Agency, Attractant, ComplaintStatus, NatureOfComplaint } from "../../types/models/code-tables"; +import CodeTable, { Agency, Attractant, ComplaintStatus, NatureOfComplaint, OrganizationUnitType } from "../../types/models/code-tables"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; import { ComplaintStatusCode } from "../complaint_status_code/entities/complaint_status_code.entity"; import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; +import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; @Injectable() export class CodeTableService { @@ -20,6 +21,8 @@ export class CodeTableService { private _complaintStatusRepository: Repository; @InjectRepository(HwcrComplaintNatureCode) private _natureOfComplaintRepository: Repository; + @InjectRepository(GeoOrgUnitTypeCode) + private _organizationUnitTypeRepository: Repository; getCodeTableByName = async (table: string): Promise => { switch (table) { @@ -112,6 +115,28 @@ export class CodeTableService { ); return results; } + case "organization-unit-type": { + const data = await this._organizationUnitTypeRepository.find(); + let results = data.map( + ({ + geo_org_unit_type_code, + short_description, + long_description, + display_order, + active_ind, + }) => { + let table: OrganizationUnitType = { + organizationUnitType: geo_org_unit_type_code, + shortDescription: short_description, + longDescription: long_description, + displayOrder: display_order, + isActive: active_ind, + }; + return table; + } + ); + return results; + } } }; } diff --git a/backend/test/mocks/mock-code-table-repositories.ts b/backend/test/mocks/mock-code-table-repositories.ts index b829a4db2..316c19a66 100644 --- a/backend/test/mocks/mock-code-table-repositories.ts +++ b/backend/test/mocks/mock-code-table-repositories.ts @@ -36,6 +36,13 @@ const natureOfComplaints = [ { "hwcr_complaint_nature_code": "DEADNV", "short_description": "DEADNV", "long_description": "Dead wildlife - no violation suspected", "display_order": 6, "active_ind": true } ] +const organizationUnitTypes = [ + { "geo_org_unit_type_code": "ZONE", "short_description": "Zone", "long_description": null, "display_order": 1, "active_ind": true }, + { "geo_org_unit_type_code": "REGION", "short_description": "Region", "long_description": null, "display_order": 2, "active_ind": true }, + { "geo_org_unit_type_code": "OFFLOC", "short_description": "Office Location", "long_description": null, "display_order": 3, "active_ind": true }, + { "geo_org_unit_type_code": "AREA", "short_description": "Area", "long_description": null, "display_order": 4, "active_ind": true } +] + const single = (name: string = "default", idx: number = 0): any => { switch (name) { case "agency": { @@ -99,4 +106,13 @@ export const MockAttractantCodeTableRepository = () => ({ where: jest.fn().mockReturnThis(), getMany: jest.fn().mockResolvedValue(natureOfComplaints), })), + }); + + export const MockOrganizationUnitTypeCodeTableRepository = () => ({ + find: jest.fn().mockResolvedValue(organizationUnitTypes), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(organizationUnitTypes), + })), }); \ No newline at end of file From 6555c49c48ef05382b9c945aaacf4cde5cb312a8 Mon Sep 17 00:00:00 2001 From: Mike Sears Date: Sat, 4 Nov 2023 21:57:05 -0700 Subject: [PATCH 09/21] organization unit code table added --- .../types/models/code-tables/code-table.ts | 4 +- .../models/code-tables/organization-unit.ts | 6 + .../code-table/code-table.controller.spec.ts | 7 +- .../src/v1/code-table/code-table.module.ts | 2 + .../v1/code-table/code-table.service.spec.ts | 21 +++- .../src/v1/code-table/code-table.service.ts | 53 +++++++- .../mocks/mock-code-table-repositories.ts | 114 ++++++++++-------- 7 files changed, 149 insertions(+), 58 deletions(-) create mode 100644 backend/src/types/models/code-tables/organization-unit.ts diff --git a/backend/src/types/models/code-tables/code-table.ts b/backend/src/types/models/code-tables/code-table.ts index 6bf46f7a0..7188318cb 100644 --- a/backend/src/types/models/code-tables/code-table.ts +++ b/backend/src/types/models/code-tables/code-table.ts @@ -1,6 +1,6 @@ export interface CodeTable { shortDescription: string; longDescription: string; - displayOrder: number; - isActive: boolean; + displayOrder?: number; + isActive?: boolean; } diff --git a/backend/src/types/models/code-tables/organization-unit.ts b/backend/src/types/models/code-tables/organization-unit.ts new file mode 100644 index 000000000..0e6ec1280 --- /dev/null +++ b/backend/src/types/models/code-tables/organization-unit.ts @@ -0,0 +1,6 @@ +import { CodeTable } from "../../models/code-tables/code-table"; + +export interface OrganizationUnit extends CodeTable { + organizationUnit: string + organizationUnitType?: string +} \ No newline at end of file diff --git a/backend/src/v1/code-table/code-table.controller.spec.ts b/backend/src/v1/code-table/code-table.controller.spec.ts index 73272dfcc..cf924bb3f 100644 --- a/backend/src/v1/code-table/code-table.controller.spec.ts +++ b/backend/src/v1/code-table/code-table.controller.spec.ts @@ -10,12 +10,13 @@ import { JwtRoleGuard } from "../../auth/jwtrole.guard"; import { CodeTableController } from "./code-table.controller"; import { CodeTableService } from "./code-table.service"; -import { MockAgencyCodeTableRepository, MockAttractantCodeTableRepository, MockComplaintStatusCodeTableRepository, MockNatureOfComplaintCodeTableRepository, MockOrganizationUnitTypeCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; +import { MockAgencyCodeTableRepository, MockAttractantCodeTableRepository, MockComplaintStatusCodeTableRepository, MockNatureOfComplaintCodeTableRepository, MockOrganizationUnitCodeTableRepository, MockOrganizationUnitTypeCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; import { ComplaintStatusCode } from "../complaint_status_code/entities/complaint_status_code.entity"; import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; +import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/geo_organization_unit_code.entity"; describe("Testing: CodeTable Controller", () => { let app: INestApplication; @@ -46,6 +47,10 @@ describe("Testing: CodeTable Controller", () => { provide: getRepositoryToken(GeoOrgUnitTypeCode), useFactory: MockOrganizationUnitTypeCodeTableRepository, }, + { + provide: getRepositoryToken(GeoOrganizationUnitCode), + useFactory: MockOrganizationUnitCodeTableRepository, + }, ], }) .overrideGuard(JwtAuthGuard) .useValue({ authGuardMock }) diff --git a/backend/src/v1/code-table/code-table.module.ts b/backend/src/v1/code-table/code-table.module.ts index 2bbdf50d9..8123eaa1b 100644 --- a/backend/src/v1/code-table/code-table.module.ts +++ b/backend/src/v1/code-table/code-table.module.ts @@ -7,6 +7,7 @@ import { AttractantCode } from "../attractant_code/entities/attractant_code.enti import { ComplaintStatusCode } from "../complaint_status_code/entities/complaint_status_code.entity"; import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; +import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/geo_organization_unit_code.entity"; @Module({ imports: [ @@ -15,6 +16,7 @@ import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_u TypeOrmModule.forFeature([ComplaintStatusCode]), TypeOrmModule.forFeature([HwcrComplaintNatureCode]), TypeOrmModule.forFeature([GeoOrgUnitTypeCode]), + TypeOrmModule.forFeature([GeoOrganizationUnitCode]), ], controllers: [CodeTableController], providers: [CodeTableService], diff --git a/backend/src/v1/code-table/code-table.service.spec.ts b/backend/src/v1/code-table/code-table.service.spec.ts index b049f5932..74e688875 100644 --- a/backend/src/v1/code-table/code-table.service.spec.ts +++ b/backend/src/v1/code-table/code-table.service.spec.ts @@ -10,10 +10,12 @@ import { MockAttractantCodeTableRepository, MockComplaintStatusCodeTableRepository, MockNatureOfComplaintCodeTableRepository, + MockOrganizationUnitCodeTableRepository, MockOrganizationUnitTypeCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; +import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/geo_organization_unit_code.entity"; describe("Testing: CodeTable Service", () => { let service: CodeTableService; @@ -42,6 +44,10 @@ describe("Testing: CodeTable Service", () => { provide: getRepositoryToken(GeoOrgUnitTypeCode), useFactory: MockOrganizationUnitTypeCodeTableRepository, }, + { + provide: getRepositoryToken(GeoOrganizationUnitCode), + useFactory: MockOrganizationUnitCodeTableRepository, + }, ], }).compile(); @@ -104,7 +110,7 @@ describe("Testing: CodeTable Service", () => { expect(results.length).toBe(6); }); - it("should return collection of organization types", async () => { + it("should return collection of organization unit types", async () => { //-- arrange const _tableName = "organization-unit-type"; @@ -116,4 +122,17 @@ describe("Testing: CodeTable Service", () => { expect(results.length).not.toBe(0); expect(results.length).toBe(4); }); + + it("should return collection of organization types", async () => { + //-- arrange + const _tableName = "organization-unit"; + + //-- act + const results = await service.getCodeTableByName(_tableName); + + //-- assert + expect(results).not.toBe(null); + expect(results.length).not.toBe(0); + expect(results.length).toBe(5); + }); }); diff --git a/backend/src/v1/code-table/code-table.service.ts b/backend/src/v1/code-table/code-table.service.ts index b5377397b..100e3a224 100644 --- a/backend/src/v1/code-table/code-table.service.ts +++ b/backend/src/v1/code-table/code-table.service.ts @@ -2,12 +2,20 @@ import { Injectable, Logger } from "@nestjs/common"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import CodeTable, { Agency, Attractant, ComplaintStatus, NatureOfComplaint, OrganizationUnitType } from "../../types/models/code-tables"; +import CodeTable, { + Agency, + Attractant, + ComplaintStatus, + NatureOfComplaint, + OrganizationUnitType, +} from "../../types/models/code-tables"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; import { ComplaintStatusCode } from "../complaint_status_code/entities/complaint_status_code.entity"; import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; +import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/geo_organization_unit_code.entity"; +import { OrganizationUnit } from "src/types/models/code-tables/organization-unit"; @Injectable() export class CodeTableService { @@ -23,6 +31,8 @@ export class CodeTableService { private _natureOfComplaintRepository: Repository; @InjectRepository(GeoOrgUnitTypeCode) private _organizationUnitTypeRepository: Repository; + @InjectRepository(GeoOrganizationUnitCode) + private _organizationUnitRepository: Repository; getCodeTableByName = async (table: string): Promise => { switch (table) { @@ -71,7 +81,7 @@ export class CodeTableService { ); return results; } - case "complaint-status": { + case "complaint-status": { const data = await this._complaintStatusRepository.find(); let results = data.map( ({ @@ -93,7 +103,7 @@ export class CodeTableService { ); return results; } - case "nature-of-complaint": { + case "nature-of-complaint": { const data = await this._natureOfComplaintRepository.find(); let results = data.map( ({ @@ -115,7 +125,7 @@ export class CodeTableService { ); return results; } - case "organization-unit-type": { + case "organization-unit-type": { const data = await this._organizationUnitTypeRepository.find(); let results = data.map( ({ @@ -137,6 +147,41 @@ export class CodeTableService { ); return results; } + case "organization-unit": { + const builder = this._organizationUnitRepository + .createQueryBuilder("organization_unit") + .leftJoinAndSelect( + "organization_unit.geo_org_unit_type_code", + "organization_unit_type" + ); + + const data = await builder.getMany(); + + let results = data.map( + ({ + geo_organization_unit_code, + short_description, + long_description, + geo_org_unit_type_code: organizationUnitType, + }) => { + let table: OrganizationUnit = { + organizationUnit: geo_organization_unit_code, + shortDescription: short_description, + longDescription: long_description, + }; + + if (organizationUnitType) { + const { geo_org_unit_type_code } = organizationUnitType; + return { + ...table, + organizationUnitType: geo_org_unit_type_code, + }; + } + return table; + } + ); + return results; + } } }; } diff --git a/backend/test/mocks/mock-code-table-repositories.ts b/backend/test/mocks/mock-code-table-repositories.ts index 316c19a66..ad6311d60 100644 --- a/backend/test/mocks/mock-code-table-repositories.ts +++ b/backend/test/mocks/mock-code-table-repositories.ts @@ -1,5 +1,3 @@ -import { randomUUID } from "crypto"; - const agencyCollection = [ { "agency_code": "BCWF", "short_description": "BCWF", "long_description": "BC Wildlife Federation", "display_order": 1, "active_ind": true }, { "agency_code": "BYLAW", "short_description": "Bylaw Enforcement", "long_description": "Bylaw Enforcement", "display_order": 2, "active_ind": true }, @@ -13,13 +11,13 @@ const agencyCollection = [ const attractants = [ { "attractant_code": "BEEHIVE", "short_description": "Beehive", "long_description": "Beehive", "display_order": 2, "active_ind": true}, - { "attractant_code": "BIRD FDR", "short_description": "Bird Feeder", "long_description": "Bird Feeder", "display_order": 3, "active_ind": true }, - { "attractant_code": "CAMP FD", "short_description": "Campground Food", "long_description": "Campground Food", "display_order": 4, "active_ind": true }, - { "attractant_code": "COMPOST", "short_description": "Compost", "long_description": "Compost", "display_order": 5, "active_ind": true }, - { "attractant_code": "CROPS", "short_description": "Crops", "long_description": "Crops", "display_order": 6, "active_ind": true }, - { "attractant_code": "FREEZER", "short_description": "Freezer", "long_description": "Freezer", "display_order": 7, "active_ind": true }, - { "attractant_code": "BBQ", "short_description": "BBQ", "long_description": "Barbeque", "display_order": 1, "active_ind": true }, - { "attractant_code": "RESFRUIT", "short_description": "Fruit/Berries", "long_description": "Residential Fruit/Berries", "display_order": 8, "active_ind": true } + { "attractant_code": "BIRD FDR", "short_description": "Bird Feeder", "long_description": "Bird Feeder", "display_order": 3, "active_ind": true }, + { "attractant_code": "CAMP FD", "short_description": "Campground Food", "long_description": "Campground Food", "display_order": 4, "active_ind": true }, + { "attractant_code": "COMPOST", "short_description": "Compost", "long_description": "Compost", "display_order": 5, "active_ind": true }, + { "attractant_code": "CROPS", "short_description": "Crops", "long_description": "Crops", "display_order": 6, "active_ind": true }, + { "attractant_code": "FREEZER", "short_description": "Freezer", "long_description": "Freezer", "display_order": 7, "active_ind": true }, + { "attractant_code": "BBQ", "short_description": "BBQ", "long_description": "Barbeque", "display_order": 1, "active_ind": true }, + { "attractant_code": "RESFRUIT", "short_description": "Fruit/Berries", "long_description": "Residential Fruit/Berries", "display_order": 8, "active_ind": true } ]; const complaitStatus = [ @@ -43,27 +41,33 @@ const organizationUnitTypes = [ { "geo_org_unit_type_code": "AREA", "short_description": "Area", "long_description": null, "display_order": 4, "active_ind": true } ] +const organizationUnits = [ + { organizationUnit: "OKNGN", shortDescription: "Okanagan", longDescription: "Okanagan", organizationUnitType: "REGION", }, + { organizationUnit: "OMINECA", shortDescription: "Omineca", longDescription: "Omineca", organizationUnitType: "REGION", }, + { organizationUnit: "BLKYCSR", shortDescription: "Bulkley-Cassiar", longDescription: "Bulkley-Cassiar", organizationUnitType: "ZONE", }, + { organizationUnit: "CRBOCHLCTN", shortDescription: "Cariboo Chilcotin", longDescription: "Cariboo Chilcotin", organizationUnitType: "ZONE", }, + { organizationUnit: "CHTWD", shortDescription: "Chetwynd", longDescription: "Chetwynd", organizationUnitType: "OFFLOC", }, +]; + const single = (name: string = "default", idx: number = 0): any => { switch (name) { case "agency": { return idx <= agencyCollection.length - ? agencyCollection[idx] - : agencyCollection[0]; + ? agencyCollection[idx] + : agencyCollection[0]; } - case "attractant": { - return idx <= attractants.length - ? attractants[idx] - : attractants[0]; + case "attractant": { + return idx <= attractants.length ? attractants[idx] : attractants[0]; } - case "complaint-status": { + case "complaint-status": { return idx <= complaitStatus.length - ? complaitStatus[idx] - : complaitStatus[0]; + ? complaitStatus[idx] + : complaitStatus[0]; } - case "nature-of-complaint": { + case "nature-of-complaint": { return idx <= natureOfComplaints.length - ? natureOfComplaints[idx] - : natureOfComplaints[0]; + ? natureOfComplaints[idx] + : natureOfComplaints[0]; } case "default": default: @@ -80,39 +84,49 @@ export const MockAgencyCodeTableRepository = () => ({ })), }); - export const MockAttractantCodeTableRepository = () => ({ - find: jest.fn().mockResolvedValue(attractants), - createQueryBuilder: jest.fn(() => ({ - leftJoinAndSelect: jest.fn().mockReturnThis(), - where: jest.fn().mockReturnThis(), - getMany: jest.fn().mockResolvedValue(attractants), - })), - }); - - export const MockComplaintStatusCodeTableRepository = () => ({ - find: jest.fn().mockResolvedValue(complaitStatus), - createQueryBuilder: jest.fn(() => ({ - leftJoinAndSelect: jest.fn().mockReturnThis(), - where: jest.fn().mockReturnThis(), - getMany: jest.fn().mockResolvedValue(complaitStatus), - })), - }); + find: jest.fn().mockResolvedValue(attractants), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(attractants), + })), +}); - export const MockNatureOfComplaintCodeTableRepository = () => ({ - find: jest.fn().mockResolvedValue(natureOfComplaints), - createQueryBuilder: jest.fn(() => ({ - leftJoinAndSelect: jest.fn().mockReturnThis(), - where: jest.fn().mockReturnThis(), - getMany: jest.fn().mockResolvedValue(natureOfComplaints), - })), - }); +export const MockComplaintStatusCodeTableRepository = () => ({ + find: jest.fn().mockResolvedValue(complaitStatus), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(complaitStatus), + })), +}); - export const MockOrganizationUnitTypeCodeTableRepository = () => ({ - find: jest.fn().mockResolvedValue(organizationUnitTypes), +export const MockNatureOfComplaintCodeTableRepository = () => ({ + find: jest.fn().mockResolvedValue(natureOfComplaints), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(natureOfComplaints), + })), +}); + +organizationUnits + +export const MockOrganizationUnitTypeCodeTableRepository = () => ({ + find: jest.fn().mockResolvedValue(organizationUnitTypes), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(organizationUnitTypes), + })), +}); + +export const MockOrganizationUnitCodeTableRepository = () => ({ + find: jest.fn().mockResolvedValue(organizationUnits), createQueryBuilder: jest.fn(() => ({ leftJoinAndSelect: jest.fn().mockReturnThis(), where: jest.fn().mockReturnThis(), - getMany: jest.fn().mockResolvedValue(organizationUnitTypes), + getMany: jest.fn().mockResolvedValue(organizationUnits), })), - }); \ No newline at end of file + }); From 5cd20482fdef9f458d1a2ca32c779394d8252033 Mon Sep 17 00:00:00 2001 From: Mike Sears Date: Sat, 4 Nov 2023 22:39:10 -0700 Subject: [PATCH 10/21] code smell removal --- backend/test/mocks/mock-code-table-repositories.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/backend/test/mocks/mock-code-table-repositories.ts b/backend/test/mocks/mock-code-table-repositories.ts index ad6311d60..2f4250c17 100644 --- a/backend/test/mocks/mock-code-table-repositories.ts +++ b/backend/test/mocks/mock-code-table-repositories.ts @@ -111,8 +111,6 @@ export const MockNatureOfComplaintCodeTableRepository = () => ({ })), }); -organizationUnits - export const MockOrganizationUnitTypeCodeTableRepository = () => ({ find: jest.fn().mockResolvedValue(organizationUnitTypes), createQueryBuilder: jest.fn(() => ({ From f6d11a1ead63b4689b5864e71ee26f4f6f75f7b1 Mon Sep 17 00:00:00 2001 From: Mike Sears Date: Sun, 5 Nov 2023 20:47:09 -0800 Subject: [PATCH 11/21] person complaint code table implemented --- backend/src/types/models/code-tables/index.ts | 4 +-- .../code-tables/person-complaint-type.ts | 5 +++ .../code-table/code-table.controller.spec.ts | 7 ++++- .../src/v1/code-table/code-table.module.ts | 2 ++ .../v1/code-table/code-table.service.spec.ts | 21 ++++++++++++- .../src/v1/code-table/code-table.service.ts | 24 ++++++++++++++ .../person_complaint_xref_code.entity.ts | 4 +-- .../mocks/mock-code-table-repositories.ts | 31 ++++++++++++++----- 8 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 backend/src/types/models/code-tables/person-complaint-type.ts diff --git a/backend/src/types/models/code-tables/index.ts b/backend/src/types/models/code-tables/index.ts index 3c920dcba..e1c04aee4 100644 --- a/backend/src/types/models/code-tables/index.ts +++ b/backend/src/types/models/code-tables/index.ts @@ -4,7 +4,7 @@ import { Attractant } from "./attractant"; import { ComplaintStatus } from "./complaint-status"; import { NatureOfComplaint } from "./nature-of-complaint"; import { OrganizationUnitType } from "./organization-unit-type"; - +import { PersonComplaintType } from "./person-complaint-type"; export const AvailableCodeTables = [ "agency", @@ -20,4 +20,4 @@ export const AvailableCodeTables = [ ]; export default CodeTable; -export { Agency, Attractant, ComplaintStatus, NatureOfComplaint, OrganizationUnitType }; +export { Agency, Attractant, ComplaintStatus, NatureOfComplaint, OrganizationUnitType, PersonComplaintType }; diff --git a/backend/src/types/models/code-tables/person-complaint-type.ts b/backend/src/types/models/code-tables/person-complaint-type.ts new file mode 100644 index 000000000..bd517b143 --- /dev/null +++ b/backend/src/types/models/code-tables/person-complaint-type.ts @@ -0,0 +1,5 @@ +import { CodeTable } from "./code-table"; + +export interface PersonComplaintType extends CodeTable { + personComplaintType: string +} \ No newline at end of file diff --git a/backend/src/v1/code-table/code-table.controller.spec.ts b/backend/src/v1/code-table/code-table.controller.spec.ts index cf924bb3f..d675603c4 100644 --- a/backend/src/v1/code-table/code-table.controller.spec.ts +++ b/backend/src/v1/code-table/code-table.controller.spec.ts @@ -10,13 +10,14 @@ import { JwtRoleGuard } from "../../auth/jwtrole.guard"; import { CodeTableController } from "./code-table.controller"; import { CodeTableService } from "./code-table.service"; -import { MockAgencyCodeTableRepository, MockAttractantCodeTableRepository, MockComplaintStatusCodeTableRepository, MockNatureOfComplaintCodeTableRepository, MockOrganizationUnitCodeTableRepository, MockOrganizationUnitTypeCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; +import { MockAgencyCodeTableRepository, MockAttractantCodeTableRepository, MockComplaintStatusCodeTableRepository, MockNatureOfComplaintCodeTableRepository, MockOrganizationUnitCodeTableRepository, MockOrganizationUnitTypeCodeTableRepository, MockPersonComplaintCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; import { ComplaintStatusCode } from "../complaint_status_code/entities/complaint_status_code.entity"; import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/geo_organization_unit_code.entity"; +import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/person_complaint_xref_code.entity"; describe("Testing: CodeTable Controller", () => { let app: INestApplication; @@ -51,6 +52,10 @@ describe("Testing: CodeTable Controller", () => { provide: getRepositoryToken(GeoOrganizationUnitCode), useFactory: MockOrganizationUnitCodeTableRepository, }, + { + provide: getRepositoryToken(PersonComplaintXrefCode), + useFactory: MockPersonComplaintCodeTableRepository, + }, ], }) .overrideGuard(JwtAuthGuard) .useValue({ authGuardMock }) diff --git a/backend/src/v1/code-table/code-table.module.ts b/backend/src/v1/code-table/code-table.module.ts index 8123eaa1b..d884963cf 100644 --- a/backend/src/v1/code-table/code-table.module.ts +++ b/backend/src/v1/code-table/code-table.module.ts @@ -8,6 +8,7 @@ import { ComplaintStatusCode } from "../complaint_status_code/entities/complaint import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/geo_organization_unit_code.entity"; +import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/person_complaint_xref_code.entity"; @Module({ imports: [ @@ -17,6 +18,7 @@ import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/ TypeOrmModule.forFeature([HwcrComplaintNatureCode]), TypeOrmModule.forFeature([GeoOrgUnitTypeCode]), TypeOrmModule.forFeature([GeoOrganizationUnitCode]), + TypeOrmModule.forFeature([PersonComplaintXrefCode]), ], controllers: [CodeTableController], providers: [CodeTableService], diff --git a/backend/src/v1/code-table/code-table.service.spec.ts b/backend/src/v1/code-table/code-table.service.spec.ts index 74e688875..ceb26bc7e 100644 --- a/backend/src/v1/code-table/code-table.service.spec.ts +++ b/backend/src/v1/code-table/code-table.service.spec.ts @@ -11,11 +11,13 @@ import { MockComplaintStatusCodeTableRepository, MockNatureOfComplaintCodeTableRepository, MockOrganizationUnitCodeTableRepository, - MockOrganizationUnitTypeCodeTableRepository + MockOrganizationUnitTypeCodeTableRepository, + MockPersonComplaintCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/geo_organization_unit_code.entity"; +import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/person_complaint_xref_code.entity"; describe("Testing: CodeTable Service", () => { let service: CodeTableService; @@ -48,6 +50,10 @@ describe("Testing: CodeTable Service", () => { provide: getRepositoryToken(GeoOrganizationUnitCode), useFactory: MockOrganizationUnitCodeTableRepository, }, + { + provide: getRepositoryToken(PersonComplaintXrefCode), + useFactory: MockPersonComplaintCodeTableRepository, + }, ], }).compile(); @@ -135,4 +141,17 @@ describe("Testing: CodeTable Service", () => { expect(results.length).not.toBe(0); expect(results.length).toBe(5); }); + + it("should return collection of person complaint types", async () => { + //-- arrange + const _tableName = "person-complaint"; + + //-- act + const results = await service.getCodeTableByName(_tableName); + + //-- assert + expect(results).not.toBe(null); + expect(results.length).not.toBe(0); + expect(results.length).toBe(2); + }); }); diff --git a/backend/src/v1/code-table/code-table.service.ts b/backend/src/v1/code-table/code-table.service.ts index 100e3a224..cc732bf7e 100644 --- a/backend/src/v1/code-table/code-table.service.ts +++ b/backend/src/v1/code-table/code-table.service.ts @@ -8,6 +8,7 @@ import CodeTable, { ComplaintStatus, NatureOfComplaint, OrganizationUnitType, + PersonComplaintType, } from "../../types/models/code-tables"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; @@ -16,6 +17,7 @@ import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/ import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/geo_organization_unit_code.entity"; import { OrganizationUnit } from "src/types/models/code-tables/organization-unit"; +import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/person_complaint_xref_code.entity"; @Injectable() export class CodeTableService { @@ -33,6 +35,8 @@ export class CodeTableService { private _organizationUnitTypeRepository: Repository; @InjectRepository(GeoOrganizationUnitCode) private _organizationUnitRepository: Repository; + @InjectRepository(PersonComplaintXrefCode) + private _personComplaintTypeRepository: Repository; getCodeTableByName = async (table: string): Promise => { switch (table) { @@ -182,6 +186,26 @@ export class CodeTableService { ); return results; } + case "person-complaint": { + const data = await this._personComplaintTypeRepository.find(); + let results = data.map( + ({ + person_complaint_xref_code, + short_description, + long_description, + display_order, + }) => { + let table: PersonComplaintType = { + personComplaintType: person_complaint_xref_code, + shortDescription: short_description, + longDescription: long_description, + displayOrder: display_order, + }; + return table; + } + ); + return results; + } } }; } diff --git a/backend/src/v1/person_complaint_xref_code/entities/person_complaint_xref_code.entity.ts b/backend/src/v1/person_complaint_xref_code/entities/person_complaint_xref_code.entity.ts index 8cb15ec3e..5e0b33795 100644 --- a/backend/src/v1/person_complaint_xref_code/entities/person_complaint_xref_code.entity.ts +++ b/backend/src/v1/person_complaint_xref_code/entities/person_complaint_xref_code.entity.ts @@ -26,8 +26,8 @@ export class PersonComplaintXrefCode { @Column("integer", { name: "display_order" }) display_order: number; - @Column("boolean", { name: "active_ind" }) - active_ind: boolean; + // @Column("boolean", { name: "active_ind" }) + // active_ind: boolean; @Column("character varying", { name: "create_user_id", length: 32 }) create_user_id: string; diff --git a/backend/test/mocks/mock-code-table-repositories.ts b/backend/test/mocks/mock-code-table-repositories.ts index 2f4250c17..94811b4b3 100644 --- a/backend/test/mocks/mock-code-table-repositories.ts +++ b/backend/test/mocks/mock-code-table-repositories.ts @@ -49,6 +49,11 @@ const organizationUnits = [ { organizationUnit: "CHTWD", shortDescription: "Chetwynd", longDescription: "Chetwynd", organizationUnitType: "OFFLOC", }, ]; +const personTypes = [ + { "person_complaint_xref_code": "ASSIGNEE", "short_description": "Officer Assigned", "long_description": "The person to whom the complaint is assigned to.", "display_order": 1, }, + { "person_complaint_xref_code": "TEST", "short_description": "TEST", "long_description": "Test person type", "display_order": 2, } +] + const single = (name: string = "default", idx: number = 0): any => { switch (name) { case "agency": { @@ -69,6 +74,9 @@ const single = (name: string = "default", idx: number = 0): any => { ? natureOfComplaints[idx] : natureOfComplaints[0]; } + case "person-complaint": { + return idx <= personTypes.length ? personTypes[idx] : personTypes[0]; + } case "default": default: return null; @@ -121,10 +129,19 @@ export const MockOrganizationUnitTypeCodeTableRepository = () => ({ }); export const MockOrganizationUnitCodeTableRepository = () => ({ - find: jest.fn().mockResolvedValue(organizationUnits), - createQueryBuilder: jest.fn(() => ({ - leftJoinAndSelect: jest.fn().mockReturnThis(), - where: jest.fn().mockReturnThis(), - getMany: jest.fn().mockResolvedValue(organizationUnits), - })), - }); + find: jest.fn().mockResolvedValue(organizationUnits), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(organizationUnits), + })), +}); + +export const MockPersonComplaintCodeTableRepository = () => ({ + find: jest.fn().mockResolvedValue(personTypes), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(personTypes), + })), +}); From c0af1f0f0b0b7caa0e2d9bd1b4f7a20b72a602ea Mon Sep 17 00:00:00 2001 From: Mike Sears Date: Sun, 5 Nov 2023 21:06:13 -0800 Subject: [PATCH 12/21] species code table implemented --- backend/src/types/models/code-tables/index.ts | 13 ++++++++- .../src/types/models/code-tables/species.ts | 6 ++++ .../code-table/code-table.controller.spec.ts | 27 +++++++++++++---- .../src/v1/code-table/code-table.module.ts | 4 +++ .../v1/code-table/code-table.service.spec.ts | 21 +++++++++++++- .../src/v1/code-table/code-table.service.ts | 29 +++++++++++++++++++ .../mocks/mock-code-table-repositories.ts | 21 ++++++++++++++ 7 files changed, 113 insertions(+), 8 deletions(-) create mode 100644 backend/src/types/models/code-tables/species.ts diff --git a/backend/src/types/models/code-tables/index.ts b/backend/src/types/models/code-tables/index.ts index e1c04aee4..eb84a0908 100644 --- a/backend/src/types/models/code-tables/index.ts +++ b/backend/src/types/models/code-tables/index.ts @@ -5,6 +5,9 @@ import { ComplaintStatus } from "./complaint-status"; import { NatureOfComplaint } from "./nature-of-complaint"; import { OrganizationUnitType } from "./organization-unit-type"; import { PersonComplaintType } from "./person-complaint-type"; +import { Species } from "./species"; + + export const AvailableCodeTables = [ "agency", @@ -20,4 +23,12 @@ export const AvailableCodeTables = [ ]; export default CodeTable; -export { Agency, Attractant, ComplaintStatus, NatureOfComplaint, OrganizationUnitType, PersonComplaintType }; +export { + Agency, + Attractant, + ComplaintStatus, + NatureOfComplaint, + OrganizationUnitType, + PersonComplaintType, + Species +}; diff --git a/backend/src/types/models/code-tables/species.ts b/backend/src/types/models/code-tables/species.ts new file mode 100644 index 000000000..c40204ae8 --- /dev/null +++ b/backend/src/types/models/code-tables/species.ts @@ -0,0 +1,6 @@ +import { CodeTable } from "../../models/code-tables/code-table"; + +export interface Species extends CodeTable { + species: string; + legacy: string; +} diff --git a/backend/src/v1/code-table/code-table.controller.spec.ts b/backend/src/v1/code-table/code-table.controller.spec.ts index d675603c4..0748ebdd0 100644 --- a/backend/src/v1/code-table/code-table.controller.spec.ts +++ b/backend/src/v1/code-table/code-table.controller.spec.ts @@ -10,7 +10,16 @@ import { JwtRoleGuard } from "../../auth/jwtrole.guard"; import { CodeTableController } from "./code-table.controller"; import { CodeTableService } from "./code-table.service"; -import { MockAgencyCodeTableRepository, MockAttractantCodeTableRepository, MockComplaintStatusCodeTableRepository, MockNatureOfComplaintCodeTableRepository, MockOrganizationUnitCodeTableRepository, MockOrganizationUnitTypeCodeTableRepository, MockPersonComplaintCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; +import { + MockAgencyCodeTableRepository, + MockAttractantCodeTableRepository, + MockComplaintStatusCodeTableRepository, + MockNatureOfComplaintCodeTableRepository, + MockOrganizationUnitCodeTableRepository, + MockOrganizationUnitTypeCodeTableRepository, + MockPersonComplaintCodeTableRepository, + MockSpeciesCodeTableRepository, +} from "../../../test/mocks/mock-code-table-repositories"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; import { ComplaintStatusCode } from "../complaint_status_code/entities/complaint_status_code.entity"; @@ -18,6 +27,7 @@ import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/ import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/geo_organization_unit_code.entity"; import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/person_complaint_xref_code.entity"; +import { SpeciesCode } from "../species_code/entities/species_code.entity"; describe("Testing: CodeTable Controller", () => { let app: INestApplication; @@ -56,12 +66,17 @@ describe("Testing: CodeTable Controller", () => { provide: getRepositoryToken(PersonComplaintXrefCode), useFactory: MockPersonComplaintCodeTableRepository, }, + { + provide: getRepositoryToken(SpeciesCode), + useFactory: MockSpeciesCodeTableRepository, + }, ], - }) .overrideGuard(JwtAuthGuard) - .useValue({ authGuardMock }) - .overrideGuard(JwtRoleGuard) - .useValue({ roleGuardMock }) - .compile(); + }) + .overrideGuard(JwtAuthGuard) + .useValue({ authGuardMock }) + .overrideGuard(JwtRoleGuard) + .useValue({ roleGuardMock }) + .compile(); app = module.createNestApplication(); await app.init(); diff --git a/backend/src/v1/code-table/code-table.module.ts b/backend/src/v1/code-table/code-table.module.ts index d884963cf..2b089f598 100644 --- a/backend/src/v1/code-table/code-table.module.ts +++ b/backend/src/v1/code-table/code-table.module.ts @@ -9,6 +9,8 @@ import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/ import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/geo_organization_unit_code.entity"; import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/person_complaint_xref_code.entity"; +import { SpeciesCode } from "../species_code/entities/species_code.entity"; +import { ViolationCode } from "../violation_code/entities/violation_code.entity"; @Module({ imports: [ @@ -19,6 +21,8 @@ import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/ TypeOrmModule.forFeature([GeoOrgUnitTypeCode]), TypeOrmModule.forFeature([GeoOrganizationUnitCode]), TypeOrmModule.forFeature([PersonComplaintXrefCode]), + TypeOrmModule.forFeature([SpeciesCode]), + TypeOrmModule.forFeature([ViolationCode]), ], controllers: [CodeTableController], providers: [CodeTableService], diff --git a/backend/src/v1/code-table/code-table.service.spec.ts b/backend/src/v1/code-table/code-table.service.spec.ts index ceb26bc7e..12c4343f8 100644 --- a/backend/src/v1/code-table/code-table.service.spec.ts +++ b/backend/src/v1/code-table/code-table.service.spec.ts @@ -12,12 +12,14 @@ import { MockNatureOfComplaintCodeTableRepository, MockOrganizationUnitCodeTableRepository, MockOrganizationUnitTypeCodeTableRepository, - MockPersonComplaintCodeTableRepository + MockPersonComplaintCodeTableRepository, + MockSpeciesCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/geo_organization_unit_code.entity"; import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/person_complaint_xref_code.entity"; +import { SpeciesCode } from "../species_code/entities/species_code.entity"; describe("Testing: CodeTable Service", () => { let service: CodeTableService; @@ -54,6 +56,10 @@ describe("Testing: CodeTable Service", () => { provide: getRepositoryToken(PersonComplaintXrefCode), useFactory: MockPersonComplaintCodeTableRepository, }, + { + provide: getRepositoryToken(SpeciesCode), + useFactory: MockSpeciesCodeTableRepository, + }, ], }).compile(); @@ -154,4 +160,17 @@ describe("Testing: CodeTable Service", () => { expect(results.length).not.toBe(0); expect(results.length).toBe(2); }); + + it("should return collection of species", async () => { + //-- arrange + const _tableName = "species"; + + //-- act + const results = await service.getCodeTableByName(_tableName); + + //-- assert + expect(results).not.toBe(null); + expect(results.length).not.toBe(0); + expect(results.length).toBe(6); + }); }); diff --git a/backend/src/v1/code-table/code-table.service.ts b/backend/src/v1/code-table/code-table.service.ts index cc732bf7e..6bbcc40c1 100644 --- a/backend/src/v1/code-table/code-table.service.ts +++ b/backend/src/v1/code-table/code-table.service.ts @@ -9,6 +9,7 @@ import CodeTable, { NatureOfComplaint, OrganizationUnitType, PersonComplaintType, + Species, } from "../../types/models/code-tables"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; @@ -18,6 +19,7 @@ import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_u import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/geo_organization_unit_code.entity"; import { OrganizationUnit } from "src/types/models/code-tables/organization-unit"; import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/person_complaint_xref_code.entity"; +import { SpeciesCode } from "../species_code/entities/species_code.entity"; @Injectable() export class CodeTableService { @@ -37,6 +39,9 @@ export class CodeTableService { private _organizationUnitRepository: Repository; @InjectRepository(PersonComplaintXrefCode) private _personComplaintTypeRepository: Repository; + @InjectRepository(SpeciesCode) + private _speciesRepository: Repository; + getCodeTableByName = async (table: string): Promise => { switch (table) { @@ -206,6 +211,30 @@ export class CodeTableService { ); return results; } + case "species": { + const data = await this._speciesRepository.find(); + let results = data.map( + ({ + species_code, + short_description, + long_description, + display_order, + active_ind, + legacy_code + }) => { + let table: Species = { + species: species_code, + legacy: legacy_code, + shortDescription: short_description, + longDescription: long_description, + displayOrder: display_order, + isActive: active_ind, + }; + return table; + } + ); + return results; + } } }; } diff --git a/backend/test/mocks/mock-code-table-repositories.ts b/backend/test/mocks/mock-code-table-repositories.ts index 94811b4b3..67873e4ed 100644 --- a/backend/test/mocks/mock-code-table-repositories.ts +++ b/backend/test/mocks/mock-code-table-repositories.ts @@ -54,6 +54,14 @@ const personTypes = [ { "person_complaint_xref_code": "TEST", "short_description": "TEST", "long_description": "Test person type", "display_order": 2, } ] +const species = [ + { "species_code": "BISON", "short_description": "Bison", "long_description": "Bison", "display_order": 1, "active_ind": true, "legacy_code": null, }, + { "species_code": "BLKBEAR", "short_description": "Black Bear", "long_description": "Black Bear", "display_order": 2, "active_ind": true, "legacy_code": null, }, + { "species_code": "BOBCAT", "short_description": "Bobcat", "long_description": "Bobcat", "display_order": 3, "active_ind": true, "legacy_code": null, }, + { "species_code": "COUGAR", "short_description": "Cougar", "long_description": "Cougar", "display_order": 4, "active_ind": true, "legacy_code": null, }, + { "species_code": "COYOTE", "short_description": "Coyote", "long_description": "Coyote", "display_order": 5, "active_ind": true, "legacy_code": null, }, + { "species_code": "DEER", "short_description": "Deer", "long_description": "Deer", "display_order": 6, "active_ind": true, "legacy_code": null, }] + const single = (name: string = "default", idx: number = 0): any => { switch (name) { case "agency": { @@ -77,6 +85,9 @@ const single = (name: string = "default", idx: number = 0): any => { case "person-complaint": { return idx <= personTypes.length ? personTypes[idx] : personTypes[0]; } + case "species": { + return idx <= species.length ? species[idx] : species[0]; + } case "default": default: return null; @@ -145,3 +156,13 @@ export const MockPersonComplaintCodeTableRepository = () => ({ getMany: jest.fn().mockResolvedValue(personTypes), })), }); + +export const MockSpeciesCodeTableRepository = () => ({ + find: jest.fn().mockResolvedValue(species), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(species), + })), + }); + \ No newline at end of file From 8753b6f4fe8589b8b36b8b0df31904d364c9fd36 Mon Sep 17 00:00:00 2001 From: Mike Sears Date: Sun, 5 Nov 2023 21:16:20 -0800 Subject: [PATCH 13/21] violation types implemented --- backend/src/types/models/code-tables/index.ts | 8 ++++-- .../src/types/models/code-tables/violation.ts | 5 ++++ .../code-table/code-table.controller.spec.ts | 6 ++++ .../v1/code-table/code-table.service.spec.ts | 21 +++++++++++++- .../src/v1/code-table/code-table.service.ts | 28 ++++++++++++++++++- .../mocks/mock-code-table-repositories.ts | 21 ++++++++++++++ 6 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 backend/src/types/models/code-tables/violation.ts diff --git a/backend/src/types/models/code-tables/index.ts b/backend/src/types/models/code-tables/index.ts index eb84a0908..360a8cfaa 100644 --- a/backend/src/types/models/code-tables/index.ts +++ b/backend/src/types/models/code-tables/index.ts @@ -4,10 +4,10 @@ import { Attractant } from "./attractant"; import { ComplaintStatus } from "./complaint-status"; import { NatureOfComplaint } from "./nature-of-complaint"; import { OrganizationUnitType } from "./organization-unit-type"; +import { OrganizationUnit } from "./organization-unit"; import { PersonComplaintType } from "./person-complaint-type"; import { Species } from "./species"; - - +import { Violation } from "./violation"; export const AvailableCodeTables = [ "agency", @@ -29,6 +29,8 @@ export { ComplaintStatus, NatureOfComplaint, OrganizationUnitType, + OrganizationUnit, PersonComplaintType, - Species + Species, + Violation }; diff --git a/backend/src/types/models/code-tables/violation.ts b/backend/src/types/models/code-tables/violation.ts new file mode 100644 index 000000000..9570077f9 --- /dev/null +++ b/backend/src/types/models/code-tables/violation.ts @@ -0,0 +1,5 @@ +import { CodeTable } from "../../models/code-tables/code-table"; + +export interface Violation extends CodeTable { + violation: string +} \ No newline at end of file diff --git a/backend/src/v1/code-table/code-table.controller.spec.ts b/backend/src/v1/code-table/code-table.controller.spec.ts index 0748ebdd0..a6e12decc 100644 --- a/backend/src/v1/code-table/code-table.controller.spec.ts +++ b/backend/src/v1/code-table/code-table.controller.spec.ts @@ -19,6 +19,7 @@ import { MockOrganizationUnitTypeCodeTableRepository, MockPersonComplaintCodeTableRepository, MockSpeciesCodeTableRepository, + MockViolationsCodeTableRepository, } from "../../../test/mocks/mock-code-table-repositories"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; @@ -28,6 +29,7 @@ import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_u import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/geo_organization_unit_code.entity"; import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/person_complaint_xref_code.entity"; import { SpeciesCode } from "../species_code/entities/species_code.entity"; +import { ViolationCode } from "../violation_code/entities/violation_code.entity"; describe("Testing: CodeTable Controller", () => { let app: INestApplication; @@ -70,6 +72,10 @@ describe("Testing: CodeTable Controller", () => { provide: getRepositoryToken(SpeciesCode), useFactory: MockSpeciesCodeTableRepository, }, + { + provide: getRepositoryToken(ViolationCode), + useFactory: MockViolationsCodeTableRepository, + }, ], }) .overrideGuard(JwtAuthGuard) diff --git a/backend/src/v1/code-table/code-table.service.spec.ts b/backend/src/v1/code-table/code-table.service.spec.ts index 12c4343f8..e189be55a 100644 --- a/backend/src/v1/code-table/code-table.service.spec.ts +++ b/backend/src/v1/code-table/code-table.service.spec.ts @@ -13,13 +13,15 @@ import { MockOrganizationUnitCodeTableRepository, MockOrganizationUnitTypeCodeTableRepository, MockPersonComplaintCodeTableRepository, - MockSpeciesCodeTableRepository + MockSpeciesCodeTableRepository, + MockViolationsCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/geo_organization_unit_code.entity"; import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/person_complaint_xref_code.entity"; import { SpeciesCode } from "../species_code/entities/species_code.entity"; +import { ViolationCode } from "../violation_code/entities/violation_code.entity"; describe("Testing: CodeTable Service", () => { let service: CodeTableService; @@ -60,6 +62,10 @@ describe("Testing: CodeTable Service", () => { provide: getRepositoryToken(SpeciesCode), useFactory: MockSpeciesCodeTableRepository, }, + { + provide: getRepositoryToken(ViolationCode), + useFactory: MockViolationsCodeTableRepository, + }, ], }).compile(); @@ -173,4 +179,17 @@ describe("Testing: CodeTable Service", () => { expect(results.length).not.toBe(0); expect(results.length).toBe(6); }); + + it("should return collection of violations", async () => { + //-- arrange + const _tableName = "violation"; + + //-- act + const results = await service.getCodeTableByName(_tableName); + + //-- assert + expect(results).not.toBe(null); + expect(results.length).not.toBe(0); + expect(results.length).toBe(9); + }); }); diff --git a/backend/src/v1/code-table/code-table.service.ts b/backend/src/v1/code-table/code-table.service.ts index 6bbcc40c1..c49934342 100644 --- a/backend/src/v1/code-table/code-table.service.ts +++ b/backend/src/v1/code-table/code-table.service.ts @@ -8,8 +8,10 @@ import CodeTable, { ComplaintStatus, NatureOfComplaint, OrganizationUnitType, + OrganizationUnit, PersonComplaintType, Species, + Violation, } from "../../types/models/code-tables"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; @@ -17,9 +19,9 @@ import { ComplaintStatusCode } from "../complaint_status_code/entities/complaint import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/geo_organization_unit_code.entity"; -import { OrganizationUnit } from "src/types/models/code-tables/organization-unit"; import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/person_complaint_xref_code.entity"; import { SpeciesCode } from "../species_code/entities/species_code.entity"; +import { ViolationCode } from "../violation_code/entities/violation_code.entity"; @Injectable() export class CodeTableService { @@ -41,6 +43,8 @@ export class CodeTableService { private _personComplaintTypeRepository: Repository; @InjectRepository(SpeciesCode) private _speciesRepository: Repository; + @InjectRepository(ViolationCode) + private _violationsRepository: Repository; getCodeTableByName = async (table: string): Promise => { @@ -235,6 +239,28 @@ export class CodeTableService { ); return results; } + case "violation": { + const data = await this._violationsRepository.find(); + let results = data.map( + ({ + violation_code, + short_description, + long_description, + display_order, + active_ind, + }) => { + let table: Violation = { + violation: violation_code, + shortDescription: short_description, + longDescription: long_description, + displayOrder: display_order, + isActive: active_ind, + }; + return table; + } + ); + return results; + } } }; } diff --git a/backend/test/mocks/mock-code-table-repositories.ts b/backend/test/mocks/mock-code-table-repositories.ts index 67873e4ed..f71845fb3 100644 --- a/backend/test/mocks/mock-code-table-repositories.ts +++ b/backend/test/mocks/mock-code-table-repositories.ts @@ -62,6 +62,18 @@ const species = [ { "species_code": "COYOTE", "short_description": "Coyote", "long_description": "Coyote", "display_order": 5, "active_ind": true, "legacy_code": null, }, { "species_code": "DEER", "short_description": "Deer", "long_description": "Deer", "display_order": 6, "active_ind": true, "legacy_code": null, }] +const violations = [ + { "violation_code": "AINVSPC", "short_description": "AINVSPC", "long_description": "Aquatic: Invasive Species", "display_order": 1, "active_ind": true, }, + { "violation_code": "BOATING", "short_description": "BOATING", "long_description": "Boating", "display_order": 2, "active_ind": true, }, + { "violation_code": "DUMPING", "short_description": "DUMPING", "long_description": "Dumping", "display_order": 3, "active_ind": true, }, + { "violation_code": "FISHERY", "short_description": "FISHERY", "long_description": "Fisheries", "display_order": 4, "active_ind": true, }, + { "violation_code": "ORV", "short_description": "ORV", "long_description": "Off-road vehicles (ORV)", "display_order": 5, "active_ind": true, }, + { "violation_code": "OPENBURN", "short_description": "OPENBURN", "long_description": "Open Burning", "display_order": 6, "active_ind": true, }, + { "violation_code": "OTHER", "short_description": "OTHER", "long_description": "Other", "display_order": 7, "active_ind": true, }, + { "violation_code": "PESTICDE", "short_description": "PESTICDE", "long_description": "Pesticide", "display_order": 8, "active_ind": true, }, + { "violation_code": "RECREATN", "short_description": "RECREATN", "long_description": "Recreation sites/ trails", "display_order": 9, "active_ind": true, } +] + const single = (name: string = "default", idx: number = 0): any => { switch (name) { case "agency": { @@ -165,4 +177,13 @@ export const MockSpeciesCodeTableRepository = () => ({ getMany: jest.fn().mockResolvedValue(species), })), }); + +export const MockViolationsCodeTableRepository = () => ({ + find: jest.fn().mockResolvedValue(violations), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(violations), + })), + }); \ No newline at end of file From 3d0c5947f16e7982e77b17a4c95438b9e6e4d3a9 Mon Sep 17 00:00:00 2001 From: Mike Sears Date: Mon, 6 Nov 2023 11:34:42 -0800 Subject: [PATCH 14/21] added functionality to get organization units by agency --- backend/src/types/models/code-tables/index.ts | 9 +++- .../code-tables/organization-code-table.ts | 10 +++++ .../code-table/code-table.controller.spec.ts | 24 ++++++++++ .../v1/code-table/code-table.controller.ts | 15 ++++++- .../src/v1/code-table/code-table.module.ts | 2 + .../v1/code-table/code-table.service.spec.ts | 21 ++++++++- .../src/v1/code-table/code-table.service.ts | 45 +++++++++++++++++-- .../mocks/mock-code-table-repositories.ts | 26 +++++++++++ 8 files changed, 145 insertions(+), 7 deletions(-) create mode 100644 backend/src/types/models/code-tables/organization-code-table.ts diff --git a/backend/src/types/models/code-tables/index.ts b/backend/src/types/models/code-tables/index.ts index 360a8cfaa..816dd46fc 100644 --- a/backend/src/types/models/code-tables/index.ts +++ b/backend/src/types/models/code-tables/index.ts @@ -8,6 +8,7 @@ import { OrganizationUnit } from "./organization-unit"; import { PersonComplaintType } from "./person-complaint-type"; import { Species } from "./species"; import { Violation } from "./violation"; +import { OrganizationCodeTable } from "./organization-code-table"; export const AvailableCodeTables = [ "agency", @@ -20,8 +21,13 @@ export const AvailableCodeTables = [ "person-complaint", "species", "violation", + "cos-organization-unit" ]; +export const AvailableAgencies = [ + "cos" +] + export default CodeTable; export { Agency, @@ -32,5 +38,6 @@ export { OrganizationUnit, PersonComplaintType, Species, - Violation + Violation, + OrganizationCodeTable }; diff --git a/backend/src/types/models/code-tables/organization-code-table.ts b/backend/src/types/models/code-tables/organization-code-table.ts new file mode 100644 index 000000000..b70d592cd --- /dev/null +++ b/backend/src/types/models/code-tables/organization-code-table.ts @@ -0,0 +1,10 @@ +export interface OrganizationCodeTable { + areaName: string; + officeLocationName: string; + regionName: string; + zoneName: string; + area: string; + officeLocation: string; + region: string; + zone: string; +} diff --git a/backend/src/v1/code-table/code-table.controller.spec.ts b/backend/src/v1/code-table/code-table.controller.spec.ts index a6e12decc..8c7777d03 100644 --- a/backend/src/v1/code-table/code-table.controller.spec.ts +++ b/backend/src/v1/code-table/code-table.controller.spec.ts @@ -14,6 +14,7 @@ import { MockAgencyCodeTableRepository, MockAttractantCodeTableRepository, MockComplaintStatusCodeTableRepository, + MockCosOrganizationUnitCodeTableRepository, MockNatureOfComplaintCodeTableRepository, MockOrganizationUnitCodeTableRepository, MockOrganizationUnitTypeCodeTableRepository, @@ -30,6 +31,7 @@ import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/ import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/person_complaint_xref_code.entity"; import { SpeciesCode } from "../species_code/entities/species_code.entity"; import { ViolationCode } from "../violation_code/entities/violation_code.entity"; +import { CosGeoOrgUnit } from "../cos_geo_org_unit/entities/cos_geo_org_unit.entity"; describe("Testing: CodeTable Controller", () => { let app: INestApplication; @@ -76,6 +78,10 @@ describe("Testing: CodeTable Controller", () => { provide: getRepositoryToken(ViolationCode), useFactory: MockViolationsCodeTableRepository, }, + { + provide: getRepositoryToken(CosGeoOrgUnit), + useFactory: MockCosOrganizationUnitCodeTableRepository, + }, ], }) .overrideGuard(JwtAuthGuard) @@ -97,12 +103,18 @@ describe("Testing: CodeTable Controller", () => { it("should return 200 when a GET is called successfully", async () => { //-- arrange const _tableName = "agency"; + const _agency = "cos"; //-- act let response = await request(app.getHttpServer()).get( `/code-table/${_tableName}` ); expect(response.statusCode).toBe(200); + + response = await request(app.getHttpServer()).get( + `/code-table/organization-by-agency/${_agency}` + ); + expect(response.statusCode).toBe(200); }); it("should return 404 when a requesting code table that doesn't exist", async () => { @@ -115,4 +127,16 @@ describe("Testing: CodeTable Controller", () => { ); expect(response.statusCode).toBe(404); }); + + it("should return 404 when a requesting organization by an agency doesn't exist", async () => { + //-- arrange + const _agency = "test"; + + //-- act + let response = await request(app.getHttpServer()).get( + `/code-table/organization-by-agency/${_agency}` + ); + expect(response.statusCode).toBe(404); + }); + }); diff --git a/backend/src/v1/code-table/code-table.controller.ts b/backend/src/v1/code-table/code-table.controller.ts index 688fb637c..676287fac 100644 --- a/backend/src/v1/code-table/code-table.controller.ts +++ b/backend/src/v1/code-table/code-table.controller.ts @@ -6,7 +6,7 @@ import { Role } from '../../enum/role.enum'; import { Roles } from '../../auth/decorators/roles.decorator'; import { JwtRoleGuard } from '../../auth/jwtrole.guard'; -import CodeTable, { AvailableCodeTables } from "../../types/models/code-tables" +import CodeTable, { AvailableAgencies, AvailableCodeTables, OrganizationCodeTable } from "../../types/models/code-tables" @UseGuards(JwtRoleGuard) @ApiTags("code-table") @@ -26,4 +26,17 @@ export class CodeTableController { const result = await this.service.getCodeTableByName(table); return result; } + + @Get("/organization-by-agency/:agency") + @Roles(Role.COS_OFFICER) + async getOrganizationsByAgency( + @Param("agency") agency: string + ): Promise { + if(!AvailableAgencies.includes(agency)){ + throw new NotFoundException(); + } + + const result = await this.service.getOrganizationsByAgency(agency); + return result; + } } diff --git a/backend/src/v1/code-table/code-table.module.ts b/backend/src/v1/code-table/code-table.module.ts index 2b089f598..1fa0bbcca 100644 --- a/backend/src/v1/code-table/code-table.module.ts +++ b/backend/src/v1/code-table/code-table.module.ts @@ -11,6 +11,7 @@ import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/ import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/person_complaint_xref_code.entity"; import { SpeciesCode } from "../species_code/entities/species_code.entity"; import { ViolationCode } from "../violation_code/entities/violation_code.entity"; +import { CosGeoOrgUnit } from "../cos_geo_org_unit/entities/cos_geo_org_unit.entity"; @Module({ imports: [ @@ -23,6 +24,7 @@ import { ViolationCode } from "../violation_code/entities/violation_code.entity" TypeOrmModule.forFeature([PersonComplaintXrefCode]), TypeOrmModule.forFeature([SpeciesCode]), TypeOrmModule.forFeature([ViolationCode]), + TypeOrmModule.forFeature([CosGeoOrgUnit]), ], controllers: [CodeTableController], providers: [CodeTableService], diff --git a/backend/src/v1/code-table/code-table.service.spec.ts b/backend/src/v1/code-table/code-table.service.spec.ts index e189be55a..154ab1b43 100644 --- a/backend/src/v1/code-table/code-table.service.spec.ts +++ b/backend/src/v1/code-table/code-table.service.spec.ts @@ -14,7 +14,8 @@ import { MockOrganizationUnitTypeCodeTableRepository, MockPersonComplaintCodeTableRepository, MockSpeciesCodeTableRepository, - MockViolationsCodeTableRepository + MockViolationsCodeTableRepository, + MockCosOrganizationUnitCodeTableRepository } from "../../../test/mocks/mock-code-table-repositories"; import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; @@ -22,6 +23,7 @@ import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/ import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/person_complaint_xref_code.entity"; import { SpeciesCode } from "../species_code/entities/species_code.entity"; import { ViolationCode } from "../violation_code/entities/violation_code.entity"; +import { CosGeoOrgUnit } from "../cos_geo_org_unit/entities/cos_geo_org_unit.entity"; describe("Testing: CodeTable Service", () => { let service: CodeTableService; @@ -66,6 +68,10 @@ describe("Testing: CodeTable Service", () => { provide: getRepositoryToken(ViolationCode), useFactory: MockViolationsCodeTableRepository, }, + { + provide: getRepositoryToken(CosGeoOrgUnit), + useFactory: MockCosOrganizationUnitCodeTableRepository, + }, ], }).compile(); @@ -192,4 +198,17 @@ describe("Testing: CodeTable Service", () => { expect(results.length).not.toBe(0); expect(results.length).toBe(9); }); + + it("should return collection of organization by agency", async () => { + //-- arrange + const _agency = "cos"; + + //-- act + const results = await service.getOrganizationsByAgency(_agency) + + //-- assert + expect(results).not.toBe(null); + expect(results.length).not.toBe(0); + expect(results.length).toBe(14); + }); }); diff --git a/backend/src/v1/code-table/code-table.service.ts b/backend/src/v1/code-table/code-table.service.ts index c49934342..d4daa40f1 100644 --- a/backend/src/v1/code-table/code-table.service.ts +++ b/backend/src/v1/code-table/code-table.service.ts @@ -12,6 +12,7 @@ import CodeTable, { PersonComplaintType, Species, Violation, + OrganizationCodeTable, } from "../../types/models/code-tables"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; @@ -22,6 +23,7 @@ import { GeoOrganizationUnitCode } from "../geo_organization_unit_code/entities/ import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/person_complaint_xref_code.entity"; import { SpeciesCode } from "../species_code/entities/species_code.entity"; import { ViolationCode } from "../violation_code/entities/violation_code.entity"; +import { CosGeoOrgUnit } from "../cos_geo_org_unit/entities/cos_geo_org_unit.entity"; @Injectable() export class CodeTableService { @@ -45,7 +47,8 @@ export class CodeTableService { private _speciesRepository: Repository; @InjectRepository(ViolationCode) private _violationsRepository: Repository; - + @InjectRepository(CosGeoOrgUnit) + private _cosOrganizationUnitRepository: Repository; getCodeTableByName = async (table: string): Promise => { switch (table) { @@ -213,7 +216,7 @@ export class CodeTableService { return table; } ); - return results; + return results; } case "species": { const data = await this._speciesRepository.find(); @@ -224,7 +227,7 @@ export class CodeTableService { long_description, display_order, active_ind, - legacy_code + legacy_code, }) => { let table: Species = { species: species_code, @@ -237,7 +240,7 @@ export class CodeTableService { return table; } ); - return results; + return results; } case "violation": { const data = await this._violationsRepository.find(); @@ -263,4 +266,38 @@ export class CodeTableService { } } }; + + getOrganizationsByAgency = async ( + agency: string + ): Promise => { + const data = await this._cosOrganizationUnitRepository.find(); + + const results = data.map( + ({ + area_code: area, + area_name: areaName, + office_location_code: officeLocation, + office_location_name: officeLocationName, + region_name: regionName, + region_code: region, + zone_name: zoneName, + zone_code: zone, + }) => { + let record: OrganizationCodeTable = { + area, + areaName, + officeLocation, + officeLocationName, + regionName, + region, + zone, + zoneName + }; + + return record; + } + ); + + return results; + }; } diff --git a/backend/test/mocks/mock-code-table-repositories.ts b/backend/test/mocks/mock-code-table-repositories.ts index f71845fb3..ea0e4eec9 100644 --- a/backend/test/mocks/mock-code-table-repositories.ts +++ b/backend/test/mocks/mock-code-table-repositories.ts @@ -74,6 +74,23 @@ const violations = [ { "violation_code": "RECREATN", "short_description": "RECREATN", "long_description": "Recreation sites/ trails", "display_order": 9, "active_ind": true, } ] +const cosOrganizationUnits = [ + { "zone_code": "CLMBAKTNY", "region_code": "KTNY", "region_name": "Kootenay", "zone_name": "Columbia/Kootenay", "office_location_code": "GLDN", "office_location_name": "Golden", "area_code": "BLBRY", "area_name": "Blaeberry" }, + { "zone_code": "CLMBAKTNY", "region_code": "KTNY", "region_name": "Kootenay", "zone_name": "Columbia/Kootenay", "office_location_code": "GLDN", "office_location_name": "Golden", "area_code": "BRS", "area_name": "Brisco" }, + { "zone_code": "CLMBAKTNY", "region_code": "KTNY", "region_name": "Kootenay", "zone_name": "Columbia/Kootenay", "office_location_code": "GLDN", "office_location_name": "Golden", "area_code": "CMB", "area_name": "Cambie" }, + { "zone_code": "CLMBAKTNY", "region_code": "KTNY", "region_name": "Kootenay", "zone_name": "Columbia/Kootenay", "office_location_code": "GLDN", "office_location_name": "Golden", "area_code": "CMRNE", "area_name": "Camborne" }, + { "zone_code": "CLMBAKTNY", "region_code": "KTNY", "region_name": "Kootenay", "zone_name": "Columbia/Kootenay", "office_location_code": "GLDN", "office_location_name": "Golden", "area_code": "CRSRLAKE", "area_name": "Coursier Lake" }, + { "zone_code": "CLMBAKTNY", "region_code": "KTNY", "region_name": "Kootenay", "zone_name": "Columbia/Kootenay", "office_location_code": "GLDN", "office_location_name": "Golden", "area_code": "DONALD", "area_name": "Donald" }, + { "zone_code": "CLMBAKTNY", "region_code": "KTNY", "region_name": "Kootenay", "zone_name": "Columbia/Kootenay", "office_location_code": "GLDN", "office_location_name": "Golden", "area_code": "FTRESSLK", "area_name": "Fortress Lake" }, + { "zone_code": "CLMBAKTNY", "region_code": "KTNY", "region_name": "Kootenay", "zone_name": "Columbia/Kootenay", "office_location_code": "GLDN", "office_location_name": "Golden", "area_code": "GOLDEN", "area_name": "Golden" }, + { "zone_code": "CLMBAKTNY", "region_code": "KTNY", "region_name": "Kootenay", "zone_name": "Columbia/Kootenay", "office_location_code": "GLDN", "office_location_name": "Golden", "area_code": "GRIFFNLK", "area_name": "Griffin Lake" }, + { "zone_code": "CLMBAKTNY", "region_code": "KTNY", "region_name": "Kootenay", "zone_name": "Columbia/Kootenay", "office_location_code": "GLDN", "office_location_name": "Golden", "area_code": "HARROGAT", "area_name": "Harrogate" }, + { "zone_code": "CLMBAKTNY", "region_code": "KTNY", "region_name": "Kootenay", "zone_name": "Columbia/Kootenay", "office_location_code": "GLDN", "office_location_name": "Golden", "area_code": "KINABSKT", "area_name": "Kinabasket Lake" }, + { "zone_code": "CLMBAKTNY", "region_code": "KTNY", "region_name": "Kootenay", "zone_name": "Columbia/Kootenay", "office_location_code": "GLDN", "office_location_name": "Golden", "area_code": "MCMURDO", "area_name": "McMurdo" }, + { "zone_code": "CLMBAKTNY", "region_code": "KTNY", "region_name": "Kootenay", "zone_name": "Columbia/Kootenay", "office_location_code": "GLDN", "office_location_name": "Golden", "area_code": "NICHOLN", "area_name": "Nicholson" }, + { "zone_code": "CLMBAKTNY", "region_code": "KTNY", "region_name": "Kootenay", "zone_name": "Columbia/Kootenay", "office_location_code": "GLDN", "office_location_name": "Golden", "area_code": "PARSON", "area_name": "Parson" } +] + const single = (name: string = "default", idx: number = 0): any => { switch (name) { case "agency": { @@ -186,4 +203,13 @@ export const MockViolationsCodeTableRepository = () => ({ getMany: jest.fn().mockResolvedValue(violations), })), }); + + export const MockCosOrganizationUnitCodeTableRepository = () => ({ + find: jest.fn().mockResolvedValue(cosOrganizationUnits), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(cosOrganizationUnits), + })), + }); \ No newline at end of file From dd89e01cabd8b9105d7c350b2d733bb0c3415adc Mon Sep 17 00:00:00 2001 From: Mike Sears Date: Tue, 7 Nov 2023 15:22:21 -0800 Subject: [PATCH 15/21] backend models migrated to frontend --- backend/src/types/models/code-tables/agency.ts | 4 ++-- backend/src/types/models/code-tables/attractant.ts | 4 ++-- backend/src/types/models/code-tables/code-table.ts | 2 +- .../src/types/models/code-tables/complaint-status.ts | 4 ++-- backend/src/types/models/code-tables/index.ts | 4 ++-- .../types/models/code-tables/nature-of-complaint.ts | 4 ++-- .../types/models/code-tables/organization-unit-type.ts | 4 ++-- .../src/types/models/code-tables/organization-unit.ts | 4 ++-- .../types/models/code-tables/person-complaint-type.ts | 4 ++-- backend/src/types/models/code-tables/species.ts | 4 ++-- backend/src/types/models/code-tables/violation.ts | 4 ++-- backend/src/v1/code-table/code-table.controller.ts | 4 ++-- backend/src/v1/code-table/code-table.service.ts | 4 ++-- frontend/src/app/types/app/code-tables/agency.ts | 5 +++++ frontend/src/app/types/app/code-tables/attactant.ts | 5 +++++ .../src/app/types/app/code-tables/base-code-table.ts | 7 +++++++ .../src/app/types/app/code-tables/complaint-status.ts | 5 +++++ .../app/types/app/code-tables/nature-of-complaint.ts | 5 +++++ .../types/app/code-tables/organization-code-table.ts | 10 ++++++++++ .../types/app/code-tables/organization-unit-type.ts | 5 +++++ .../src/app/types/app/code-tables/organization-unit.ts | 6 ++++++ .../app/types/app/code-tables/person-complaint-type.ts | 5 +++++ frontend/src/app/types/app/code-tables/species.ts | 6 ++++++ frontend/src/app/types/app/code-tables/violation.ts | 5 +++++ 24 files changed, 89 insertions(+), 25 deletions(-) create mode 100644 frontend/src/app/types/app/code-tables/agency.ts create mode 100644 frontend/src/app/types/app/code-tables/attactant.ts create mode 100644 frontend/src/app/types/app/code-tables/base-code-table.ts create mode 100644 frontend/src/app/types/app/code-tables/complaint-status.ts create mode 100644 frontend/src/app/types/app/code-tables/nature-of-complaint.ts create mode 100644 frontend/src/app/types/app/code-tables/organization-code-table.ts create mode 100644 frontend/src/app/types/app/code-tables/organization-unit-type.ts create mode 100644 frontend/src/app/types/app/code-tables/organization-unit.ts create mode 100644 frontend/src/app/types/app/code-tables/person-complaint-type.ts create mode 100644 frontend/src/app/types/app/code-tables/species.ts create mode 100644 frontend/src/app/types/app/code-tables/violation.ts diff --git a/backend/src/types/models/code-tables/agency.ts b/backend/src/types/models/code-tables/agency.ts index 5b7adb539..9e8f222b5 100644 --- a/backend/src/types/models/code-tables/agency.ts +++ b/backend/src/types/models/code-tables/agency.ts @@ -1,5 +1,5 @@ -import { CodeTable } from "../../models/code-tables/code-table"; +import { BaseCodeTable } from "../../models/code-tables/code-table"; -export interface Agency extends CodeTable { +export interface Agency extends BaseCodeTable { agency: string } \ No newline at end of file diff --git a/backend/src/types/models/code-tables/attractant.ts b/backend/src/types/models/code-tables/attractant.ts index 28f3d0042..a433270e2 100644 --- a/backend/src/types/models/code-tables/attractant.ts +++ b/backend/src/types/models/code-tables/attractant.ts @@ -1,5 +1,5 @@ -import { CodeTable } from "../../models/code-tables/code-table"; +import { BaseCodeTable } from "../../models/code-tables/code-table"; -export interface Attractant extends CodeTable { +export interface Attractant extends BaseCodeTable { attractant: string } \ No newline at end of file diff --git a/backend/src/types/models/code-tables/code-table.ts b/backend/src/types/models/code-tables/code-table.ts index 7188318cb..689ee760c 100644 --- a/backend/src/types/models/code-tables/code-table.ts +++ b/backend/src/types/models/code-tables/code-table.ts @@ -1,4 +1,4 @@ -export interface CodeTable { +export interface BaseCodeTable { shortDescription: string; longDescription: string; displayOrder?: number; diff --git a/backend/src/types/models/code-tables/complaint-status.ts b/backend/src/types/models/code-tables/complaint-status.ts index fa0d39dbe..08c3951a4 100644 --- a/backend/src/types/models/code-tables/complaint-status.ts +++ b/backend/src/types/models/code-tables/complaint-status.ts @@ -1,5 +1,5 @@ -import { CodeTable } from "../../models/code-tables/code-table"; +import { BaseCodeTable } from "../../models/code-tables/code-table"; -export interface ComplaintStatus extends CodeTable { +export interface ComplaintStatus extends BaseCodeTable { complaintStatus: string } \ No newline at end of file diff --git a/backend/src/types/models/code-tables/index.ts b/backend/src/types/models/code-tables/index.ts index 816dd46fc..7ff4755a3 100644 --- a/backend/src/types/models/code-tables/index.ts +++ b/backend/src/types/models/code-tables/index.ts @@ -1,4 +1,4 @@ -import { CodeTable } from "./code-table"; +import { BaseCodeTable } from "./code-table"; import { Agency } from "./agency"; import { Attractant } from "./attractant"; import { ComplaintStatus } from "./complaint-status"; @@ -28,7 +28,7 @@ export const AvailableAgencies = [ "cos" ] -export default CodeTable; +export default BaseCodeTable; export { Agency, Attractant, diff --git a/backend/src/types/models/code-tables/nature-of-complaint.ts b/backend/src/types/models/code-tables/nature-of-complaint.ts index 8386f176c..fffd1776b 100644 --- a/backend/src/types/models/code-tables/nature-of-complaint.ts +++ b/backend/src/types/models/code-tables/nature-of-complaint.ts @@ -1,5 +1,5 @@ -import { CodeTable } from "../../models/code-tables/code-table"; +import { BaseCodeTable } from "./code-table"; -export interface NatureOfComplaint extends CodeTable { +export interface NatureOfComplaint extends BaseCodeTable { natureOfComplaint: string } \ No newline at end of file diff --git a/backend/src/types/models/code-tables/organization-unit-type.ts b/backend/src/types/models/code-tables/organization-unit-type.ts index b813c32d4..f6d3279d5 100644 --- a/backend/src/types/models/code-tables/organization-unit-type.ts +++ b/backend/src/types/models/code-tables/organization-unit-type.ts @@ -1,5 +1,5 @@ -import { CodeTable } from "../../models/code-tables/code-table"; +import { BaseCodeTable } from "./code-table"; -export interface OrganizationUnitType extends CodeTable { +export interface OrganizationUnitType extends BaseCodeTable { organizationUnitType: string } \ No newline at end of file diff --git a/backend/src/types/models/code-tables/organization-unit.ts b/backend/src/types/models/code-tables/organization-unit.ts index 0e6ec1280..133cd8250 100644 --- a/backend/src/types/models/code-tables/organization-unit.ts +++ b/backend/src/types/models/code-tables/organization-unit.ts @@ -1,6 +1,6 @@ -import { CodeTable } from "../../models/code-tables/code-table"; +import { BaseCodeTable } from "./code-table"; -export interface OrganizationUnit extends CodeTable { +export interface OrganizationUnit extends BaseCodeTable { organizationUnit: string organizationUnitType?: string } \ No newline at end of file diff --git a/backend/src/types/models/code-tables/person-complaint-type.ts b/backend/src/types/models/code-tables/person-complaint-type.ts index bd517b143..7d52692e6 100644 --- a/backend/src/types/models/code-tables/person-complaint-type.ts +++ b/backend/src/types/models/code-tables/person-complaint-type.ts @@ -1,5 +1,5 @@ -import { CodeTable } from "./code-table"; +import { BaseCodeTable } from "./code-table"; -export interface PersonComplaintType extends CodeTable { +export interface PersonComplaintType extends BaseCodeTable { personComplaintType: string } \ No newline at end of file diff --git a/backend/src/types/models/code-tables/species.ts b/backend/src/types/models/code-tables/species.ts index c40204ae8..b003420f2 100644 --- a/backend/src/types/models/code-tables/species.ts +++ b/backend/src/types/models/code-tables/species.ts @@ -1,6 +1,6 @@ -import { CodeTable } from "../../models/code-tables/code-table"; +import { BaseCodeTable } from "./code-table"; -export interface Species extends CodeTable { +export interface Species extends BaseCodeTable { species: string; legacy: string; } diff --git a/backend/src/types/models/code-tables/violation.ts b/backend/src/types/models/code-tables/violation.ts index 9570077f9..5a5bf8220 100644 --- a/backend/src/types/models/code-tables/violation.ts +++ b/backend/src/types/models/code-tables/violation.ts @@ -1,5 +1,5 @@ -import { CodeTable } from "../../models/code-tables/code-table"; +import { BaseCodeTable } from "./code-table"; -export interface Violation extends CodeTable { +export interface Violation extends BaseCodeTable { violation: string } \ No newline at end of file diff --git a/backend/src/v1/code-table/code-table.controller.ts b/backend/src/v1/code-table/code-table.controller.ts index 676287fac..40564fddf 100644 --- a/backend/src/v1/code-table/code-table.controller.ts +++ b/backend/src/v1/code-table/code-table.controller.ts @@ -6,7 +6,7 @@ import { Role } from '../../enum/role.enum'; import { Roles } from '../../auth/decorators/roles.decorator'; import { JwtRoleGuard } from '../../auth/jwtrole.guard'; -import CodeTable, { AvailableAgencies, AvailableCodeTables, OrganizationCodeTable } from "../../types/models/code-tables" +import BaseCodeTable, { AvailableAgencies, AvailableCodeTables, OrganizationCodeTable } from "../../types/models/code-tables" @UseGuards(JwtRoleGuard) @ApiTags("code-table") @@ -18,7 +18,7 @@ export class CodeTableController { @Roles(Role.COS_OFFICER) async getCodeTableByName( @Param("table") table: string - ): Promise { + ): Promise { if(!AvailableCodeTables.includes(table)){ throw new NotFoundException(); } diff --git a/backend/src/v1/code-table/code-table.service.ts b/backend/src/v1/code-table/code-table.service.ts index d4daa40f1..409591973 100644 --- a/backend/src/v1/code-table/code-table.service.ts +++ b/backend/src/v1/code-table/code-table.service.ts @@ -2,7 +2,7 @@ import { Injectable, Logger } from "@nestjs/common"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import CodeTable, { +import BaseCodeTable, { Agency, Attractant, ComplaintStatus, @@ -50,7 +50,7 @@ export class CodeTableService { @InjectRepository(CosGeoOrgUnit) private _cosOrganizationUnitRepository: Repository; - getCodeTableByName = async (table: string): Promise => { + getCodeTableByName = async (table: string): Promise => { switch (table) { case "agency": { const data = await this._agencyRepository.find(); diff --git a/frontend/src/app/types/app/code-tables/agency.ts b/frontend/src/app/types/app/code-tables/agency.ts new file mode 100644 index 000000000..a624a22f3 --- /dev/null +++ b/frontend/src/app/types/app/code-tables/agency.ts @@ -0,0 +1,5 @@ +import { BaseCodeTable } from "./base-code-table"; + +export interface Agency extends BaseCodeTable { + agency: string; +} diff --git a/frontend/src/app/types/app/code-tables/attactant.ts b/frontend/src/app/types/app/code-tables/attactant.ts new file mode 100644 index 000000000..09bfac884 --- /dev/null +++ b/frontend/src/app/types/app/code-tables/attactant.ts @@ -0,0 +1,5 @@ +import { BaseCodeTable } from "./base-code-table"; + +export interface Attractant extends BaseCodeTable { + attractant: string; +} diff --git a/frontend/src/app/types/app/code-tables/base-code-table.ts b/frontend/src/app/types/app/code-tables/base-code-table.ts new file mode 100644 index 000000000..5cd506a5f --- /dev/null +++ b/frontend/src/app/types/app/code-tables/base-code-table.ts @@ -0,0 +1,7 @@ +export interface BaseCodeTable { + [key: string]: string | number | boolean | undefined; + shortDescription: string; + longDescription: string; + displayOrder?: number; + isActive?: boolean; +} \ No newline at end of file diff --git a/frontend/src/app/types/app/code-tables/complaint-status.ts b/frontend/src/app/types/app/code-tables/complaint-status.ts new file mode 100644 index 000000000..db266f29f --- /dev/null +++ b/frontend/src/app/types/app/code-tables/complaint-status.ts @@ -0,0 +1,5 @@ +import { BaseCodeTable } from "./base-code-table"; + +export interface ComplaintStatus extends BaseCodeTable { + complaintStatus: string +} \ No newline at end of file diff --git a/frontend/src/app/types/app/code-tables/nature-of-complaint.ts b/frontend/src/app/types/app/code-tables/nature-of-complaint.ts new file mode 100644 index 000000000..d397f5879 --- /dev/null +++ b/frontend/src/app/types/app/code-tables/nature-of-complaint.ts @@ -0,0 +1,5 @@ +import { BaseCodeTable } from "./base-code-table"; + +export interface NatureOfComplaint extends BaseCodeTable { + natureOfComplaint: string +} \ No newline at end of file diff --git a/frontend/src/app/types/app/code-tables/organization-code-table.ts b/frontend/src/app/types/app/code-tables/organization-code-table.ts new file mode 100644 index 000000000..b70d592cd --- /dev/null +++ b/frontend/src/app/types/app/code-tables/organization-code-table.ts @@ -0,0 +1,10 @@ +export interface OrganizationCodeTable { + areaName: string; + officeLocationName: string; + regionName: string; + zoneName: string; + area: string; + officeLocation: string; + region: string; + zone: string; +} diff --git a/frontend/src/app/types/app/code-tables/organization-unit-type.ts b/frontend/src/app/types/app/code-tables/organization-unit-type.ts new file mode 100644 index 000000000..f096b2258 --- /dev/null +++ b/frontend/src/app/types/app/code-tables/organization-unit-type.ts @@ -0,0 +1,5 @@ +import { BaseCodeTable } from "./base-code-table"; + +export interface OrganizationUnitType extends BaseCodeTable { + organizationUnitType: string +} \ No newline at end of file diff --git a/frontend/src/app/types/app/code-tables/organization-unit.ts b/frontend/src/app/types/app/code-tables/organization-unit.ts new file mode 100644 index 000000000..92aa284b4 --- /dev/null +++ b/frontend/src/app/types/app/code-tables/organization-unit.ts @@ -0,0 +1,6 @@ +import { BaseCodeTable } from "./base-code-table"; + +export interface OrganizationUnit extends BaseCodeTable { + organizationUnit: string + organizationUnitType?: string +} \ No newline at end of file diff --git a/frontend/src/app/types/app/code-tables/person-complaint-type.ts b/frontend/src/app/types/app/code-tables/person-complaint-type.ts new file mode 100644 index 000000000..797433ecf --- /dev/null +++ b/frontend/src/app/types/app/code-tables/person-complaint-type.ts @@ -0,0 +1,5 @@ +import { BaseCodeTable } from "./base-code-table"; + +export interface PersonComplaintType extends BaseCodeTable { + personComplaintType: string +} \ No newline at end of file diff --git a/frontend/src/app/types/app/code-tables/species.ts b/frontend/src/app/types/app/code-tables/species.ts new file mode 100644 index 000000000..a1397a687 --- /dev/null +++ b/frontend/src/app/types/app/code-tables/species.ts @@ -0,0 +1,6 @@ +import { BaseCodeTable } from "./base-code-table"; + +export interface Species extends BaseCodeTable { + species: string; + legacy: string; +} diff --git a/frontend/src/app/types/app/code-tables/violation.ts b/frontend/src/app/types/app/code-tables/violation.ts new file mode 100644 index 000000000..20a225369 --- /dev/null +++ b/frontend/src/app/types/app/code-tables/violation.ts @@ -0,0 +1,5 @@ +import { BaseCodeTable } from "./base-code-table"; + +export interface Violation extends BaseCodeTable { + violation: string +} \ No newline at end of file From 7f629d5f58a01c42a8ee9f21d01c08b0273f90d1 Mon Sep 17 00:00:00 2001 From: Mike Sears Date: Thu, 9 Nov 2023 23:08:54 -0800 Subject: [PATCH 16/21] added tests for getting organizations units by agency, refactored code-table reducer --- .../src/types/models/code-tables/community.ts | 5 + .../models/code-tables/complaint-type.ts | 5 + backend/src/types/models/code-tables/index.ts | 13 +- .../src/types/models/code-tables/sector.ts | 4 + backend/src/types/models/code-tables/zone.ts | 5 + .../code-table/code-table.controller.spec.ts | 40 +- .../v1/code-table/code-table.controller.ts | 60 +- .../src/v1/code-table/code-table.module.ts | 2 + .../v1/code-table/code-table.service.spec.ts | 254 +++++++- .../src/v1/code-table/code-table.service.ts | 108 +++- .../mocks/mock-code-table-repositories.ts | 145 ++++- .../src/app/constants/code-table-types.ts | 14 + frontend/src/app/constants/code-table.enum.ts | 10 - .../app/store/reducers/_code-table.orig.txt | 563 ++++++++++++++++++ frontend/src/app/store/reducers/code-table.ts | 364 ++++------- .../types/app/code-tables/complaint-type.ts | 5 + .../src/app/types/state/code-table-state.ts | 50 +- 17 files changed, 1354 insertions(+), 293 deletions(-) create mode 100644 backend/src/types/models/code-tables/community.ts create mode 100644 backend/src/types/models/code-tables/complaint-type.ts create mode 100644 backend/src/types/models/code-tables/sector.ts create mode 100644 backend/src/types/models/code-tables/zone.ts create mode 100644 frontend/src/app/constants/code-table-types.ts delete mode 100644 frontend/src/app/constants/code-table.enum.ts create mode 100644 frontend/src/app/store/reducers/_code-table.orig.txt create mode 100644 frontend/src/app/types/app/code-tables/complaint-type.ts diff --git a/backend/src/types/models/code-tables/community.ts b/backend/src/types/models/code-tables/community.ts new file mode 100644 index 000000000..8180e50da --- /dev/null +++ b/backend/src/types/models/code-tables/community.ts @@ -0,0 +1,5 @@ +import { Zone } from "./zone"; + +export interface Community extends Zone { + zone: string +} \ No newline at end of file diff --git a/backend/src/types/models/code-tables/complaint-type.ts b/backend/src/types/models/code-tables/complaint-type.ts new file mode 100644 index 000000000..5d09e416f --- /dev/null +++ b/backend/src/types/models/code-tables/complaint-type.ts @@ -0,0 +1,5 @@ +import { BaseCodeTable } from "./code-table"; + +export interface ComplaintType extends BaseCodeTable { + complaintType: string +} \ No newline at end of file diff --git a/backend/src/types/models/code-tables/index.ts b/backend/src/types/models/code-tables/index.ts index 7ff4755a3..2f1680b5e 100644 --- a/backend/src/types/models/code-tables/index.ts +++ b/backend/src/types/models/code-tables/index.ts @@ -9,6 +9,10 @@ import { PersonComplaintType } from "./person-complaint-type"; import { Species } from "./species"; import { Violation } from "./violation"; import { OrganizationCodeTable } from "./organization-code-table"; +import { ComplaintType } from "./complaint-type"; +import { Sector } from "./sector"; +import { Community } from "./community"; +import { Zone } from "./zone"; export const AvailableCodeTables = [ "agency", @@ -21,7 +25,8 @@ export const AvailableCodeTables = [ "person-complaint", "species", "violation", - "cos-organization-unit" + "cos-organization-unit", + "complaint-type", ]; export const AvailableAgencies = [ @@ -39,5 +44,9 @@ export { PersonComplaintType, Species, Violation, - OrganizationCodeTable + OrganizationCodeTable, + ComplaintType, + Sector, + Zone, + Community }; diff --git a/backend/src/types/models/code-tables/sector.ts b/backend/src/types/models/code-tables/sector.ts new file mode 100644 index 000000000..334e0ee25 --- /dev/null +++ b/backend/src/types/models/code-tables/sector.ts @@ -0,0 +1,4 @@ +export interface Sector { + code: string + name: string +} \ No newline at end of file diff --git a/backend/src/types/models/code-tables/zone.ts b/backend/src/types/models/code-tables/zone.ts new file mode 100644 index 000000000..aab65c99c --- /dev/null +++ b/backend/src/types/models/code-tables/zone.ts @@ -0,0 +1,5 @@ +import { Sector } from "./sector"; + +export interface Zone extends Sector { + region: string +} \ No newline at end of file diff --git a/backend/src/v1/code-table/code-table.controller.spec.ts b/backend/src/v1/code-table/code-table.controller.spec.ts index 8c7777d03..9b9b17817 100644 --- a/backend/src/v1/code-table/code-table.controller.spec.ts +++ b/backend/src/v1/code-table/code-table.controller.spec.ts @@ -13,8 +13,9 @@ import { CodeTableService } from "./code-table.service"; import { MockAgencyCodeTableRepository, MockAttractantCodeTableRepository, + MockCommunityCodeTableServiceRepository, MockComplaintStatusCodeTableRepository, - MockCosOrganizationUnitCodeTableRepository, + MockComplaintTypeCodeTableRepository, MockNatureOfComplaintCodeTableRepository, MockOrganizationUnitCodeTableRepository, MockOrganizationUnitTypeCodeTableRepository, @@ -32,6 +33,7 @@ import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/ import { SpeciesCode } from "../species_code/entities/species_code.entity"; import { ViolationCode } from "../violation_code/entities/violation_code.entity"; import { CosGeoOrgUnit } from "../cos_geo_org_unit/entities/cos_geo_org_unit.entity"; +import { ComplaintTypeCode } from "../complaint_type_code/entities/complaint_type_code.entity"; describe("Testing: CodeTable Controller", () => { let app: INestApplication; @@ -80,7 +82,11 @@ describe("Testing: CodeTable Controller", () => { }, { provide: getRepositoryToken(CosGeoOrgUnit), - useFactory: MockCosOrganizationUnitCodeTableRepository, + useFactory: MockCommunityCodeTableServiceRepository, + }, + { + provide: getRepositoryToken(ComplaintTypeCode), + useFactory: MockComplaintTypeCodeTableRepository, }, ], }) @@ -115,6 +121,21 @@ describe("Testing: CodeTable Controller", () => { `/code-table/organization-by-agency/${_agency}` ); expect(response.statusCode).toBe(200); + + response = await request(app.getHttpServer()).get( + `/code-table/regions-by-agency/${_agency}` + ); + expect(response.statusCode).toBe(200); + + response = await request(app.getHttpServer()).get( + `/code-table/zones-by-agency/${_agency}` + ); + expect(response.statusCode).toBe(200); + + response = await request(app.getHttpServer()).get( + `/code-table/communities-by-agency/${_agency}` + ); + expect(response.statusCode).toBe(200); }); it("should return 404 when a requesting code table that doesn't exist", async () => { @@ -137,6 +158,21 @@ describe("Testing: CodeTable Controller", () => { `/code-table/organization-by-agency/${_agency}` ); expect(response.statusCode).toBe(404); + + response = await request(app.getHttpServer()).get( + `/code-table/regions-by-agency/${_agency}` + ); + expect(response.statusCode).toBe(404); + + response = await request(app.getHttpServer()).get( + `/code-table/zones-by-agency/${_agency}` + ); + expect(response.statusCode).toBe(404); + + response = await request(app.getHttpServer()).get( + `/code-table/communities-by-agency/${_agency}` + ); + expect(response.statusCode).toBe(404); }); }); diff --git a/backend/src/v1/code-table/code-table.controller.ts b/backend/src/v1/code-table/code-table.controller.ts index 40564fddf..ed18f8c32 100644 --- a/backend/src/v1/code-table/code-table.controller.ts +++ b/backend/src/v1/code-table/code-table.controller.ts @@ -1,12 +1,23 @@ -import { Controller, Get, NotFoundException, Param, UseGuards } from "@nestjs/common"; +import { + Controller, + Get, + NotFoundException, + Param, + UseGuards, +} from "@nestjs/common"; import { ApiTags } from "@nestjs/swagger"; import { CodeTableService } from "./code-table.service"; -import { Role } from '../../enum/role.enum'; -import { Roles } from '../../auth/decorators/roles.decorator'; -import { JwtRoleGuard } from '../../auth/jwtrole.guard'; +import { Role } from "../../enum/role.enum"; +import { Roles } from "../../auth/decorators/roles.decorator"; +import { JwtRoleGuard } from "../../auth/jwtrole.guard"; -import BaseCodeTable, { AvailableAgencies, AvailableCodeTables, OrganizationCodeTable } from "../../types/models/code-tables" +import BaseCodeTable, { + AvailableAgencies, + AvailableCodeTables, + OrganizationCodeTable, + Sector, +} from "../../types/models/code-tables"; @UseGuards(JwtRoleGuard) @ApiTags("code-table") @@ -19,7 +30,7 @@ export class CodeTableController { async getCodeTableByName( @Param("table") table: string ): Promise { - if(!AvailableCodeTables.includes(table)){ + if (!AvailableCodeTables.includes(table)) { throw new NotFoundException(); } @@ -32,11 +43,46 @@ export class CodeTableController { async getOrganizationsByAgency( @Param("agency") agency: string ): Promise { - if(!AvailableAgencies.includes(agency)){ + if (!AvailableAgencies.includes(agency)) { throw new NotFoundException(); } const result = await this.service.getOrganizationsByAgency(agency); return result; } + + @Get("/regions-by-agency/:agency") + @Roles(Role.COS_OFFICER) + async getRegionsByAgency(@Param("agency") agency: string): Promise { + if (!AvailableAgencies.includes(agency)) { + throw new NotFoundException(); + } + + const result = await this.service.getRegionsByAgency(agency); + return result; + } + + @Get("/zones-by-agency/:agency") + @Roles(Role.COS_OFFICER) + async getZonesByAgency(@Param("agency") agency: string): Promise { + if (!AvailableAgencies.includes(agency)) { + throw new NotFoundException(); + } + + const result = await this.service.getZonesByAgency(agency); + return result; + } + + @Get("/communities-by-agency/:agency") + @Roles(Role.COS_OFFICER) + async getCommunitiesByAgency( + @Param("agency") agency: string + ): Promise { + if (!AvailableAgencies.includes(agency)) { + throw new NotFoundException(); + } + + const result = await this.service.getCommunitiesByAgency(agency); + return result; + } } diff --git a/backend/src/v1/code-table/code-table.module.ts b/backend/src/v1/code-table/code-table.module.ts index 1fa0bbcca..b33f1d269 100644 --- a/backend/src/v1/code-table/code-table.module.ts +++ b/backend/src/v1/code-table/code-table.module.ts @@ -12,6 +12,7 @@ import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/ import { SpeciesCode } from "../species_code/entities/species_code.entity"; import { ViolationCode } from "../violation_code/entities/violation_code.entity"; import { CosGeoOrgUnit } from "../cos_geo_org_unit/entities/cos_geo_org_unit.entity"; +import { ComplaintTypeCode } from "../complaint_type_code/entities/complaint_type_code.entity"; @Module({ imports: [ @@ -25,6 +26,7 @@ import { CosGeoOrgUnit } from "../cos_geo_org_unit/entities/cos_geo_org_unit.ent TypeOrmModule.forFeature([SpeciesCode]), TypeOrmModule.forFeature([ViolationCode]), TypeOrmModule.forFeature([CosGeoOrgUnit]), + TypeOrmModule.forFeature([ComplaintTypeCode]), ], controllers: [CodeTableController], providers: [CodeTableService], diff --git a/backend/src/v1/code-table/code-table.service.spec.ts b/backend/src/v1/code-table/code-table.service.spec.ts index 154ab1b43..e028e382e 100644 --- a/backend/src/v1/code-table/code-table.service.spec.ts +++ b/backend/src/v1/code-table/code-table.service.spec.ts @@ -15,7 +15,11 @@ import { MockPersonComplaintCodeTableRepository, MockSpeciesCodeTableRepository, MockViolationsCodeTableRepository, - MockCosOrganizationUnitCodeTableRepository + MockCosOrganizationUnitCodeTableRepository, + MockComplaintTypeCodeTableRepository, + MockCommunityCodeTableServiceRepository, + MockZoneCodeTableServiceRepository, + MockRegionCodeTableServiceRepository, } from "../../../test/mocks/mock-code-table-repositories"; import { HwcrComplaintNatureCode } from "../hwcr_complaint_nature_code/entities/hwcr_complaint_nature_code.entity"; import { GeoOrgUnitTypeCode } from "../geo_org_unit_type_code/entities/geo_org_unit_type_code.entity"; @@ -24,6 +28,7 @@ import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/ import { SpeciesCode } from "../species_code/entities/species_code.entity"; import { ViolationCode } from "../violation_code/entities/violation_code.entity"; import { CosGeoOrgUnit } from "../cos_geo_org_unit/entities/cos_geo_org_unit.entity"; +import { ComplaintTypeCode } from "../complaint_type_code/entities/complaint_type_code.entity"; describe("Testing: CodeTable Service", () => { let service: CodeTableService; @@ -72,6 +77,10 @@ describe("Testing: CodeTable Service", () => { provide: getRepositoryToken(CosGeoOrgUnit), useFactory: MockCosOrganizationUnitCodeTableRepository, }, + { + provide: getRepositoryToken(ComplaintTypeCode), + useFactory: MockComplaintTypeCodeTableRepository, + }, ], }).compile(); @@ -204,11 +213,252 @@ describe("Testing: CodeTable Service", () => { const _agency = "cos"; //-- act - const results = await service.getOrganizationsByAgency(_agency) + const results = await service.getOrganizationsByAgency(_agency); //-- assert expect(results).not.toBe(null); expect(results.length).not.toBe(0); expect(results.length).toBe(14); }); + + it("should return collection of complaint types", async () => { + //-- arrange + const _tableName = "complaint-type"; + + //-- act + const results = await service.getCodeTableByName(_tableName); + + //-- assert + expect(results).not.toBe(null); + expect(results.length).not.toBe(0); + expect(results.length).toBe(2); + }); +}); + +describe("Testing: CodeTable service", () => { + let service: CodeTableService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + CodeTableService, + { + provide: getRepositoryToken(AgencyCode), + useFactory: MockAgencyCodeTableRepository, + }, + { + provide: getRepositoryToken(AttractantCode), + useFactory: MockAttractantCodeTableRepository, + }, + { + provide: getRepositoryToken(ComplaintStatusCode), + useFactory: MockComplaintStatusCodeTableRepository, + }, + { + provide: getRepositoryToken(HwcrComplaintNatureCode), + useFactory: MockNatureOfComplaintCodeTableRepository, + }, + { + provide: getRepositoryToken(GeoOrgUnitTypeCode), + useFactory: MockOrganizationUnitTypeCodeTableRepository, + }, + { + provide: getRepositoryToken(GeoOrganizationUnitCode), + useFactory: MockOrganizationUnitCodeTableRepository, + }, + { + provide: getRepositoryToken(PersonComplaintXrefCode), + useFactory: MockPersonComplaintCodeTableRepository, + }, + { + provide: getRepositoryToken(SpeciesCode), + useFactory: MockSpeciesCodeTableRepository, + }, + { + provide: getRepositoryToken(ViolationCode), + useFactory: MockViolationsCodeTableRepository, + }, + { + provide: getRepositoryToken(CosGeoOrgUnit), + useFactory: MockRegionCodeTableServiceRepository, + }, + { + provide: getRepositoryToken(ComplaintTypeCode), + useFactory: MockComplaintTypeCodeTableRepository, + }, + ], + }).compile(); + + service = module.get(CodeTableService); + }); + + it("should be defined", () => { + expect(service).toBeDefined(); + }); + + it("should return collection of regions", async () => { + //-- arrange + const _agency = "cos"; + + //-- act + const results = await service.getRegionsByAgency(_agency); + + //-- assert + expect(results).not.toBe(null); + expect(results.length).not.toBe(0); + expect(results.length).toBe(8); + }); + +}); + +describe("Testing: CodeTable service", () => { + let service: CodeTableService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + CodeTableService, + { + provide: getRepositoryToken(AgencyCode), + useFactory: MockAgencyCodeTableRepository, + }, + { + provide: getRepositoryToken(AttractantCode), + useFactory: MockAttractantCodeTableRepository, + }, + { + provide: getRepositoryToken(ComplaintStatusCode), + useFactory: MockComplaintStatusCodeTableRepository, + }, + { + provide: getRepositoryToken(HwcrComplaintNatureCode), + useFactory: MockNatureOfComplaintCodeTableRepository, + }, + { + provide: getRepositoryToken(GeoOrgUnitTypeCode), + useFactory: MockOrganizationUnitTypeCodeTableRepository, + }, + { + provide: getRepositoryToken(GeoOrganizationUnitCode), + useFactory: MockOrganizationUnitCodeTableRepository, + }, + { + provide: getRepositoryToken(PersonComplaintXrefCode), + useFactory: MockPersonComplaintCodeTableRepository, + }, + { + provide: getRepositoryToken(SpeciesCode), + useFactory: MockSpeciesCodeTableRepository, + }, + { + provide: getRepositoryToken(ViolationCode), + useFactory: MockViolationsCodeTableRepository, + }, + { + provide: getRepositoryToken(CosGeoOrgUnit), + useFactory: MockZoneCodeTableServiceRepository, + }, + { + provide: getRepositoryToken(ComplaintTypeCode), + useFactory: MockComplaintTypeCodeTableRepository, + }, + ], + }).compile(); + + service = module.get(CodeTableService); + }); + + it("should be defined", () => { + expect(service).toBeDefined(); + }); + + + it("should return collection of zones", async () => { + //-- arrange + const _agency = "cos"; + + //-- act + const results = await service.getZonesByAgency(_agency); + + //-- assert + expect(results).not.toBe(null); + expect(results.length).not.toBe(0); + expect(results.length).toBe(9); + }); + +}); + +describe("Testing: CodeTable service", () => { + let service: CodeTableService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + CodeTableService, + { + provide: getRepositoryToken(AgencyCode), + useFactory: MockAgencyCodeTableRepository, + }, + { + provide: getRepositoryToken(AttractantCode), + useFactory: MockAttractantCodeTableRepository, + }, + { + provide: getRepositoryToken(ComplaintStatusCode), + useFactory: MockComplaintStatusCodeTableRepository, + }, + { + provide: getRepositoryToken(HwcrComplaintNatureCode), + useFactory: MockNatureOfComplaintCodeTableRepository, + }, + { + provide: getRepositoryToken(GeoOrgUnitTypeCode), + useFactory: MockOrganizationUnitTypeCodeTableRepository, + }, + { + provide: getRepositoryToken(GeoOrganizationUnitCode), + useFactory: MockOrganizationUnitCodeTableRepository, + }, + { + provide: getRepositoryToken(PersonComplaintXrefCode), + useFactory: MockPersonComplaintCodeTableRepository, + }, + { + provide: getRepositoryToken(SpeciesCode), + useFactory: MockSpeciesCodeTableRepository, + }, + { + provide: getRepositoryToken(ViolationCode), + useFactory: MockViolationsCodeTableRepository, + }, + { + provide: getRepositoryToken(CosGeoOrgUnit), + useFactory: MockCommunityCodeTableServiceRepository, + }, + { + provide: getRepositoryToken(ComplaintTypeCode), + useFactory: MockComplaintTypeCodeTableRepository, + }, + ], + }).compile(); + + service = module.get(CodeTableService); + }); + + it("should be defined", () => { + expect(service).toBeDefined(); + }); + + it("should return collection of communities", async () => { + //-- arrange + const _agency = "cos"; + + //-- act + const results = await service.getCommunitiesByAgency(_agency); + + //-- assert + expect(results).not.toBe(null); + expect(results.length).not.toBe(0); + expect(results.length).toBe(11); + }); }); diff --git a/backend/src/v1/code-table/code-table.service.ts b/backend/src/v1/code-table/code-table.service.ts index 409591973..72f5676f0 100644 --- a/backend/src/v1/code-table/code-table.service.ts +++ b/backend/src/v1/code-table/code-table.service.ts @@ -13,6 +13,10 @@ import BaseCodeTable, { Species, Violation, OrganizationCodeTable, + ComplaintType, + Sector, + Zone, + Community, } from "../../types/models/code-tables"; import { AgencyCode } from "../agency_code/entities/agency_code.entity"; import { AttractantCode } from "../attractant_code/entities/attractant_code.entity"; @@ -24,6 +28,7 @@ import { PersonComplaintXrefCode } from "../person_complaint_xref_code/entities/ import { SpeciesCode } from "../species_code/entities/species_code.entity"; import { ViolationCode } from "../violation_code/entities/violation_code.entity"; import { CosGeoOrgUnit } from "../cos_geo_org_unit/entities/cos_geo_org_unit.entity"; +import { ComplaintTypeCode } from "../complaint_type_code/entities/complaint_type_code.entity"; @Injectable() export class CodeTableService { @@ -49,6 +54,8 @@ export class CodeTableService { private _violationsRepository: Repository; @InjectRepository(CosGeoOrgUnit) private _cosOrganizationUnitRepository: Repository; + @InjectRepository(ComplaintTypeCode) + private _complaintTypetRepository: Repository; getCodeTableByName = async (table: string): Promise => { switch (table) { @@ -264,6 +271,28 @@ export class CodeTableService { ); return results; } + case "complaint-type": { + const data = await this._complaintTypetRepository.find(); + let results = data.map( + ({ + complaint_type_code, + short_description, + long_description, + display_order, + active_ind, + }) => { + let table: ComplaintType = { + complaintType: complaint_type_code, + shortDescription: short_description, + longDescription: long_description, + displayOrder: display_order, + isActive: active_ind, + }; + return table; + } + ); + return results; + } } }; @@ -291,9 +320,77 @@ export class CodeTableService { regionName, region, zone, - zoneName + zoneName, + }; + + return record; + } + ); + + return results; + }; + + getRegionsByAgency = async (agency: string): Promise> => { + const data = await this._cosOrganizationUnitRepository + .createQueryBuilder("cos_geo_org_unit") + .select(["region_name", "region_code"]) + .distinctOn(["region_code"]) + .getRawMany(); + + const results = data.map(({ region_name: name, region_code: code }) => { + let record: Sector = { + code, + name, + }; + return record; + }); + + return results; + }; + + getZonesByAgency = async (agency: string): Promise> => { + const data = await this._cosOrganizationUnitRepository + .createQueryBuilder("cos_geo_org_unit") + .select(["zone_name", "zone_code", "region_code"]) + .distinctOn(["zone_code"]) + .getRawMany(); + + const results = data.map( + ({ zone_name: name, zone_code: code, region_code: region }) => { + let record: Zone = { + code, + name, + region, }; + return record; + } + ); + + return results; + }; + + getCommunitiesByAgency = async ( + agency: string + ): Promise> => { + const data = await this._cosOrganizationUnitRepository + .createQueryBuilder("cos_geo_org_unit") + .select(["area_name", "area_code", "zone_code", "region_code"]) + .distinctOn(["area_code"]) + .getRawMany(); + const results = data.map( + ({ + area_name: name, + area_code: code, + zone_code: zone, + region_code: region, + }) => { + let record: Community = { + code, + name, + zone, + region, + }; return record; } ); @@ -301,3 +398,12 @@ export class CodeTableService { return results; }; } + +/* + .createQueryBuilder("cos_geo_org_unit") + .where("cos_geo_org_unit.zone_code = :zone", { zone }) + .distinctOn(["cos_geo_org_unit.offloc_code"]) + .orderBy("cos_geo_org_unit.offloc_code"); + + const zoneOffices = await officeQuery.getMany(); +*/ diff --git a/backend/test/mocks/mock-code-table-repositories.ts b/backend/test/mocks/mock-code-table-repositories.ts index ea0e4eec9..55b6ac74e 100644 --- a/backend/test/mocks/mock-code-table-repositories.ts +++ b/backend/test/mocks/mock-code-table-repositories.ts @@ -51,7 +51,7 @@ const organizationUnits = [ const personTypes = [ { "person_complaint_xref_code": "ASSIGNEE", "short_description": "Officer Assigned", "long_description": "The person to whom the complaint is assigned to.", "display_order": 1, }, - { "person_complaint_xref_code": "TEST", "short_description": "TEST", "long_description": "Test person type", "display_order": 2, } + { "person_complaint_xref_code": "TEST", "short_description": "TEST", "long_description": "Test person type", "display_order": 2, } ] const species = [ @@ -91,6 +91,48 @@ const cosOrganizationUnits = [ { "zone_code": "CLMBAKTNY", "region_code": "KTNY", "region_name": "Kootenay", "zone_name": "Columbia/Kootenay", "office_location_code": "GLDN", "office_location_name": "Golden", "area_code": "PARSON", "area_name": "Parson" } ] +const complaintTypes = [ + { "complaint_type_code": "HWCR", "short_description": "HWCR", "long_description": "Human Wildlife Conflict", "display_order": 1, "active_ind": true, }, + { "complaint_type_code": "ERS", "short_description": "ERS", "long_description": "Enforcement", "display_order": 2, "active_ind": true, } +] + +const regions = [ + { "code": "KTNY", "name": "Kootenay" }, + { "code": "OKNGN", "name": "Okanagan" }, + { "code": "OMINECA", "name": "Omineca" }, + { "code": "PCLRD", "name": "Peace Liard" }, + { "code": "SKNA", "name": "Skeena" }, + { "code": "STHCST", "name": "South Coast" }, + { "code": "TMPSNCRBO", "name": "Thompson Cariboo" }, + { "code": "WSTCST", "name": "West Coast" } +] + +const zones = [ +{ "code": "NOKNGN", "name": "North Okanagan", "region": "OKNGN"}, +{ "code": "NPCE", "name": "North Peace", "region": "PCLRD"}, +{ "code": "OMNCA", "name": "Omineca", "region": "OMINECA"}, +{ "code": "SEA2SKY", "name": "Sea to Sky", "region": "STHCST"}, +{ "code": "SISL", "name": "South Island", "region": "WSTCST"}, +{ "code": "SNSHNCST", "name": "Sunshine Coast", "region": "STHCST"}, +{ "code": "SOKNGN", "name": "South Okanagan", "region": "OKNGN"}, +{ "code": "SPCE", "name": "South Peace", "region": "PCLRD"}, +{ "code": "TMPSNNCLA", "name": "Thompson Nicola", "region": "TMPSNCRBO"}, +] + +const communities = [ + { "code": "100MHHS", "name": "100 Mile House", "zone": "CRBOTMPSN", "region": "TMPSNCRBO" }, + { "code": "108MLRNH", "name": "108 Mile Ranch", "zone": "CRBOTMPSN", "region": "TMPSNCRBO" }, + { "code": "140MHHS", "name": "140 Mile House", "zone": "CRBOCHLCTN", "region": "TMPSNCRBO" }, + { "code": "150MHHS", "name": "150 Mile House", "zone": "CRBOCHLCTN", "region": "TMPSNCRBO" }, + { "code": "16MIL", "name": "16 Mile", "zone": "CRBOTMPSN", "region": "TMPSNCRBO" }, + { "code": "40MLFLTZ", "name": "40 Mile Flats", "zone": "CRBOCHLCTN", "region": "TMPSNCRBO" }, + { "code": "70MLHS", "name": "70 Mile House", "zone": "CRBOTMPSN", "region": "TMPSNCRBO" }, + { "code": "ABTFRD", "name": "Abbotsford", "zone": "FRSRS", "region": "STHCST" }, + { "code": "ADMSLKHS", "name": "Adams Lake", "zone": "TMPSNNCLA", "region": "TMPSNCRBO" }, + { "code": "AGSSZHS", "name": "Agassiz", "zone": "FRSRS", "region": "STHCST" }, + { "code": "AHST", "name": "Ahousat", "zone": "CENISL", "region": "WSTCST" } +] + const single = (name: string = "default", idx: number = 0): any => { switch (name) { case "agency": { @@ -187,29 +229,80 @@ export const MockPersonComplaintCodeTableRepository = () => ({ }); export const MockSpeciesCodeTableRepository = () => ({ - find: jest.fn().mockResolvedValue(species), - createQueryBuilder: jest.fn(() => ({ - leftJoinAndSelect: jest.fn().mockReturnThis(), - where: jest.fn().mockReturnThis(), - getMany: jest.fn().mockResolvedValue(species), - })), - }); - + find: jest.fn().mockResolvedValue(species), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(species), + })), +}); + export const MockViolationsCodeTableRepository = () => ({ - find: jest.fn().mockResolvedValue(violations), - createQueryBuilder: jest.fn(() => ({ - leftJoinAndSelect: jest.fn().mockReturnThis(), - where: jest.fn().mockReturnThis(), - getMany: jest.fn().mockResolvedValue(violations), - })), - }); - - export const MockCosOrganizationUnitCodeTableRepository = () => ({ - find: jest.fn().mockResolvedValue(cosOrganizationUnits), - createQueryBuilder: jest.fn(() => ({ - leftJoinAndSelect: jest.fn().mockReturnThis(), - where: jest.fn().mockReturnThis(), - getMany: jest.fn().mockResolvedValue(cosOrganizationUnits), - })), - }); - \ No newline at end of file + find: jest.fn().mockResolvedValue(violations), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(violations), + })), +}); + +export const MockCosOrganizationUnitCodeTableRepository = () => ({ + find: jest.fn().mockResolvedValue(cosOrganizationUnits), + map: jest.fn().mockReturnThis(), + createQueryBuilder: jest.fn(() => ({ + select: jest.fn().mockReturnThis(), + distinctOn: jest.fn().mockReturnThis(), + getRawMany: jest.fn().mockReturnThis(), + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(cosOrganizationUnits), + })), +}); + +export const MockComplaintTypeCodeTableRepository = () => ({ + find: jest.fn().mockResolvedValue(complaintTypes), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockResolvedValue(complaintTypes), + })), +}); + +export const MockRegionCodeTableServiceRepository = () => ({ + find: jest.fn().mockReturnThis(), + map: jest.fn().mockReturnThis(), + createQueryBuilder: jest.fn(() => ({ + select: jest.fn().mockReturnThis(), + distinctOn: jest.fn().mockReturnThis(), + getRawMany: jest.fn().mockResolvedValue(regions), + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockReturnThis(), + })), +}); + +export const MockZoneCodeTableServiceRepository = () => ({ + find: jest.fn().mockReturnThis(), + map: jest.fn().mockReturnThis(), + createQueryBuilder: jest.fn(() => ({ + select: jest.fn().mockReturnThis(), + distinctOn: jest.fn().mockReturnThis(), + getRawMany: jest.fn().mockResolvedValue(zones), + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockReturnThis(), + })), +}); + +export const MockCommunityCodeTableServiceRepository = () => ({ + find: jest.fn().mockReturnThis(), + map: jest.fn().mockReturnThis(), + createQueryBuilder: jest.fn(() => ({ + select: jest.fn().mockReturnThis(), + distinctOn: jest.fn().mockReturnThis(), + getRawMany: jest.fn().mockResolvedValue(communities), + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + getMany: jest.fn().mockReturnThis(), + })), +}); \ No newline at end of file diff --git a/frontend/src/app/constants/code-table-types.ts b/frontend/src/app/constants/code-table-types.ts new file mode 100644 index 000000000..38e5a9c65 --- /dev/null +++ b/frontend/src/app/constants/code-table-types.ts @@ -0,0 +1,14 @@ + export const CODE_TABLE_TYPES = { + AGENCY: "agency", + ATTRACTANT: "attractant", + COMPLAINT_STATUS: "complaint-status", + COMPLAINT_TYPE: "complaint-type", + NATURE_OF_COMPLAINT: "nature-of-complaint", + // ORGANIZATION_UNIT_TYPE: "organization-unit-type", + // ORGANIZATION_UNIT: "organization-unit", + // PERSON_TYPE: "person-complaint", + SPECIES: "species", + VIOLATIONS: "violation", + // COS_ORGANIZATION: "cos-organization-unit" + }; + \ No newline at end of file diff --git a/frontend/src/app/constants/code-table.enum.ts b/frontend/src/app/constants/code-table.enum.ts deleted file mode 100644 index 74e660e52..000000000 --- a/frontend/src/app/constants/code-table.enum.ts +++ /dev/null @@ -1,10 +0,0 @@ -export enum CodeTable { - AGENCY_CODE = "agency-code", - ATTRACTANT_CODE = "attractant-code", - COMPLAINT_STATUS_CODE = "complaint-status-code", - GEO_ORG_UNIT_TYPE_CODE = "geo-org-unit-type-code", - GEO_ORGANIZATION_UNIT_CODE = "geo-organization-unit-code", - HWCR_COMPLAINT_NATURE_CODE = "hwcr-complaint-nature-code", - SPECIES_CODE = "species-code", - VIOLATION_CODE = "violation-code", -} diff --git a/frontend/src/app/store/reducers/_code-table.orig.txt b/frontend/src/app/store/reducers/_code-table.orig.txt new file mode 100644 index 000000000..700cfc117 --- /dev/null +++ b/frontend/src/app/store/reducers/_code-table.orig.txt @@ -0,0 +1,563 @@ +import { PayloadAction, createSlice } from "@reduxjs/toolkit"; +import { AppThunk, RootState, store } from "../store"; +import { from } from "linq-to-typescript"; +import config from "../../../config"; +import { CodeTableState } from "../../types/state/code-table-state"; +import { AgencyCode } from "../../types/code-tables/agency-code"; +import { CodeTable } from "../../types/code-tables/code-table"; +import { ComplaintStatusCode } from "../../types/code-tables/complaint-status-code"; +import { ViolationCode } from "../../types/code-tables/violation-code"; +import { SpeciesCode } from "../../types/code-tables/species-code"; +import { HwcrNatureOfComplaintCode } from "../../types/code-tables/hwcr-nature-of-complaint-code"; +import { CosGeoOrgUnit } from "../../types/person/person"; +import { AttractantCode } from "../../types/code-tables/attractant-code"; +import Option from "../../types/app/option"; +import { generateApiParameters, get } from "../../common/api"; +import { GeoOrganizationCode } from "../../types/code-tables/geo-orginaization-code"; +import { DropdownOption } from "../../types/code-tables/option"; +import { ComplaintTypeCode } from "../../types/code-tables/complaint-type-code"; + +const initialState: CodeTableState = { + agencyCodes: [], + complaintStatusCodes: [], + violationCodes: [], + speciesCodes: [], + wildlifeNatureOfComplaintCodes: [], + areaCodes: [], + attractantCodes: [], + regions: [], + zones: [], + communities: [], + complaintCodes: [], + complaintTypeCodes: [], +}; + +export const codeTableSlice = createSlice({ + name: "code-table", + initialState, + + reducers: { + setAgencyCodes: ( + state: CodeTableState, + action: PayloadAction>, + ) => { + const { payload } = action; + const data = payload.map( + ({ + agency_code: value, + long_description: label, + short_description: description, + }) => { + return { value, label, description } as CodeTable; + }, + ); + + return { ...state, agencyCodes: data }; + }, + setComplaintStatusCodes: ( + state: CodeTableState, + action: PayloadAction>, + ) => { + const { payload } = action; + const data = payload.map( + ({ + complaint_status_code: value, + long_description: label, + short_description: description, + }) => { + return { value, label, description } as CodeTable; + }, + ); + return { ...state, complaintStatusCodes: data }; + }, + setViolationCodes: ( + state: CodeTableState, + action: PayloadAction>, + ) => { + const { payload } = action; + const data = payload.map( + ({ + violation_code: value, + long_description: label, + short_description: description, + }) => { + return { value, label, description } as CodeTable; + }, + ); + return { ...state, violationCodes: data }; + }, + setSpeciesCodes: ( + state: CodeTableState, + action: PayloadAction>, + ) => { + const { payload } = action; + const data = payload.map( + ({ + species_code: value, + long_description: label, + short_description: description, + }) => { + return { value, label, description } as CodeTable; + }, + ); + return { ...state, speciesCodes: data }; + }, + setWildlifeNatureOfComplaintCodes: ( + state: CodeTableState, + action: PayloadAction>, + ) => { + const { payload } = action; + const data = payload.map( + ({ + hwcr_complaint_nature_code: value, + long_description: label, + short_description: description, + }) => { + return { value, label, description } as CodeTable; + }, + ); + return { ...state, wildlifeNatureOfComplaintCodes: data }; + }, + setAreaCodes: ( + state: CodeTableState, + action: PayloadAction>, + ) => { + const { payload } = action; + const data = payload.map(({ area_code: value, area_name: label }) => { + return { value, label, description: label } as CodeTable; + }); + return { ...state, areaCodes: data }; + }, + setAttractantCodes: ( + state: CodeTableState, + action: PayloadAction>, + ) => { + const { payload } = action; + const data = payload.map( + ({ + attractant_code: value, + short_description: label, + short_description: description, + }) => { + return { value, label, description } as CodeTable; + }, + ); + return { ...state, attractantCodes: data }; + }, + setRegions: ( + state: CodeTableState, + action: PayloadAction>, + ) => { + const { payload } = action; + const data = payload.map( + ({ + geo_organization_unit_code: value, + long_description: label, + short_description: description, + }) => { + return { value, label, description } as CodeTable; + }, + ); + return { ...state, regions: data }; + }, + setZones: ( + state: CodeTableState, + action: PayloadAction>, + ) => { + const { payload } = action; + const data = payload.map( + ({ + geo_organization_unit_code: value, + long_description: label, + short_description: description, + }) => { + return { value, label, description } as CodeTable; + }, + ); + return { ...state, zones: data }; + }, + setCommunities: ( + state: CodeTableState, + action: PayloadAction>, + ) => { + const { payload } = action; + const data = payload.map( + ({ + geo_organization_unit_code: value, + long_description: label, + short_description: description, + }) => { + return { value, label, description } as CodeTable; + }, + ); + return { ...state, communities: data }; + }, + setComplaintCodes: ( + state: CodeTableState, + action: PayloadAction>, + ) => { + const { payload } = action; + const data = payload.map( + ({ + geo_organization_unit_code: value, + long_description: label, + short_description: description, + }) => { + return { value, label, description } as CodeTable; + }, + ); + return { ...state, complaintCodes: data }; + }, + setComplaintTypeCodes: ( + state: CodeTableState, + action: PayloadAction>, + ) => { + const { payload } = action; + const data = payload.map( + ({ + complaint_type_code: value, + long_description: label, + short_description: description, + }) => { + return { value, label, description } as CodeTable; + }, + ); + + return { ...state, complaintTypeCodes: data }; + }, + }, + + // The `extraReducers` field lets the slice handle actions defined elsewhere, + // including actions generated by createAsyncThunk or in other slices. + extraReducers: (builder) => {}, +}); + +export const { + setAgencyCodes, + setComplaintStatusCodes, + setViolationCodes, + setSpeciesCodes, + setWildlifeNatureOfComplaintCodes, + setAreaCodes, + setAttractantCodes, + setRegions, + setZones, + setCommunities, + setComplaintCodes, + setComplaintTypeCodes, +} = codeTableSlice.actions; + +export const fetchCodeTables = (): AppThunk => async (dispatch) => { + const state = store.getState(); + const { + codeTables: { + agencyCodes, + complaintStatusCodes, + violationCodes, + speciesCodes, + wildlifeNatureOfComplaintCodes, + areaCodes, + attractantCodes, + regions, + zones, + communities, + complaintTypeCodes, + }, + } = state; + + try { + if (!from(agencyCodes).any()) { + dispatch(fetchAgencyCodes()); + } + + if (!from(complaintStatusCodes).any()) { + dispatch(fetchComplaintStatusCodes()); + } + + if (!from(violationCodes).any()) { + dispatch(fetchViolationCodes()); + } + + if (!from(speciesCodes).any()) { + dispatch(fetchSpeciesCodes()); + } + + if (!from(wildlifeNatureOfComplaintCodes).any()) { + dispatch(fetchWildlifeNatureOfComplaintCodes()); + } + + if (!from(areaCodes).any()) { + dispatch(fetchAreaCodes()); + } + + if (!from(attractantCodes).any()) { + dispatch(fetchAttractantCodes()); + } + + if (!from(regions).any()) { + dispatch(fetchRegions()); + } + + if (!from(zones).any()) { + dispatch(fetchZones()); + } + + if (!from(communities).any()) { + dispatch(fetchCommunities()); + } + + if (!from(complaintTypeCodes).any()) { + dispatch(fetchComplaintTypeCodes()); + } + } catch (error) { + } +}; + +export const fetchAgencyCodes = (): AppThunk => async (dispatch) => { + const parameters = generateApiParameters( + `${config.API_BASE_URL}/v1/agency-code`, + ); + const response = await get>(dispatch, parameters); + + if (response && from(response).any()) { + dispatch(setAgencyCodes(response)); + } +}; + +export const fetchViolationCodes = (): AppThunk => async (dispatch) => { + const parameters = generateApiParameters( + `${config.API_BASE_URL}/v1/violation-code`, + ); + const response = await get>(dispatch, parameters); + + if (response && from(response).any()) { + dispatch(setViolationCodes(response)); + } +}; + +export const fetchSpeciesCodes = (): AppThunk => async (dispatch) => { + const parameters = generateApiParameters( + `${config.API_BASE_URL}/v1/species-code`, + ); + const response = await get>(dispatch, parameters); + + if (response && from(response).any()) { + dispatch(setSpeciesCodes(response)); + } +}; + +export const fetchWildlifeNatureOfComplaintCodes = + (): AppThunk => async (dispatch) => { + const parameters = generateApiParameters( + `${config.API_BASE_URL}/v1/hwcr-complaint-nature-code`, + ); + const response = await get>( + dispatch, + parameters, + ); + + if (response && from(response).any()) { + dispatch(setWildlifeNatureOfComplaintCodes(response)); + } + }; + +export const fetchComplaintStatusCodes = (): AppThunk => async (dispatch) => { + const parameters = generateApiParameters( + `${config.API_BASE_URL}/v1/complaint-status-code`, + ); + const response = await get>(dispatch, parameters); + + if (response && from(response).any()) { + dispatch(setComplaintStatusCodes(response)); + } +}; + +export const fetchAreaCodes = (): AppThunk => async (dispatch) => { + const parameters = generateApiParameters( + `${config.API_BASE_URL}/v1/cos-geo-org-unit`, + ); + const response = await get>(dispatch, parameters); + + if (response && from(response).any()) { + dispatch(setAreaCodes(response)); + } +}; + +export const fetchAttractantCodes = (): AppThunk => async (dispatch) => { + const parameters = generateApiParameters( + `${config.API_BASE_URL}/v1/attractant-code`, + ); + const response = await get>(dispatch, parameters); + + if (response && from(response).any()) { + dispatch(setAttractantCodes(response)); + } +}; + +export const fetchRegions = (): AppThunk => async (dispatch) => { + const parameters = generateApiParameters( + `${config.API_BASE_URL}/v1/geo-organization-unit-code/find-all-regions`, + ); + const response = await get>(dispatch, parameters); + + if (response && from(response).any()) { + dispatch(setRegions(response)); + } +}; + +export const fetchZones = (): AppThunk => async (dispatch) => { + const parameters = generateApiParameters( + `${config.API_BASE_URL}/v1/geo-organization-unit-code/find-all-zones`, + ); + const response = await get>(dispatch, parameters); + + if (response && from(response).any()) { + dispatch(setZones(response)); + } +}; + +export const fetchCommunities = (): AppThunk => async (dispatch) => { + const parameters = generateApiParameters( + `${config.API_BASE_URL}/v1/geo-organization-unit-code/find-all-areas`, + ); + const response = await get>(dispatch, parameters); + + if (response && from(response).any()) { + dispatch(setCommunities(response)); + } +}; + +export const fetchComplaintTypeCodes = (): AppThunk => async (dispatch) => { + const parameters = generateApiParameters( + `${config.API_BASE_URL}/v1/complaint-type-code`, + ); + const response = await get>(dispatch, parameters); + + if (response && from(response).any()) { + dispatch(setComplaintTypeCodes(response)); + } +}; + +export const selectCodeTable = + (table: string) => + (state: RootState): Array => { + const { codeTables } = state; + const selected = codeTables[table as keyof CodeTableState]; + + return selected; + }; + +export const selectSortedCodeTable = + (table: string, sortBy: string) => + (state: RootState): Array => { + const { codeTables } = state; + const data = codeTables[table as keyof CodeTableState]; + + let sorted = data.sort((a: any, b: any) => + a[sortBy].localeCompare(b[sortBy]), + ); + + return sorted; + }; + + export const selectComplaintTypeDropdown = (state: RootState): Array