From 5e3a40ec0f3d852b94e3f545abf72071ad0cf0b3 Mon Sep 17 00:00:00 2001 From: Air1 Date: Mon, 18 Nov 2019 15:43:33 +0400 Subject: [PATCH 1/2] fix: use wallet publicKey as id for wallet busness --- .../src/handlers/bridgechains/schema.ts | 18 +++++++------- .../src/handlers/businesses/methods.ts | 8 +++---- .../src/handlers/businesses/schema.ts | 24 +++++++++---------- .../src/handlers/wallets/transformer.ts | 2 +- .../wallets-business-repository.ts | 13 ++++------ .../src/handlers/business-registration.ts | 6 ----- .../src/interfaces.ts | 1 - .../src/wallet-manager.ts | 4 ++-- 8 files changed, 32 insertions(+), 44 deletions(-) diff --git a/packages/core-api/src/handlers/bridgechains/schema.ts b/packages/core-api/src/handlers/bridgechains/schema.ts index ca4afd5cae..75cd5cdfeb 100644 --- a/packages/core-api/src/handlers/bridgechains/schema.ts +++ b/packages/core-api/src/handlers/bridgechains/schema.ts @@ -6,9 +6,9 @@ export const index: object = { ...pagination, ...{ orderBy, - businessId: Joi.number() - .integer() - .min(1), + publicKey: Joi.string() + .hex() + .length(66), bridgechainId: Joi.number() .integer() .min(1), @@ -18,9 +18,9 @@ export const index: object = { export const show: object = { params: { - id: Joi.number() - .integer() - .min(1), + id: Joi.string() + .hex() + .length(66), }, }; @@ -36,9 +36,9 @@ export const search: object = { .integer() .min(1), bridgechainRepository: Joi.string().max(80), - businessId: Joi.number() - .integer() - .min(1), + publicKey: Joi.string() + .hex() + .length(66), genesisHash: Joi.string() .hex() .length(64), diff --git a/packages/core-api/src/handlers/businesses/methods.ts b/packages/core-api/src/handlers/businesses/methods.ts index 3733fb3c1b..7f0af611df 100644 --- a/packages/core-api/src/handlers/businesses/methods.ts +++ b/packages/core-api/src/handlers/businesses/methods.ts @@ -16,9 +16,7 @@ const index = async request => { }; const show = async request => { - const business = databaseService.wallets.search(Database.SearchScope.Businesses, { - businessId: request.params.id, - }).rows[0]; + const business = databaseService.walletManager.findByPublicKey(request.params.id); if (!business) { return Boom.notFound("Business not found"); @@ -29,7 +27,7 @@ const show = async request => { const bridgechains = async request => { const business = databaseService.wallets.search(Database.SearchScope.Businesses, { - businessId: request.params.id, + publicKey: request.params.id, }); if (!business) { @@ -37,7 +35,7 @@ const bridgechains = async request => { } const bridgechains = databaseService.wallets.search(Database.SearchScope.Bridgechains, { - businessId: request.params.id, + publicKey: request.params.id, ...request.query, ...paginate(request), }); diff --git a/packages/core-api/src/handlers/businesses/schema.ts b/packages/core-api/src/handlers/businesses/schema.ts index a2729eb53a..de7ab15286 100644 --- a/packages/core-api/src/handlers/businesses/schema.ts +++ b/packages/core-api/src/handlers/businesses/schema.ts @@ -6,26 +6,26 @@ export const index: object = { ...pagination, ...{ orderBy, - businessId: Joi.number() - .integer() - .min(1), + publicKey: Joi.string() + .hex() + .length(66), }, }, }; export const show: object = { params: { - id: Joi.number() - .integer() - .min(1), + id: Joi.string() + .hex() + .length(66), }, }; export const bridgechains: object = { params: { - id: Joi.number() - .integer() - .min(1), + id: Joi.string() + .hex() + .length(66), }, query: { ...pagination, @@ -43,9 +43,9 @@ export const search: object = { }, }, payload: { - businessId: Joi.number() - .integer() - .min(1), + publicKey: Joi.string() + .hex() + .length(66), name: Joi.string() .regex(/^[a-zA-Z0-9_-]+$/) .max(40), diff --git a/packages/core-api/src/handlers/wallets/transformer.ts b/packages/core-api/src/handlers/wallets/transformer.ts index d58ca8d3e0..22ff355154 100644 --- a/packages/core-api/src/handlers/wallets/transformer.ts +++ b/packages/core-api/src/handlers/wallets/transformer.ts @@ -14,7 +14,7 @@ export const transformWallet = (wallet: State.IWallet) => { if (business) { business = { ...business.businessAsset, - businessId: business.businessId, + publicKey: wallet.publicKey, resigned: business.resigned, }; } diff --git a/packages/core-database/src/repositories/wallets-business-repository.ts b/packages/core-database/src/repositories/wallets-business-repository.ts index 982fdb3c94..93f42612cd 100644 --- a/packages/core-database/src/repositories/wallets-business-repository.ts +++ b/packages/core-database/src/repositories/wallets-business-repository.ts @@ -212,9 +212,7 @@ export class WalletsBusinessRepository implements Database.IWalletsBusinessRepos timestamp: lock.timestamp, expirationType: lock.expiration.type, expirationValue: lock.expiration.value, - isExpired: expirationCalculator.calculateLockExpirationStatus( - lock.expiration, - ), + isExpired: expirationCalculator.calculateLockExpirationStatus(lock.expiration), vendorField: lock.vendorField, }); } @@ -231,7 +229,7 @@ export class WalletsBusinessRepository implements Database.IWalletsBusinessRepos private searchBusinesses(params: Database.IParameters = {}): ISearchContext { const query: Record = { - exact: ["businessId", "vat"], + exact: ["publicKey", "vat"], like: ["name", "repository", "website"], }; @@ -242,7 +240,7 @@ export class WalletsBusinessRepository implements Database.IWalletsBusinessRepos const business: any = wallet.getAttribute("business"); return { address: wallet.address, - businessId: business.businessId, + publicKey: wallet.publicKey, ...business.businessAsset, }; }); @@ -256,7 +254,7 @@ export class WalletsBusinessRepository implements Database.IWalletsBusinessRepos private searchBridgechains(params: Database.IParameters = {}): ISearchContext { const query: Record = { - exact: ["bridgechainId", "businessId", "genesisHash"], + exact: ["bridgechainId", "publicKey", "genesisHash"], like: ["bridgechainRepository", "name"], every: ["seedNodes"], }; @@ -265,14 +263,13 @@ export class WalletsBusinessRepository implements Database.IWalletsBusinessRepos .walletManager.getIndex("bridgechains") .entries() .reduce((acc, [bridgechainId, wallet]) => { - const business: any = wallet.getAttribute("business"); const bridgechains: any[] = wallet.getAttribute("business.bridgechains"); if (bridgechains && bridgechains[bridgechainId]) { const bridgechain: any = bridgechains[bridgechainId]; acc.push({ bridgechainId: bridgechain.bridgechainId, - businessId: business.businessId, + publicKey: wallet.publicKey, ...bridgechain.bridgechainAsset, }); } diff --git a/packages/core-magistrate-transactions/src/handlers/business-registration.ts b/packages/core-magistrate-transactions/src/handlers/business-registration.ts index 871c021c4a..2e1dc6a27b 100644 --- a/packages/core-magistrate-transactions/src/handlers/business-registration.ts +++ b/packages/core-magistrate-transactions/src/handlers/business-registration.ts @@ -37,7 +37,6 @@ export class BusinessRegistrationTransactionHandler extends MagistrateTransactio const wallet: State.IWallet = walletManager.findByPublicKey(transaction.senderPublicKey); const asset: IBusinessWalletAttributes = { businessAsset: transaction.asset.businessRegistration, - businessId: this.getBusinessId(walletManager), }; wallet.setAttribute("business", asset); @@ -94,7 +93,6 @@ export class BusinessRegistrationTransactionHandler extends MagistrateTransactio const sender: State.IWallet = walletManager.findByPublicKey(transaction.data.senderPublicKey); const businessAsset: IBusinessWalletAttributes = { businessAsset: transaction.data.asset.businessRegistration, - businessId: this.getBusinessId(walletManager), }; sender.setAttribute("business", businessAsset); @@ -124,8 +122,4 @@ export class BusinessRegistrationTransactionHandler extends MagistrateTransactio walletManager: State.IWalletManager, // tslint:disable-next-line:no-empty ): Promise {} - - private getBusinessId(walletManager: State.IWalletManager): number { - return walletManager.getIndex(MagistrateIndex.Businesses).values().length + 1; - } } diff --git a/packages/core-magistrate-transactions/src/interfaces.ts b/packages/core-magistrate-transactions/src/interfaces.ts index a3a005e8c7..2789eac0b2 100644 --- a/packages/core-magistrate-transactions/src/interfaces.ts +++ b/packages/core-magistrate-transactions/src/interfaces.ts @@ -2,7 +2,6 @@ import { Interfaces } from "@arkecosystem/core-magistrate-crypto"; export interface IBusinessWalletAttributes { businessAsset: Interfaces.IBusinessRegistrationAsset; - businessId: number; resigned?: boolean; bridgechains?: Record; } diff --git a/packages/core-magistrate-transactions/src/wallet-manager.ts b/packages/core-magistrate-transactions/src/wallet-manager.ts index bfb62f2f0e..ab3f6f8384 100644 --- a/packages/core-magistrate-transactions/src/wallet-manager.ts +++ b/packages/core-magistrate-transactions/src/wallet-manager.ts @@ -10,7 +10,7 @@ export const businessIndexer = (index: State.IWalletIndex, wallet: State.IWallet if (wallet.hasAttribute("business")) { const business: IBusinessWalletAttributes = wallet.getAttribute("business"); if (business !== undefined && !business.resigned) { - index.set(business.businessId.toString(), wallet); + index.set(wallet.publicKey, wallet); } } }; @@ -19,7 +19,7 @@ export const bridgechainIndexer = (index: State.IWalletIndex, wallet: State.IWal if (wallet.hasAttribute("business.bridgechains")) { const bridgechains: Record = wallet.getAttribute("business.bridgechains"); for (const bridgechainId of Object.keys(bridgechains)) { - // TODO: allow generic index values to create more sophisticated indexes like businessId -> bridgechains + // TODO: allow generic index values to create more sophisticated indexes like publicKey -> bridgechains index.set(bridgechainId, wallet); } } From e5cfdaf7a9aec3eb7289638ac7a18e5a662676da Mon Sep 17 00:00:00 2001 From: Air1 Date: Mon, 18 Nov 2019 15:44:07 +0400 Subject: [PATCH 2/2] test: update tests for businessId refactor --- .../core-api/handlers/businesses.test.ts | 92 +++++++++++++++++++ .../handlers/business-registration.test.ts | 19 ++-- __tests__/unit/core-magistrate/wallet.test.ts | 1 - 3 files changed, 101 insertions(+), 11 deletions(-) create mode 100644 __tests__/integration/core-api/handlers/businesses.test.ts diff --git a/__tests__/integration/core-api/handlers/businesses.test.ts b/__tests__/integration/core-api/handlers/businesses.test.ts new file mode 100644 index 0000000000..56dac623bf --- /dev/null +++ b/__tests__/integration/core-api/handlers/businesses.test.ts @@ -0,0 +1,92 @@ +import "../../../utils"; + +import { app } from "@arkecosystem/core-container"; +import { Database, State } from "@arkecosystem/core-interfaces"; +import { setUp, tearDown } from "../__support__/setup"; +import { utils } from "../utils"; + +const publicKey = "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647"; + +beforeAll(async () => await setUp()); +afterAll(async () => await tearDown()); + +describe("API 2.0 - Businesses", () => { + let walletManager: State.IWalletManager; + const businessAttribute = { + businessAsset: { + name: "bizzz", + website: "biz.com", + bridgechains: { + "127e6fbfe24a750e72930c220a8e138275656b8e5d8f48a98c3c92df2caba935": { + name: "arkecosystem1", + seedNodes: [ + "74.125.224.71", + "74.125.224.72", + "64.233.173.193", + "2001:4860:4860::8888", + "2001:4860:4860::8844", + ], + genesisHash: "127e6fbfe24a750e72930c220a8e138275656b8e5d8f48a98c3c92df2caba935", + bridgechainRepository: "http://www.repository.com/myorg/myrepo", + }, + }, + }, + }; + + beforeAll(() => { + walletManager = app.resolvePlugin("database").walletManager; + + const wallet = walletManager.findByPublicKey(publicKey); + wallet.setAttribute("business", businessAttribute); + wallet.setAttribute("business.bridgechains", businessAttribute.businessAsset.bridgechains); + + walletManager.reindex(wallet); + }); + + describe("GET /businesses", () => { + it("should GET all businesses", async () => { + const response = await utils.request("GET", `businesses`); + expect(response).toBeSuccessfulResponse(); + expect(response.data.data).toBeArray(); + expect(response.data.data).toHaveLength(1); + + expect(response.data.data[0].publicKey).toBe(publicKey); + expect(response.data.data[0].name).toEqual(businessAttribute.businessAsset.name); + expect(response.data.data[0].website).toEqual(businessAttribute.businessAsset.website); + }); + }); + + describe("GET /businesses/:id", () => { + it("should GET business by id (wallet publicKey)", async () => { + const response = await utils.request("GET", `businesses/${publicKey}`); + expect(response).toBeSuccessfulResponse(); + expect(response.data.data).toBeObject(); + expect(response.data.data.attributes.business).toEqual(businessAttribute); + }); + }); + + describe("GET /businesses/:id/bridgechains", () => { + it("should GET business bridgechains", async () => { + const response = await utils.request("GET", `businesses/${publicKey}/bridgechains`); + expect(response).toBeSuccessfulResponse(); + expect(response.data.data).toBeArray(); + expect(response.data.data).toHaveLength(1); + // TODO check bridgechainId is correct (after bridgechainId = genesisHash PR is merged) + }); + }); + + describe("POST /businesses/search", () => { + it("should POST a search for businesses by name", async () => { + const response = await utils.request("POST", "businesses/search", { + name: businessAttribute.businessAsset.name, + }); + expect(response).toBeSuccessfulResponse(); + expect(response.data.data).toBeArray(); + expect(response.data.data).toHaveLength(1); + + expect(response.data.data[0].publicKey).toBe(publicKey); + expect(response.data.data[0].name).toEqual(businessAttribute.businessAsset.name); + expect(response.data.data[0].website).toEqual(businessAttribute.businessAsset.website); + }); + }); +}); diff --git a/__tests__/unit/core-magistrate/handlers/business-registration.test.ts b/__tests__/unit/core-magistrate/handlers/business-registration.test.ts index b6a06076d7..2efc5b6e59 100644 --- a/__tests__/unit/core-magistrate/handlers/business-registration.test.ts +++ b/__tests__/unit/core-magistrate/handlers/business-registration.test.ts @@ -112,10 +112,7 @@ describe("Business registration handler", () => { await businessRegistrationHandler.applyToSender(actual.build(), walletManager); - const wallet = walletManager.findByIndex( - MagistrateIndex.Businesses, - senderWallet.getAttribute("business").businessId.toString(), - ); + const wallet = walletManager.findByIndex(MagistrateIndex.Businesses, senderWallet.publicKey); expect(wallet).toStrictEqual(senderWallet); }); @@ -124,7 +121,6 @@ describe("Business registration handler", () => { describe("revertForSender", () => { it("should not fail", async () => { senderWallet.setAttribute("business", { - businessId: 1, businessAsset: businessRegistrationAsset1, }); senderWallet.nonce = Utils.BigNumber.make(1); @@ -138,14 +134,13 @@ describe("Business registration handler", () => { it("should be undefined", async () => { senderWallet.setAttribute("business", { - businessId: 1, businessAsset: businessRegistrationAsset1, }); senderWallet.nonce = Utils.BigNumber.make(1); walletManager.reindex(senderWallet); - let wallet = walletManager.findByIndex(MagistrateIndex.Businesses, "1"); - expect(wallet).toBe(senderWallet); + const initialWallet = walletManager.findByIndex(MagistrateIndex.Businesses, senderWallet.publicKey); + expect(initialWallet).toBe(senderWallet); const actual = businessRegistrationBuilder .businessRegistrationAsset(businessRegistrationAsset1) @@ -154,8 +149,12 @@ describe("Business registration handler", () => { await businessRegistrationHandler.revertForSender(actual.build(), walletManager); - wallet = walletManager.findByIndex(MagistrateIndex.Businesses, "1"); - expect(wallet.getAttribute("business")).toBeUndefined(); + const walletByIndexAfterRevert = walletManager.findByIndex( + MagistrateIndex.Businesses, + senderWallet.publicKey, + ); + expect(walletByIndexAfterRevert).toBeUndefined(); + expect(initialWallet.getAttribute("business")).toBeUndefined(); }); }); }); diff --git a/__tests__/unit/core-magistrate/wallet.test.ts b/__tests__/unit/core-magistrate/wallet.test.ts index 098062df01..2e34dff86c 100644 --- a/__tests__/unit/core-magistrate/wallet.test.ts +++ b/__tests__/unit/core-magistrate/wallet.test.ts @@ -8,7 +8,6 @@ describe("should test wallet", () => { Handlers.Registry.registerTransactionHandler(BusinessRegistrationTransactionHandler); const senderWallet: Wallets.Wallet = new Wallets.Wallet("ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo"); const businessAttributes: IBusinessWalletAttributes = { - businessId: 1, businessAsset: { name: "google", website: "https://www.google.com",