diff --git a/package.json b/package.json index ff27eb3..c7cfa7e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "logion-directory", - "version": "0.9.3", + "version": "0.9.4-1", "private": true, "author": { "name": "Logion Team", @@ -23,8 +23,8 @@ "typeorm": "node ./node_modules/typeorm/cli.js -d ./dist/db-tools/ormconfig.js" }, "dependencies": { - "@logion/node-api": "^0.28.4", - "@logion/rest-api-core": "^0.4.7", + "@logion/node-api": "^0.29.0-2", + "@logion/rest-api-core": "^0.4.8-6", "ansi-regex": "^6.0.1", "body-parser": "^1.20.2", "bson": "^4.7.0", diff --git a/src/logion/controllers/legalofficer.controller.ts b/src/logion/controllers/legalofficer.controller.ts index 05e76fd..6394805 100644 --- a/src/logion/controllers/legalofficer.controller.ts +++ b/src/logion/controllers/legalofficer.controller.ts @@ -10,6 +10,7 @@ import { LegalOfficerDescription, LegalOfficerFactory, } from "../model/legalofficer.model.js"; +import { ValidAccountId } from "@logion/node-api"; export function fillInSpec(spec: OpenAPIV3.Document): void { const tagName = 'Legal Officers'; @@ -67,7 +68,8 @@ export class LegalOfficerController extends ApiController { @HttpGet('/:address') @Async() async getLegalOfficer(address: string): Promise { - const legalOfficer = await this.legalOfficerRepository.findByAddress(address); + const account = ValidAccountId.polkadot(address); + const legalOfficer = await this.legalOfficerRepository.findByAccount(account); if (legalOfficer) { return this.toView(legalOfficer.getDescription()); } else { @@ -79,7 +81,7 @@ export class LegalOfficerController extends ApiController { const userIdentity = description.userIdentity; const postalAddress = description.postalAddress; return { - address: description.address, + address: description.account.address, userIdentity: { firstName: userIdentity.firstName, lastName: userIdentity.lastName, @@ -116,14 +118,14 @@ export class LegalOfficerController extends ApiController { @Async() async createOrUpdateLegalOfficer(createOrUpdate: CreateOrUpdateLegalOfficerView): Promise { const authenticatedUser = await this.authenticationService.authenticatedUser(this.request); - const address = authenticatedUser.address; + const account = authenticatedUser.toValidAccountId(); if (!await authenticatedUser.isLegalOfficer()) { - throw new UnauthorizedException(`${ address } is not a Legal Officer.`) + throw new UnauthorizedException(`${ account.address } is not a Legal Officer.`); } const userIdentity = requireDefined(createOrUpdate.userIdentity); const postalAddress = requireDefined(createOrUpdate.postalAddress); const description: LegalOfficerDescription = { - address, + account, userIdentity: { firstName: userIdentity.firstName || "", lastName: userIdentity.lastName || "", diff --git a/src/logion/model/legalofficer.model.ts b/src/logion/model/legalofficer.model.ts index 184731a..5d349e2 100644 --- a/src/logion/model/legalofficer.model.ts +++ b/src/logion/model/legalofficer.model.ts @@ -1,6 +1,9 @@ import { appDataSource } from "@logion/rest-api-core"; import { Entity, Column, PrimaryColumn, Repository } from "typeorm"; import { injectable } from "inversify"; +import { ValidAccountId } from "@logion/node-api"; + +export const DB_SS58_PREFIX = 42; @Entity("legal_officer") export class LegalOfficerAggregateRoot { @@ -43,7 +46,7 @@ export class LegalOfficerAggregateRoot { getDescription(): LegalOfficerDescription { return { - address: this.address!, + account: ValidAccountId.polkadot(this.address!), userIdentity: { firstName: this.firstName || "", lastName: this.lastName || "", @@ -64,7 +67,7 @@ export class LegalOfficerAggregateRoot { } export interface LegalOfficerDescription { - readonly address: string; + readonly account: ValidAccountId; readonly userIdentity: UserIdentity; readonly postalAddress: PostalAddress; readonly additionalDetails: string; @@ -91,7 +94,7 @@ export class LegalOfficerFactory { newLegalOfficer(description: LegalOfficerDescription): LegalOfficerAggregateRoot { const legalOfficer = new LegalOfficerAggregateRoot(); - legalOfficer.address = description.address + legalOfficer.address = description.account.getAddress(DB_SS58_PREFIX); const userIdentity = description.userIdentity; legalOfficer.firstName = userIdentity.firstName; @@ -122,8 +125,8 @@ export class LegalOfficerRepository { readonly repository: Repository - public findByAddress(address: string): Promise { - return this.repository.findOneBy({ address }); + public findByAccount(address: ValidAccountId): Promise { + return this.repository.findOneBy({ address: address.getAddress(DB_SS58_PREFIX) }); } public findAll(): Promise { diff --git a/test/integration/migration/migration.spec.ts b/test/integration/migration/migration.spec.ts index 6d64574..34c021b 100644 --- a/test/integration/migration/migration.spec.ts +++ b/test/integration/migration/migration.spec.ts @@ -1,8 +1,5 @@ -import { TestDb, Log } from "@logion/rest-api-core"; -import { MigrationInterface, QueryRunner } from "typeorm"; - -const { logger } = Log; -const { connect, disconnect, queryRunner, allMigrations } = TestDb; +import { TestDb } from "@logion/rest-api-core"; +const { connect, disconnect, queryRunner, runAllMigrations, revertAllMigrations } = TestDb; describe('Migration', () => { @@ -16,50 +13,32 @@ describe('Migration', () => { await disconnect(); }); - async function testMigrationUp(migration: MigrationInterface, runner:QueryRunner) { - logger.info("Migrating UP %s ", migration.name) - await migration.up(runner) - } - - async function runAllMigrations(runner:QueryRunner) { - for (const migration of allMigrations()) { - await testMigrationUp(migration, runner); - } - } - it("executes all up()", async () => { // Given - const runner = queryRunner() - const tablesBefore = await runner.getTables() + const runner = queryRunner(); + const tablesBefore = await runner.getTables(); // When - await runAllMigrations(runner) + await runAllMigrations(); // Then const tablesAfter = await runner.getTables(); - expect(tablesAfter.length - tablesBefore.length).toBe(NUM_OF_TABLES) + expect(tablesAfter.length - tablesBefore.length - 1).toBe(NUM_OF_TABLES); }) - async function testMigrationDown(migration: MigrationInterface, runner:QueryRunner) { - logger.info("Migrating DOWN %s ", migration.name) - await migration.down(runner) - } - it("executes all down()", async () => { // Given - const runner = queryRunner() - await runAllMigrations(runner) - const tablesBefore = await runner.getTables() + await runAllMigrations(); + const runner = queryRunner(); + const tablesBefore = await runner.getTables(); // When - for (const migration of allMigrations().reverse()) { - await testMigrationDown(migration, runner); - } + await revertAllMigrations(); // Then const tablesAfter = await runner.getTables(); - expect(tablesBefore.length - tablesAfter.length).toBe(NUM_OF_TABLES) + expect(tablesBefore.length - tablesAfter.length).toBe(NUM_OF_TABLES); }) }) diff --git a/test/integration/model/legalofficer.model.spec.ts b/test/integration/model/legalofficer.model.spec.ts index bcdc736..072218b 100644 --- a/test/integration/model/legalofficer.model.spec.ts +++ b/test/integration/model/legalofficer.model.spec.ts @@ -1,5 +1,6 @@ import { TestDb } from "@logion/rest-api-core"; import { LegalOfficerAggregateRoot, LegalOfficerRepository } from "../../../src/logion/model/legalofficer.model.js"; +import { ValidAccountId } from "@logion/node-api"; const { connect, executeScript, disconnect } = TestDb; @@ -18,7 +19,8 @@ describe("LegalOfficerRepository", () => { }); it("findByAddress", async () => { - let result = await repository.findByAddress("5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"); + const account = ValidAccountId.polkadot("5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"); + let result = await repository.findByAccount(account); expect(result?.city).toBe("Etterbeek") }) diff --git a/test/testdata.ts b/test/testdata.ts index 41336e7..f355036 100644 --- a/test/testdata.ts +++ b/test/testdata.ts @@ -1,8 +1,9 @@ +import { ValidAccountId } from "@logion/node-api"; import { LegalOfficerDescription } from "../src/logion/model/legalofficer.model.js"; export const LEGAL_OFFICERS: LegalOfficerDescription[] = [ { - address: "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", + account: ValidAccountId.polkadot("5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"), userIdentity: { firstName: "Alice", lastName: "Alice", @@ -20,7 +21,7 @@ export const LEGAL_OFFICERS: LegalOfficerDescription[] = [ additionalDetails: "", }, { - address: "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty", + account: ValidAccountId.polkadot("5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"), userIdentity: { firstName: "Bob", lastName: "Bob", @@ -38,7 +39,7 @@ export const LEGAL_OFFICERS: LegalOfficerDescription[] = [ additionalDetails: "", }, { - address: "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y", + account: ValidAccountId.polkadot("5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y"), userIdentity: { firstName: "Charlie", lastName: "Charlie", diff --git a/test/unit/controllers/legalofficer.controller.spec.ts b/test/unit/controllers/legalofficer.controller.spec.ts index 68f96d3..cb9374d 100644 --- a/test/unit/controllers/legalofficer.controller.spec.ts +++ b/test/unit/controllers/legalofficer.controller.spec.ts @@ -9,10 +9,12 @@ import { LegalOfficerAggregateRoot, LegalOfficerFactory, LegalOfficerDescription, + DB_SS58_PREFIX, } from "../../../src/logion/model/legalofficer.model.js"; import { LEGAL_OFFICERS } from "../../testdata.js"; +import { ValidAccountId } from "@logion/node-api"; -const AUTHENTICATED_ADDRESS = LEGAL_OFFICERS[0].address; +const AUTHENTICATED_ADDRESS = LEGAL_OFFICERS[0].account; const { setupApp, mockAuthenticationForUserOrLegalOfficer } = TestApp; describe("LegalOfficerController", () => { @@ -32,11 +34,11 @@ describe("LegalOfficerController", () => { it("should fetch one legal officer", async () => { const app = setupApp(LegalOfficerController, mockForFetch) await request(app) - .get("/api/legal-officer/5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY") + .get("/api/legal-officer/vQx5kESPn8dWyX4KxMCKqUyCaWUwtui1isX6PVNcZh2Ghjitr") .expect(200) .expect('Content-Type', /application\/json/) .then(response => { - expect(response.body.address).toBe("5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY") + expect(response.body.address).toBe("vQx5kESPn8dWyX4KxMCKqUyCaWUwtui1isX6PVNcZh2Ghjitr") const userIdentity = response.body.userIdentity; expect(userIdentity.firstName).toBe("Alice") expect(userIdentity.lastName).toBe("Alice") @@ -61,7 +63,7 @@ describe("LegalOfficerController", () => { .expect(200) .expect('Content-Type', /application\/json/) .then(response => { - expect(response.body.address).toBe(AUTHENTICATED_ADDRESS) + expect(response.body.address).toBe(AUTHENTICATED_ADDRESS.address) const userIdentity = response.body.userIdentity; expect(userIdentity.firstName).toBe("Alice") expect(userIdentity.lastName).toBe("Alice") @@ -84,7 +86,7 @@ describe("LegalOfficerController", () => { .put("/api/legal-officer") .send(payload) .expect(401) - .expect('Content-Type', /application\/json/) + .expect('Content-Type', /application\/json/); }) }) @@ -100,7 +102,7 @@ function mockForFetch(container: Container) { ]; repository.setup(instance => instance.findAll()) .returns(Promise.resolve(legalOfficers)); - repository.setup(instance => instance.findByAddress(It.IsAny())) + repository.setup(instance => instance.findByAccount(It.IsAny())) .returns(Promise.resolve(legalOfficer0)); const factory = new Mock(); @@ -109,7 +111,7 @@ function mockForFetch(container: Container) { function mockForCreateOrUpdate(container: Container) { const repository = new Mock(); - container.bind(LegalOfficerRepository).toConstantValue(repository.object()) + container.bind(LegalOfficerRepository).toConstantValue(repository.object()); const legalOfficer0 = mockLegalOfficer(repository, 0); const legalOfficers = [ legalOfficer0, @@ -117,21 +119,21 @@ function mockForCreateOrUpdate(container: Container) { mockLegalOfficer(repository, 2), ]; repository.setup(instance => instance.findAll()) - .returns(Promise.resolve(legalOfficers)) + .returns(Promise.resolve(legalOfficers)); repository.setup(instance => instance.save(It.IsAny())) - .returns(Promise.resolve()) + .returns(Promise.resolve()); const factory = new Mock(); - container.bind(LegalOfficerFactory).toConstantValue(factory.object()) + container.bind(LegalOfficerFactory).toConstantValue(factory.object()); factory.setup(instance => instance.newLegalOfficer(It.IsAny())) - .returns(legalOfficer0) + .returns(legalOfficer0); } function mockLegalOfficer(repository: Mock, idx:number):LegalOfficerAggregateRoot { const legalOfficer = new Mock(); - legalOfficer.setup(instance => instance.getDescription()).returns(LEGAL_OFFICERS[idx]) - legalOfficer.setup(instance => instance.address).returns(LEGAL_OFFICERS[idx].address) - repository.setup(instance => instance.findByAddress(It.Is(address => address === LEGAL_OFFICERS[idx].address))) - .returns(Promise.resolve(legalOfficer.object())) + legalOfficer.setup(instance => instance.getDescription()).returns(LEGAL_OFFICERS[idx]); + legalOfficer.setup(instance => instance.address).returns(LEGAL_OFFICERS[idx].account.getAddress(DB_SS58_PREFIX)); + repository.setup(instance => instance.findByAccount(It.Is(account => account.equals(LEGAL_OFFICERS[idx].account)))) + .returns(Promise.resolve(legalOfficer.object())); return legalOfficer.object(); } diff --git a/test/unit/model/legalofficer.model.spec.ts b/test/unit/model/legalofficer.model.spec.ts index 00c60dc..a22212b 100644 --- a/test/unit/model/legalofficer.model.spec.ts +++ b/test/unit/model/legalofficer.model.spec.ts @@ -1,4 +1,4 @@ -import { LegalOfficerFactory, LegalOfficerDescription } from "../../../src/logion/model/legalofficer.model.js"; +import { LegalOfficerFactory, LegalOfficerDescription, DB_SS58_PREFIX } from "../../../src/logion/model/legalofficer.model.js"; import { LEGAL_OFFICERS } from "../../testdata.js"; describe("LegalOfficerFactory", () => { @@ -14,9 +14,9 @@ describe("LegalOfficerFactory", () => { function testNewLegalOfficer(legalOfficer: LegalOfficerDescription) { let aggregate = factory.newLegalOfficer(legalOfficer) - expect(aggregate.address).toBe(legalOfficer.address) - expect(aggregate.getDescription().userIdentity).toEqual(legalOfficer.userIdentity) - expect(aggregate.getDescription().postalAddress).toEqual(legalOfficer.postalAddress) - expect(aggregate.getDescription().additionalDetails).toEqual(legalOfficer.additionalDetails) + expect(aggregate.address).toBe(legalOfficer.account.getAddress(DB_SS58_PREFIX)); + expect(aggregate.getDescription().userIdentity).toEqual(legalOfficer.userIdentity); + expect(aggregate.getDescription().postalAddress).toEqual(legalOfficer.postalAddress); + expect(aggregate.getDescription().additionalDetails).toEqual(legalOfficer.additionalDetails); } }) diff --git a/yarn.lock b/yarn.lock index 7e07d65..201d32b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -494,11 +494,12 @@ __metadata: languageName: node linkType: hard -"@logion/authenticator@npm:^0.5.5": - version: 0.5.5 - resolution: "@logion/authenticator@npm:0.5.5" +"@logion/authenticator@npm:^0.5.6-4": + version: 0.5.6-4 + resolution: "@logion/authenticator@npm:0.5.6-4" dependencies: "@ethersproject/transactions": ^5.7.0 + "@logion/node-api": ^0.29.0-2 "@multiversx/sdk-core": ^12.19.1 "@multiversx/sdk-wallet": ^4.3.0 ethers: ^6.11.1 @@ -508,13 +509,13 @@ __metadata: web3-utils: ^4.2.1 peerDependencies: "@logion/node-api": 0.x - checksum: 13783c7d56a319eb7dba070f499c5eb9fc86d3db8c130412c98a2ed988196e59d9a1f86464c61fb68f86fa0108563c88e2f34c2c3dfcc251f6050e8ecfb5bf7d + checksum: 43568b5446ccdfe7b9d0eedc526caa7e2dda64702f83ebe7a326d3c9480d17214b6c06cf3e964dcec98c9c472f7efbb35de6715fb888303c310ff98938217580 languageName: node linkType: hard -"@logion/node-api@npm:^0.28.4": - version: 0.28.4 - resolution: "@logion/node-api@npm:0.28.4" +"@logion/node-api@npm:^0.29.0-2": + version: 0.29.0-3 + resolution: "@logion/node-api@npm:0.29.0-3" dependencies: "@polkadot/api": ^10.12.2 "@polkadot/util": ^12.6.2 @@ -522,15 +523,15 @@ __metadata: "@types/uuid": ^9.0.2 fast-sha256: ^1.3.0 uuid: ^9.0.0 - checksum: 0a2ac1fe3cfb06326a4ca1374b786fafa634830471258d618aafefe0effb2e682a9febe4a301b71e5a9d22c5daaba2beb43f3838ca13ecfea8917da40bb14c3a + checksum: 8b7759ec19d4ebbf7eddf1c8a9d6308f2ee83c9fd9232538d04eaa2b35344eaf36554304ac8a95cf40baa5475eb75d990070b49b72bb84f21c3e0c73cc21f016 languageName: node linkType: hard -"@logion/rest-api-core@npm:^0.4.7": - version: 0.4.7 - resolution: "@logion/rest-api-core@npm:0.4.7" +"@logion/rest-api-core@npm:^0.4.8-6": + version: 0.4.8-6 + resolution: "@logion/rest-api-core@npm:0.4.8-6" dependencies: - "@logion/authenticator": ^0.5.5 + "@logion/authenticator": ^0.5.6-4 dinoloop: ^2.4.0 express: ^4.18.2 express-fileupload: ^1.4.0 @@ -540,7 +541,7 @@ __metadata: swagger-ui-express: ^5.0.0 typeorm: ^0.3.11 typeorm-transactional: ^0.4.1 - checksum: 5fed0d747155c5fdeea3a192c7b9b88b92908c83b50a12a5f4e2c7522c5bcc08dc4b340bac170fa0b2bd7ef71cee624f99c27623ed034d5866fb836800249cc4 + checksum: 4b49b7a9c8d32def4c501296bd0b45cacec4cffb053495d38270ccaec0e8172bb8584f28f7bb437cea6e3b3b4da96faacfe6ec75d98a36d5dcb12f2bc862ef8f languageName: node linkType: hard @@ -3922,8 +3923,8 @@ __metadata: resolution: "logion-directory@workspace:." dependencies: "@istanbuljs/nyc-config-typescript": ^1.0.2 - "@logion/node-api": ^0.28.4 - "@logion/rest-api-core": ^0.4.7 + "@logion/node-api": ^0.29.0-2 + "@logion/rest-api-core": ^0.4.8-6 "@tsconfig/node18": ^1.0.1 "@types/cors": ^2.8.12 "@types/express": ^4.17.13