diff --git a/e2e/infrastructure/RestrictionHttp.spec.ts b/e2e/infrastructure/RestrictionHttp.spec.ts index ec96ac6b80..96abcd3739 100644 --- a/e2e/infrastructure/RestrictionHttp.spec.ts +++ b/e2e/infrastructure/RestrictionHttp.spec.ts @@ -35,6 +35,7 @@ import { MosaicGlobalRestrictionTransaction } from '../../src/model/transaction/ import { UInt64 } from '../../src/model/UInt64'; import { IntegrationTestHelper } from './IntegrationTestHelper'; import { AddressRestrictionFlag } from '../../src/model/restriction/AddressRestrictionFlag'; +import { MosaicAddressRestriction } from '../../src/model/restriction/MosaicAddressRestriction'; describe('RestrictionHttp', () => { const helper = new IntegrationTestHelper(); @@ -203,66 +204,15 @@ describe('RestrictionHttp', () => { }); }); - describe('getAccountRestrictionsFromAccounts', () => { - it('should call getAccountRestrictionsFromAccounts successfully', async () => { - const accountRestrictions = await restrictionAccountRepository.getAccountRestrictionsFromAccounts([accountAddress]).toPromise(); - deepEqual(accountRestrictions[0]!.address, accountAddress); - }); - }); - - describe('getMosaicAddressRestriction', () => { - it('should call getMosaicAddressRestriction successfully', async () => { - const mosaicRestriction = await restrictionMosaicRepository.getMosaicAddressRestriction(mosaicId, account3.address).toPromise(); - deepEqual(mosaicRestriction.mosaicId.toHex(), mosaicId.toHex()); - deepEqual(mosaicRestriction.entryType, MosaicRestrictionEntryType.ADDRESS); - deepEqual(mosaicRestriction.targetAddress.plain(), account3.address.plain()); - deepEqual(mosaicRestriction.restrictions.get(UInt64.fromUint(60641).toString()), UInt64.fromUint(2).toString()); - }); - }); - - describe('getMosaicAddressRestrictions', () => { - it('should call getMosaicAddressRestrictions successfully', async () => { - const mosaicRestriction = await restrictionMosaicRepository - .getMosaicAddressRestrictions(mosaicId, [account3.address]) + describe('search', () => { + it('should call search successfully', async () => { + const mosaicRestrictionPage = await restrictionMosaicRepository + .searchMosaicRestrictions({ mosaicId, targetAddress: account3.address }) .toPromise(); - deepEqual(mosaicRestriction[0].mosaicId.toHex(), mosaicId.toHex()); - deepEqual(mosaicRestriction[0].entryType, MosaicRestrictionEntryType.ADDRESS); - deepEqual(mosaicRestriction[0].targetAddress.plain(), account3.address.plain()); - deepEqual(mosaicRestriction[0].restrictions.get(UInt64.fromUint(60641).toString()), UInt64.fromUint(2).toString()); - }); - }); - - describe('getMosaicGlobalRestriction', () => { - it('should call getMosaicGlobalRestriction successfully', async () => { - const mosaicRestriction = await restrictionMosaicRepository.getMosaicGlobalRestriction(mosaicId).toPromise(); - deepEqual(mosaicRestriction.mosaicId.toHex(), mosaicId.toHex()); - deepEqual(mosaicRestriction.entryType, MosaicRestrictionEntryType.GLOBAL); - deepEqual( - mosaicRestriction.restrictions.get(UInt64.fromUint(60641).toString())!.referenceMosaicId.toHex(), - new MosaicId(UInt64.fromUint(0).toHex()).toHex(), - ); - deepEqual(mosaicRestriction.restrictions.get(UInt64.fromUint(60641).toString())!.restrictionType, MosaicRestrictionType.GE); - deepEqual( - mosaicRestriction.restrictions.get(UInt64.fromUint(60641).toString())!.restrictionValue.toString(), - UInt64.fromUint(0).toString(), - ); - }); - }); - - describe('getMosaicGlobalRestrictions', () => { - it('should call getMosaicGlobalRestrictions successfully', async () => { - const mosaicRestriction = await restrictionMosaicRepository.getMosaicGlobalRestrictions([mosaicId]).toPromise(); - deepEqual(mosaicRestriction[0].mosaicId.toHex(), mosaicId.toHex()); - deepEqual(mosaicRestriction[0].entryType, MosaicRestrictionEntryType.GLOBAL); - deepEqual( - mosaicRestriction[0].restrictions.get(UInt64.fromUint(60641).toString())!.referenceMosaicId.toHex(), - new MosaicId(UInt64.fromUint(0).toHex()).toHex(), - ); - deepEqual(mosaicRestriction[0].restrictions.get(UInt64.fromUint(60641).toString())!.restrictionType, MosaicRestrictionType.GE); - deepEqual( - mosaicRestriction[0].restrictions.get(UInt64.fromUint(60641).toString())!.restrictionValue.toString(), - UInt64.fromUint(0).toString(), - ); + deepEqual(mosaicRestrictionPage.data[0].mosaicId.toHex(), mosaicId.toHex()); + deepEqual(mosaicRestrictionPage.data[0].entryType, MosaicRestrictionEntryType.ADDRESS); + deepEqual((mosaicRestrictionPage.data[0] as MosaicAddressRestriction).targetAddress.plain(), account3.address.plain()); + deepEqual(mosaicRestrictionPage.data[0].restrictions.get(UInt64.fromUint(60641).toString()), UInt64.fromUint(2).toString()); }); }); diff --git a/e2e/infrastructure/TransactionHttp.spec.ts b/e2e/infrastructure/TransactionHttp.spec.ts index 608cd4e8fc..ce632541a6 100644 --- a/e2e/infrastructure/TransactionHttp.spec.ts +++ b/e2e/infrastructure/TransactionHttp.spec.ts @@ -732,8 +732,8 @@ describe('TransactionHttp', () => { const votingLinkTransaction = VotingKeyLinkTransaction.create( Deadline.create(), votingKey, - UInt64.fromUint(100), - UInt64.fromUint(300), + 100, + 300, LinkAction.Link, networkType, helper.maxFee, @@ -742,8 +742,8 @@ describe('TransactionHttp', () => { return helper.announce(signedTransaction).then((transaction: VotingKeyLinkTransaction) => { expect(transaction.linkedPublicKey, 'LinkedPublicKey').not.to.be.undefined; - expect(transaction.startPoint, 'StartPoint').not.to.be.undefined; - expect(transaction.endPoint, 'EndPoint').not.to.be.undefined; + expect(transaction.startEpoch, 'startEpoch').not.to.be.undefined; + expect(transaction.endEpoch, 'endEpoch').not.to.be.undefined; expect(transaction.linkAction, 'LinkAction').not.to.be.undefined; return signedTransaction; }); @@ -754,8 +754,8 @@ describe('TransactionHttp', () => { const votingLinkTransaction = VotingKeyLinkTransaction.create( Deadline.create(), votingKey, - UInt64.fromUint(100), - UInt64.fromUint(300), + 100, + 300, LinkAction.Unlink, networkType, helper.maxFee, diff --git a/package-lock.json b/package-lock.json index f64864bbce..89c1ff191f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1110,9 +1110,9 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "catbuffer-typescript": { - "version": "0.0.21", - "resolved": "https://registry.npmjs.org/catbuffer-typescript/-/catbuffer-typescript-0.0.21.tgz", - "integrity": "sha512-fKz6NoojjWOf7eJRZeh3pH6wMkxTXSfH/55yfzaImnhTQeaL6j1xiYElgWDDkKDJe2N4UWUJywRjbfT96I/GJw==" + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/catbuffer-typescript/-/catbuffer-typescript-0.0.22.tgz", + "integrity": "sha512-Wip3kJFnXrsMRF+4yJSE/F+aEqrTYLPPXdNuVftHNl9oFaKwQ9si8oI2ruSu53QIR+/ohOlY4QYtOagRpHnrFg==" }, "chai": { "version": "4.1.2", @@ -6611,9 +6611,9 @@ } }, "symbol-openapi-typescript-fetch-client": { - "version": "0.9.7-SNAPSHOT.202009100936", - "resolved": "https://registry.npmjs.org/symbol-openapi-typescript-fetch-client/-/symbol-openapi-typescript-fetch-client-0.9.7-SNAPSHOT.202009100936.tgz", - "integrity": "sha512-C53mXJ9cegoIo26VzMtycx4lu7vzCQbN7Q4N9yM4GfK4CxLXgheCHFP9zUxBH4PS/j8WTgGmQP3mApSZeRY2wA==" + "version": "0.9.7-SNAPSHOT.202009110940", + "resolved": "https://registry.npmjs.org/symbol-openapi-typescript-fetch-client/-/symbol-openapi-typescript-fetch-client-0.9.7-SNAPSHOT.202009110940.tgz", + "integrity": "sha512-blkoDizJKdx11pvtqaFaoXFhMuGueJ/vusjN5oIZY6vSm7GuyP8Cipkx5fBnE+J6Y3hQYpb5Ble2Be/UjG+cZw==" }, "table": { "version": "5.4.6", diff --git a/package.json b/package.json index bf89a898f6..b1fd1e1910 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ }, "dependencies": { "bluebird": "^3.7.2", - "catbuffer-typescript": "0.0.21", + "catbuffer-typescript": "0.0.22", "crypto-js": "^4.0.0", "diff": "^4.0.2", "futoin-hkdf": "^1.3.1", @@ -101,7 +101,7 @@ "ripemd160": "^2.0.2", "rxjs": "^6.5.3", "rxjs-compat": "^6.5.3", - "symbol-openapi-typescript-fetch-client": "0.9.7-SNAPSHOT.202009100936", + "symbol-openapi-typescript-fetch-client": "0.9.7-SNAPSHOT.202009110940", "tweetnacl": "^1.0.3", "utf8": "^3.0.0", "ws": "^7.2.3" diff --git a/src/infrastructure/AccountHttp.ts b/src/infrastructure/AccountHttp.ts index ab9df52edb..b0ba660591 100644 --- a/src/infrastructure/AccountHttp.ts +++ b/src/infrastructure/AccountHttp.ts @@ -119,12 +119,7 @@ export class AccountHttp extends Http implements AccountRepository { : undefined, dto.account.supplementalPublicKeys.voting ? dto.account.supplementalPublicKeys.voting?.publicKeys.map( - (v) => - new AccountLinkVotingKey( - v.publicKey, - UInt64.fromNumericString(v.startPoint), - UInt64.fromNumericString(v.endPoint), - ), + (v) => new AccountLinkVotingKey(v.publicKey, v.startEpoch, v.endEpoch), ) : undefined, ), diff --git a/src/infrastructure/RepositoryFactory.ts b/src/infrastructure/RepositoryFactory.ts index bda4dad7e7..9787df32ec 100644 --- a/src/infrastructure/RepositoryFactory.ts +++ b/src/infrastructure/RepositoryFactory.ts @@ -48,7 +48,7 @@ export interface RepositoryFactory { /** * @returns the generation hash used to sign transactions. Value retrieved from the block/1 - * endpoint. This method is cached, the server is only called the first time. + * endEpoch. This method is cached, the server is only called the first time. */ getGenerationHash(): Observable; diff --git a/src/infrastructure/RestrictionAccountHttp.ts b/src/infrastructure/RestrictionAccountHttp.ts index 4166961744..365d1cf637 100644 --- a/src/infrastructure/RestrictionAccountHttp.ts +++ b/src/infrastructure/RestrictionAccountHttp.ts @@ -19,7 +19,6 @@ import { RestrictionAccountRoutesApi } from 'symbol-openapi-typescript-fetch-cli import { DtoMapping } from '../core/utils/DtoMapping'; import { Address } from '../model/account/Address'; import { AccountRestriction } from '../model/restriction/AccountRestriction'; -import { AccountRestrictions } from '../model/restriction/AccountRestrictions'; import { Http } from './Http'; import { RestrictionAccountRepository } from './RestrictionAccountRepository'; @@ -55,20 +54,4 @@ export class RestrictionAccountHttp extends Http implements RestrictionAccountRe (body) => DtoMapping.extractAccountRestrictionFromDto(body).accountRestrictions.restrictions, ); } - - /** - * Get Account restrictions. - * @param address list of addresses - * @returns Observable - */ - public getAccountRestrictionsFromAccounts(addresses: Address[]): Observable { - const accountIds = { - addresses: addresses.map((address) => address.plain()), - }; - return this.call(this.restrictionAccountRoutesApi.getAccountRestrictionsFromAccounts(accountIds), (body) => - body.map((restriction) => { - return DtoMapping.extractAccountRestrictionFromDto(restriction).accountRestrictions; - }), - ); - } } diff --git a/src/infrastructure/RestrictionAccountRepository.ts b/src/infrastructure/RestrictionAccountRepository.ts index b029bc9d5e..259f5f7e93 100644 --- a/src/infrastructure/RestrictionAccountRepository.ts +++ b/src/infrastructure/RestrictionAccountRepository.ts @@ -17,7 +17,6 @@ import { Observable } from 'rxjs/internal/Observable'; import { Address } from '../model/account/Address'; import { AccountRestriction } from '../model/restriction/AccountRestriction'; -import { AccountRestrictions } from '../model/restriction/AccountRestrictions'; export interface RestrictionAccountRepository { /** @@ -26,11 +25,4 @@ export interface RestrictionAccountRepository { * @returns Observable */ getAccountRestrictions(address: Address): Observable; - - /** - * Gets Account restrictions. - * @param addresses list of addresses - * @returns Observable - */ - getAccountRestrictionsFromAccounts(addresses: Address[]): Observable; } diff --git a/src/infrastructure/RestrictionMosaicHttp.ts b/src/infrastructure/RestrictionMosaicHttp.ts index 33a7d995ad..093386ab30 100644 --- a/src/infrastructure/RestrictionMosaicHttp.ts +++ b/src/infrastructure/RestrictionMosaicHttp.ts @@ -27,6 +27,9 @@ import { MosaicGlobalRestriction } from '../model/restriction/MosaicGlobalRestri import { MosaicGlobalRestrictionItem } from '../model/restriction/MosaicGlobalRestrictionItem'; import { Http } from './Http'; import { RestrictionMosaicRepository } from './RestrictionMosaicRepository'; +import { RestrictionMosaicSearchCriteria } from './searchCriteria/RestrictionMosaicSearchCriteria'; +import { DtoMapping } from '../core/utils/DtoMapping'; +import { Page } from './Page'; /** * RestrictionMosaic http repository. @@ -50,90 +53,51 @@ export class RestrictionMosaicHttp extends Http implements RestrictionMosaicRepo } /** - * Get mosaic address restriction. - * @summary Get mosaic address restrictions for a given mosaic and account identifier. - * @param mosaicId Mosaic identifier. - * @param address address - * @returns Observable - */ - getMosaicAddressRestriction(mosaicId: MosaicId, address: Address): Observable { - return this.call(this.restrictionMosaicRoutesApi.getMosaicAddressRestriction(mosaicId.toHex(), address.plain()), (body) => - this.toMosaicAddressRestriction(body), - ); - } - - /** - * Get mosaic address restrictions. - * @summary Get mosaic address restrictions for a given mosaic and account identifiers array - * @param mosaicId Mosaic identifier. - * @param addresses list of addresses - * @returns Observable - */ - getMosaicAddressRestrictions(mosaicId: MosaicId, addresses: Address[]): Observable { - const accountIds = { - addresses: addresses.map((address) => address.plain()), - }; - return this.call(this.restrictionMosaicRoutesApi.getMosaicAddressRestrictions(mosaicId.toHex(), accountIds), (body) => - body.map(this.toMosaicAddressRestriction), - ); - } - - /** - * Get mosaic global restriction. - * @summary Get mosaic global restrictions for a given mosaic identifier. - * @param mosaicId Mosaic identifier. - * @returns Observable - */ - getMosaicGlobalRestriction(mosaicId: MosaicId): Observable { - return this.call(this.restrictionMosaicRoutesApi.getMosaicGlobalRestriction(mosaicId.toHex()), (body) => - this.toMosaicGlobalRestriction(body), - ); - } - - /** - * Get mosaic global restrictions. - * @summary Get mosaic global restrictions for a given list of mosaics. - * @param mosaicIds List of mosaic identifier. - * @returns Observable - */ - getMosaicGlobalRestrictions(mosaicIds: MosaicId[]): Observable { - const mosaicIdsBody = { - mosaicIds: mosaicIds.map((id) => id.toHex()), - }; - return this.call(this.restrictionMosaicRoutesApi.getMosaicGlobalRestrictions(mosaicIdsBody), (body) => - body.map(this.toMosaicGlobalRestriction), - ); - } - - /** - * This method maps a MosaicAddressRestrictionDTO from rest to the SDK's MosaicAddressRestriction model object. + * Returns a mosaic restrictions page based on the criteria. * - * @internal - * @param {MosaicAddressRestrictionDTO} dto the MosaicAddressRestrictionDTO object from rest. - * @returns {MosaicAddressRestriction} a MosaicAddressRestriction model + * @param criteria the criteria + * @return a page of {@link MosaicAddressRestriction | MosaicGlobalRestriction} */ - private toMosaicAddressRestriction(dto: MosaicAddressRestrictionDTO): MosaicAddressRestriction { - const restrictionItems = new Map(); - dto.mosaicRestrictionEntry.restrictions.forEach((restriction) => { - restrictionItems.set(restriction.key, restriction.value); - }); - return new MosaicAddressRestriction( - dto.mosaicRestrictionEntry.compositeHash, - dto.mosaicRestrictionEntry.entryType.valueOf(), - new MosaicId(dto.mosaicRestrictionEntry.mosaicId), - Address.createFromEncoded(dto.mosaicRestrictionEntry.targetAddress), - restrictionItems, + public searchMosaicRestrictions( + criteria: RestrictionMosaicSearchCriteria, + ): Observable> { + return this.call( + this.restrictionMosaicRoutesApi.searchMosaicRestriction( + criteria.mosaicId?.toHex(), + criteria.entryType?.valueOf(), + criteria.targetAddress?.plain(), + criteria.pageSize, + criteria.pageNumber, + criteria.offset, + DtoMapping.mapEnum(criteria.order), + ), + (body) => super.toPage(body.pagination, body.data, this.toMosaicRestriction), ); } /** - * This method maps a MosaicGlobalRestrictionDTO from rest to the SDK's MosaicGlobalRestriction model object. + * This method maps a mosaic restriction dto from rest to the SDK's model object. * * @internal - * @param {MosaicGlobalRestrictionDTO} dto the MosaicGlobalRestrictionDTO object from rest. - * @returns {MosaicGlobalRestriction} a MosaicGlobalRestriction model + * @param {MosaicAddressRestrictionDTO | MosaicGlobalRestrictionDTO} dto the restriction object from rest. + * @returns {MosaicAddressRestriction | MosaicGlobalRestriction} a restriction model */ - private toMosaicGlobalRestriction(dto: MosaicGlobalRestrictionDTO): MosaicGlobalRestriction { + private toMosaicRestriction( + dto: MosaicAddressRestrictionDTO | MosaicGlobalRestrictionDTO, + ): MosaicAddressRestriction | MosaicGlobalRestriction { + if ((dto.mosaicRestrictionEntry as any).targetAddress) { + const mosaicAddressrestrictionItems = new Map(); + dto.mosaicRestrictionEntry.restrictions.forEach((restriction) => { + mosaicAddressrestrictionItems.set(restriction.key, restriction.value); + }); + return new MosaicAddressRestriction( + dto.mosaicRestrictionEntry.compositeHash, + dto.mosaicRestrictionEntry.entryType.valueOf(), + new MosaicId(dto.mosaicRestrictionEntry.mosaicId), + Address.createFromEncoded((dto as MosaicAddressRestrictionDTO).mosaicRestrictionEntry.targetAddress), + mosaicAddressrestrictionItems, + ); + } const restirctionItems = new Map(); dto.mosaicRestrictionEntry.restrictions.forEach((restriction) => restirctionItems.set( diff --git a/src/infrastructure/RestrictionMosaicRepository.ts b/src/infrastructure/RestrictionMosaicRepository.ts index f6dd5cf29b..8a8fc2577e 100644 --- a/src/infrastructure/RestrictionMosaicRepository.ts +++ b/src/infrastructure/RestrictionMosaicRepository.ts @@ -15,43 +15,19 @@ */ import { Observable } from 'rxjs/internal/Observable'; -import { Address } from '../model/account/Address'; -import { MosaicId } from '../model/mosaic/MosaicId'; import { MosaicAddressRestriction } from '../model/restriction/MosaicAddressRestriction'; import { MosaicGlobalRestriction } from '../model/restriction/MosaicGlobalRestriction'; +import { RestrictionMosaicSearchCriteria } from './searchCriteria/RestrictionMosaicSearchCriteria'; +import { Page } from './Page'; export interface RestrictionMosaicRepository { /** - * Get mosaic address restriction. - * @summary Get mosaic address restrictions for a given mosaic and account identifier. - * @param mosaicId Mosaic identifier. - * @param address address - * @returns Observable + * Returns a mosaic restrictions page based on the criteria. + * + * @param criteria the criteria + * @return a page of {@link MosaicAddressRestriction | MosaicGlobalRestriction} */ - getMosaicAddressRestriction(mosaicId: MosaicId, address: Address): Observable; - - /** - * Get mosaic address restrictions. - * @summary Get mosaic address restrictions for a given mosaic and account identifiers array - * @param mosaicId Mosaic identifier. - * @param addresses list of addresses - * @returns Observable - */ - getMosaicAddressRestrictions(mosaicId: MosaicId, address: Address[]): Observable; - - /** - * Get mosaic global restriction. - * @summary Get mosaic global restrictions for a given mosaic identifier. - * @param mosaicId Mosaic identifier. - * @returns Observable - */ - getMosaicGlobalRestriction(mosaicId: MosaicId): Observable; - - /** - * Get mosaic global restrictions. - * @summary Get mosaic global restrictions for a given list of mosaics. - * @param mosaicIds List of mosaic identifier. - * @returns Observable - */ - getMosaicGlobalRestrictions(mosaicIds: MosaicId[]): Observable; + searchMosaicRestrictions( + criteria: RestrictionMosaicSearchCriteria, + ): Observable>; } diff --git a/src/infrastructure/infrastructure.ts b/src/infrastructure/infrastructure.ts index 484d9c6cf6..3768fe9d0a 100644 --- a/src/infrastructure/infrastructure.ts +++ b/src/infrastructure/infrastructure.ts @@ -70,6 +70,7 @@ export * from './searchCriteria/ResolutionStatementSearchCriteria'; export * from './searchCriteria/TransactionStatementSearchCriteria'; export * from './searchCriteria/HashLockSearchCriteria'; export * from './searchCriteria/SecretLockSearchCriteria'; +export * from './searchCriteria/RestrictionMosaicSearchCriteria'; export * from './paginationStreamer/BlockPaginationStreamer'; export * from './paginationStreamer/MosaicPaginationStreamer'; @@ -82,3 +83,4 @@ export * from './paginationStreamer/MetadataPaginationStreamer'; export * from './paginationStreamer/ReceiptPaginationStreamer'; export * from './paginationStreamer/HashLockPaginationStreamer'; export * from './paginationStreamer/SecretLockPaginationStreamer'; +export * from './paginationStreamer/RestrictionMosaicPaginationStreamer'; diff --git a/src/infrastructure/paginationStreamer/RestrictionMosaicPaginationStreamer.ts b/src/infrastructure/paginationStreamer/RestrictionMosaicPaginationStreamer.ts new file mode 100644 index 0000000000..25be4e5d85 --- /dev/null +++ b/src/infrastructure/paginationStreamer/RestrictionMosaicPaginationStreamer.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Observable } from 'rxjs/internal/Observable'; +import { Page } from '../Page'; +import { PaginationStreamer } from './PaginationStreamer'; +import { RestrictionMosaicRepository } from '../RestrictionMosaicRepository'; +import { RestrictionMosaicSearchCriteria } from '../searchCriteria/RestrictionMosaicSearchCriteria'; +import { MosaicGlobalRestriction } from '../../model/restriction/MosaicGlobalRestriction'; +import { MosaicAddressRestriction } from '../../model/restriction/MosaicAddressRestriction'; + +/** + * A helper object that streams {@link RestrictionMosaic} using the search. + */ +export class RestrictionMosaicPaginationStreamer { + /** + * It creates a restriction mosaic streamer of MosaicRestriction objects. + * + * @param repository the {@link RestrictionMosaicRepository} repository + * @return a new Pagination Streamer. + */ + public static MosaicRestrictions( + repository: RestrictionMosaicRepository, + ): PaginationStreamer { + return new PaginationStreamer({ + search(criteria: RestrictionMosaicSearchCriteria): Observable> { + return repository.searchMosaicRestrictions(criteria); + }, + }); + } +} diff --git a/src/infrastructure/searchCriteria/RestrictionMosaicSearchCriteria.ts b/src/infrastructure/searchCriteria/RestrictionMosaicSearchCriteria.ts new file mode 100644 index 0000000000..fc51a29d7b --- /dev/null +++ b/src/infrastructure/searchCriteria/RestrictionMosaicSearchCriteria.ts @@ -0,0 +1,41 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SearchCriteria } from './SearchCriteria'; +import { MosaicId } from '../../model/mosaic/MosaicId'; +import { MosaicRestrictionType } from '../../model/restriction/MosaicRestrictionType'; +import { Address } from '../../model/account/Address'; + +/** + * Defines the params used to search mosaic restrictions. With this criteria, you can sort and filter + * mosaic restriction queries using rest. + */ +export interface RestrictionMosaicSearchCriteria extends SearchCriteria { + /** + * Restrictionmosaic id. (optional) + */ + mosaicId?: MosaicId; + + /** + * Mosaic restriction entity type. (optional) + */ + entryType?: MosaicRestrictionType; + + /** + * Mosaic restriction target address. (optional) + */ + targetAddress?: Address; +} diff --git a/src/infrastructure/transaction/CreateTransactionFromDTO.ts b/src/infrastructure/transaction/CreateTransactionFromDTO.ts index 3833a376d2..aac1fc5add 100644 --- a/src/infrastructure/transaction/CreateTransactionFromDTO.ts +++ b/src/infrastructure/transaction/CreateTransactionFromDTO.ts @@ -491,8 +491,8 @@ const CreateStandaloneTransactionFromDTO = (transactionDTO, transactionInfo): Tr Deadline.createFromDTO(transactionDTO.deadline), UInt64.fromNumericString(transactionDTO.maxFee || '0'), transactionDTO.linkedPublicKey, - UInt64.fromNumericString(transactionDTO.startPoint), - UInt64.fromNumericString(transactionDTO.endPoint), + transactionDTO.startEpoch, + transactionDTO.endEpoch, transactionDTO.linkAction, transactionDTO.signature, transactionDTO.signerPublicKey diff --git a/src/infrastructure/transaction/SerializeTransactionToJSON.ts b/src/infrastructure/transaction/SerializeTransactionToJSON.ts index 55b4c4ccef..cc0a3418f3 100644 --- a/src/infrastructure/transaction/SerializeTransactionToJSON.ts +++ b/src/infrastructure/transaction/SerializeTransactionToJSON.ts @@ -269,8 +269,8 @@ export const SerializeTransactionToJSON = (transaction: Transaction): any => { const votingKeyLinkTx = transaction as VotingKeyLinkTransaction; return { linkedPublicKey: votingKeyLinkTx.linkedPublicKey, - startPoint: votingKeyLinkTx.startPoint.toString(), - endPoint: votingKeyLinkTx.endPoint.toString(), + startEpoch: votingKeyLinkTx.startEpoch.toString(), + endEpoch: votingKeyLinkTx.endEpoch.toString(), linkAction: votingKeyLinkTx.linkAction, }; default: diff --git a/src/model/account/AccountLinkVotingKey.ts b/src/model/account/AccountLinkVotingKey.ts index 1b559688a1..c1aa2f8fc0 100644 --- a/src/model/account/AccountLinkVotingKey.ts +++ b/src/model/account/AccountLinkVotingKey.ts @@ -27,12 +27,12 @@ export class AccountLinkVotingKey { */ public readonly publicKey: string, /** - * Start point + * Start epoch */ - public readonly startPoint: UInt64, + public readonly startEpoch: number, /** - * End point + * End epoch */ - public readonly endPoint: UInt64, + public readonly endEpoch: number, ) {} } diff --git a/src/model/transaction/VotingKeyLinkTransaction.ts b/src/model/transaction/VotingKeyLinkTransaction.ts index 86365a1196..7c7f737bd8 100644 --- a/src/model/transaction/VotingKeyLinkTransaction.ts +++ b/src/model/transaction/VotingKeyLinkTransaction.ts @@ -37,15 +37,15 @@ import { TransactionInfo } from './TransactionInfo'; import { TransactionType } from './TransactionType'; import { TransactionVersion } from './TransactionVersion'; import { Address } from '../account/Address'; -import { FinalizationPointDto } from 'catbuffer-typescript/dist/FinalizationPointDto'; +import { FinalizationEpochDto } from 'catbuffer-typescript/dist/FinalizationEpochDto'; export class VotingKeyLinkTransaction extends Transaction { /** * Create a voting key link transaction object * @param deadline - The deadline to include the transaction. * @param linkedPublicKey - The public key for voting (48 bytes). - * @param startPoint - The start finalization point. - * @param endPoint - The end finalization point. + * @param startEpoch - The start finalization point. + * @param endEpoch - The end finalization point. * @param linkAction - The account link action. * @param maxFee - (Optional) Max fee defined by the sender * @param signature - (Optional) Transaction signature @@ -55,8 +55,8 @@ export class VotingKeyLinkTransaction extends Transaction { public static create( deadline: Deadline, linkedPublicKey: string, - startPoint: UInt64, - endPoint: UInt64, + startEpoch: number, + endEpoch: number, linkAction: LinkAction, networkType: NetworkType, maxFee: UInt64 = new UInt64([0, 0]), @@ -69,8 +69,8 @@ export class VotingKeyLinkTransaction extends Transaction { deadline, maxFee, linkedPublicKey, - startPoint, - endPoint, + startEpoch, + endEpoch, linkAction, signature, signer, @@ -83,8 +83,8 @@ export class VotingKeyLinkTransaction extends Transaction { * @param deadline * @param maxFee * @param linkedPublicKey - * @param startPoint - * @param endPoint + * @param startEpoch + * @param endEpoch * @param linkAction * @param signature * @param signer @@ -102,11 +102,11 @@ export class VotingKeyLinkTransaction extends Transaction { /** * The start finalization point. */ - public readonly startPoint: UInt64, + public readonly startEpoch: number, /** * The start finalization point. */ - public readonly endPoint: UInt64, + public readonly endEpoch: number, /** * The account link action. */ @@ -134,8 +134,8 @@ export class VotingKeyLinkTransaction extends Transaction { const transaction = VotingKeyLinkTransaction.create( isEmbedded ? Deadline.create() : Deadline.createFromDTO((builder as VotingKeyLinkTransactionBuilder).getDeadline().timestamp), Convert.uint8ToHex(builder.getLinkedPublicKey().votingKey), - new UInt64(builder.getStartPoint().finalizationPoint), - new UInt64(builder.getEndPoint().finalizationPoint), + builder.getStartEpoch().finalizationEpoch, + builder.getEndEpoch().finalizationEpoch, builder.getLinkAction().valueOf(), networkType, isEmbedded ? new UInt64([0, 0]) : new UInt64((builder as VotingKeyLinkTransactionBuilder).fee.amount), @@ -162,8 +162,8 @@ export class VotingKeyLinkTransaction extends Transaction { new AmountDto(this.maxFee.toDTO()), new TimestampDto(this.deadline.toDTO()), new VotingKeyDto(Convert.hexToUint8(this.linkedPublicKey)), - new FinalizationPointDto(this.startPoint.toDTO()), - new FinalizationPointDto(this.endPoint.toDTO()), + new FinalizationEpochDto(this.startEpoch), + new FinalizationEpochDto(this.endEpoch), this.linkAction.valueOf(), ); return transactionBuilder; @@ -180,8 +180,8 @@ export class VotingKeyLinkTransaction extends Transaction { this.networkType.valueOf(), TransactionType.VOTING_KEY_LINK.valueOf(), new VotingKeyDto(Convert.hexToUint8(this.linkedPublicKey)), - new FinalizationPointDto(this.startPoint.toDTO()), - new FinalizationPointDto(this.endPoint.toDTO()), + new FinalizationEpochDto(this.startEpoch), + new FinalizationEpochDto(this.endEpoch), this.linkAction.valueOf(), ); } diff --git a/src/service/MosaicRestrictionTransactionService.ts b/src/service/MosaicRestrictionTransactionService.ts index 00e32cd27b..36bc17d230 100644 --- a/src/service/MosaicRestrictionTransactionService.ts +++ b/src/service/MosaicRestrictionTransactionService.ts @@ -31,6 +31,8 @@ import { Transaction } from '../model/transaction/Transaction'; import { UInt64 } from '../model/UInt64'; import { UnresolvedAddress } from '../model/account/UnresolvedAddress'; import { UnresolvedMosaicId } from '../model/mosaic/UnresolvedMosaicId'; +import { MosaicAddressRestriction } from '../model/restriction/MosaicAddressRestriction'; +import { Page } from '../infrastructure/Page'; /** * MosaicRestrictionTransactionService service @@ -156,9 +158,9 @@ export class MosaicRestrictionTransactionService { * @return {Observable} */ private getAddressRestrictionEntry(mosaicId: MosaicId, restrictionKey: UInt64, targetAddress: Address): Observable { - return this.restrictionMosaicRepository.getMosaicAddressRestriction(mosaicId, targetAddress).pipe( + return this.restrictionMosaicRepository.searchMosaicRestrictions({ mosaicId, targetAddress }).pipe( map((mosaicRestriction) => { - return mosaicRestriction.restrictions.get(restrictionKey.toString()); + return (mosaicRestriction.data[0] as MosaicAddressRestriction).restrictions.get(restrictionKey.toString()); }), catchError((err: Error) => { const error = JSON.parse(err.message); @@ -177,9 +179,13 @@ export class MosaicRestrictionTransactionService { * @return {Observable} */ private getGlobalRestrictionEntry(mosaicId: MosaicId, restrictionKey: UInt64): Observable { - return this.restrictionMosaicRepository.getMosaicGlobalRestriction(mosaicId).pipe( - map((mosaicRestriction: MosaicGlobalRestriction) => { - return mosaicRestriction.restrictions.get(restrictionKey.toString()); + return this.restrictionMosaicRepository.searchMosaicRestrictions({ mosaicId }).pipe( + map((mosaicRestrictionPage: Page) => { + const globalRestriction = mosaicRestrictionPage.data.find((r) => r instanceof MosaicGlobalRestriction); + if (globalRestriction !== undefined) { + return globalRestriction.restrictions.get(restrictionKey.toString()); + } + throw new Error('No global restriction found for mosaic' + mosaicId.toHex()); }), catchError((err: Error) => { const error = JSON.parse(err.message); diff --git a/test/core/utils/TransactionMapping.spec.ts b/test/core/utils/TransactionMapping.spec.ts index 87553fe723..1a4152f669 100644 --- a/test/core/utils/TransactionMapping.spec.ts +++ b/test/core/utils/TransactionMapping.spec.ts @@ -418,8 +418,8 @@ describe('TransactionMapping - createFromPayload', () => { const votingKeyLinkTransaction = VotingKeyLinkTransaction.create( Deadline.create(), Convert.uint8ToHex(Crypto.randomBytes(48)), - UInt64.fromUint(1), - UInt64.fromUint(3), + 1, + 3, LinkAction.Link, NetworkType.MIJIN_TEST, ); @@ -616,8 +616,8 @@ describe('TransactionMapping - createFromPayload', () => { const votingKeyLinkTransaction = VotingKeyLinkTransaction.create( Deadline.create(), key, - UInt64.fromUint(1), - UInt64.fromUint(3), + 1, + 3, LinkAction.Link, NetworkType.MIJIN_TEST, ); @@ -626,8 +626,8 @@ describe('TransactionMapping - createFromPayload', () => { const transaction = TransactionMapping.createFromPayload(signedTransaction.payload) as VotingKeyLinkTransaction; expect(transaction.linkAction).to.be.equal(1); - expect(transaction.startPoint.toString()).to.be.equal('1'); - expect(transaction.endPoint.toString()).to.be.equal('3'); + expect(transaction.startEpoch.toString()).to.be.equal('1'); + expect(transaction.endEpoch.toString()).to.be.equal('3'); expect(transaction.linkedPublicKey).to.be.equal(key); }); @@ -920,8 +920,8 @@ describe('TransactionMapping - createFromDTO (Transaction.toJSON() feed)', () => const votingKeyLinkTransaction = VotingKeyLinkTransaction.create( Deadline.create(), key, - UInt64.fromUint(1), - UInt64.fromUint(3), + 1, + 3, LinkAction.Link, NetworkType.MIJIN_TEST, ); @@ -929,8 +929,8 @@ describe('TransactionMapping - createFromDTO (Transaction.toJSON() feed)', () => const transaction = TransactionMapping.createFromDTO(votingKeyLinkTransaction.toJSON()) as VotingKeyLinkTransaction; expect(transaction.linkedPublicKey).to.be.equal(key); - expect(transaction.startPoint.toString()).to.be.equal('1'); - expect(transaction.endPoint.toString()).to.be.equal('3'); + expect(transaction.startEpoch.toString()).to.be.equal('1'); + expect(transaction.endEpoch.toString()).to.be.equal('3'); expect(transaction.linkAction).to.be.equal(LinkAction.Link); }); it('should create AccountRestrictionAddressTransaction', () => { diff --git a/test/core/utils/TransactionMappingWithSignatures.spec.ts b/test/core/utils/TransactionMappingWithSignatures.spec.ts index b17c3396e2..936e5382fc 100644 --- a/test/core/utils/TransactionMappingWithSignatures.spec.ts +++ b/test/core/utils/TransactionMappingWithSignatures.spec.ts @@ -499,8 +499,8 @@ describe('TransactionMapping - createFromPayload with optional sigature and sign const votingKeyLinkTransaction = VotingKeyLinkTransaction.create( Deadline.create(), Convert.uint8ToHex(Crypto.randomBytes(48)), - UInt64.fromUint(1), - UInt64.fromUint(3), + 1, + 3, LinkAction.Link, NetworkType.MIJIN_TEST, ); @@ -769,8 +769,8 @@ describe('TransactionMapping - createFromPayload with optional sigature and sign const votingKeyLinkTransaction = VotingKeyLinkTransaction.create( Deadline.create(), key, - UInt64.fromUint(1), - UInt64.fromUint(3), + 1, + 3, LinkAction.Link, NetworkType.MIJIN_TEST, undefined, @@ -783,8 +783,8 @@ describe('TransactionMapping - createFromPayload with optional sigature and sign expect(transaction.linkAction).to.be.equal(1); expect(transaction.linkedPublicKey).to.be.equal(key); - expect(transaction.startPoint.toString()).to.be.equal('1'); - expect(transaction.endPoint.toString()).to.be.equal('3'); + expect(transaction.startEpoch.toString()).to.be.equal('1'); + expect(transaction.endEpoch.toString()).to.be.equal('3'); expect(transaction.signature).to.be.equal(testSignature); expect(transaction.signer?.publicKey).to.be.equal(account.publicKey); diff --git a/test/infrastructure/AccountHttp.spec.ts b/test/infrastructure/AccountHttp.spec.ts index 1f4c7d927a..8012d56884 100644 --- a/test/infrastructure/AccountHttp.spec.ts +++ b/test/infrastructure/AccountHttp.spec.ts @@ -58,7 +58,7 @@ describe('AccountHttp', () => { accountDTO.importanceHeight = '333'; accountDTO.publicKeyHeight = '444'; const accountKeyDto: AccountLinkPublicKeyDTO = { publicKey: 'abc' }; - const accountVotingKeyDto: AccountLinkVotingKeyDTO = { publicKey: 'abc', startPoint: '1', endPoint: '3' }; + const accountVotingKeyDto: AccountLinkVotingKeyDTO = { publicKey: 'abc', startEpoch: 1, endEpoch: 3 }; accountDTO.supplementalPublicKeys = { linked: accountKeyDto, node: accountKeyDto, @@ -98,8 +98,8 @@ describe('AccountHttp', () => { expect(accountInfo.supplementalPublicKeys.vrf?.publicKey).to.be.equals('abc'); expect(accountInfo.supplementalPublicKeys.voting?.length).to.be.equals(1); expect(accountInfo.supplementalPublicKeys.voting![0].publicKey).to.be.equals('abc'); - expect(accountInfo.supplementalPublicKeys.voting![0].endPoint.toString()).to.be.equals('3'); - expect(accountInfo.supplementalPublicKeys.voting![0].startPoint.toString()).to.be.equals('1'); + expect(accountInfo.supplementalPublicKeys.voting![0].endEpoch.toString()).to.be.equals('3'); + expect(accountInfo.supplementalPublicKeys.voting![0].startEpoch.toString()).to.be.equals('1'); expect(accountInfo.mosaics.length).to.be.equals(1); expect(accountInfo.mosaics[0].id.id.toHex()).to.be.equals(mosaic.id); expect(accountInfo.mosaics[0].amount.toString()).to.be.equals(mosaic.amount); diff --git a/test/infrastructure/RestrictionAccountHttp.spec.ts b/test/infrastructure/RestrictionAccountHttp.spec.ts index 06b9345cb6..df64a3d217 100644 --- a/test/infrastructure/RestrictionAccountHttp.spec.ts +++ b/test/infrastructure/RestrictionAccountHttp.spec.ts @@ -68,19 +68,6 @@ describe('RestrictionAccountHttp', () => { expect((restrictions[0].values[0] as Address).plain()).to.be.equals(address.plain()); }); - it('getAccountRestrictionsFromAccounts', async () => { - when(restrictionAccountRoutesApi.getAccountRestrictionsFromAccounts(deepEqual({ addresses: [address.plain()] }))).thenReturn( - Promise.resolve([restrictionInfo]), - ); - - const restrictions = await restrictionAccountRepository.getAccountRestrictionsFromAccounts([address]).toPromise(); - expect(restrictions).to.be.not.null; - expect(restrictions.length).to.be.greaterThan(0); - expect(restrictions[0].address.plain()).to.be.equals(address.plain()); - expect(restrictions[0].restrictions[0].restrictionFlags).to.be.equals(AddressRestrictionFlag.AllowIncomingAddress); - expect((restrictions[0].restrictions[0].values[0] as Address).plain()).to.be.equals(address.plain()); - }); - it('getAccountRestrictions - Error', async () => { when(restrictionAccountRoutesApi.getAccountRestrictions(deepEqual(address.plain()))).thenReject(new Error('Mocked Error')); await restrictionAccountRepository @@ -88,14 +75,4 @@ describe('RestrictionAccountHttp', () => { .toPromise() .catch((error) => expect(error).not.to.be.undefined); }); - - it('getAccountsRestrictions - Error', async () => { - when(restrictionAccountRoutesApi.getAccountRestrictionsFromAccounts(deepEqual({ addresses: [address.plain()] }))).thenReject( - new Error('Mocked Error'), - ); - await restrictionAccountRepository - .getAccountRestrictions(address) - .toPromise() - .catch((error) => expect(error).not.to.be.undefined); - }); }); diff --git a/test/infrastructure/RestrictionMosaicHttp.spec.ts b/test/infrastructure/RestrictionMosaicHttp.spec.ts index 09f4d217dc..96fef83df1 100644 --- a/test/infrastructure/RestrictionMosaicHttp.spec.ts +++ b/test/infrastructure/RestrictionMosaicHttp.spec.ts @@ -26,13 +26,16 @@ import { MosaicRestrictionEntryTypeEnum, MosaicRestrictionTypeEnum, RestrictionMosaicRoutesApi, + MosaicRestrictionsPage, + Pagination, } from 'symbol-openapi-typescript-fetch-client'; -import { deepEqual, instance, mock, reset, when } from 'ts-mockito'; +import { instance, mock, reset, when } from 'ts-mockito'; import { DtoMapping } from '../../src/core/utils/DtoMapping'; import { RestrictionMosaicHttp } from '../../src/infrastructure/RestrictionMosaicHttp'; import { PublicAccount } from '../../src/model/account/PublicAccount'; import { MosaicId } from '../../src/model/mosaic/MosaicId'; import { NetworkType } from '../../src/model/network/NetworkType'; +import { MosaicAddressRestriction } from '../../src/model/restriction/MosaicAddressRestriction'; describe('RestrictionMosaicHttp', () => { const publicAccount = PublicAccount.createFromPublicKey( @@ -80,99 +83,61 @@ describe('RestrictionMosaicHttp', () => { mosaicGlobalRestrictionDto.mosaicRestrictionEntry = mosaicGlobalRestrictionEntryWrapperDto; + const pagination = {} as Pagination; + pagination.pageNumber = 1; + pagination.pageSize = 1; + + const body = {} as MosaicRestrictionsPage; + body.data = [mosaicGlobalRestrictionDto, mosaicAddressRestrictionDto]; + body.pagination = pagination; + before(() => { reset(response); reset(restrictionMosaicRoutesApi); }); - it('getMosaicAddressRestriction', async () => { - when(restrictionMosaicRoutesApi.getMosaicAddressRestriction(mosaicId.toHex(), address.plain())).thenReturn( - Promise.resolve(mosaicAddressRestrictionDto), - ); - - const restrictions = await restrictionMosaicRepository.getMosaicAddressRestriction(mosaicId, address).toPromise(); - expect(restrictions).to.be.not.null; - expect(restrictions.compositeHash).to.be.equal('hash'); - expect(restrictions.entryType.valueOf()).to.be.equal(0); - expect(restrictions.mosaicId.toHex()).to.be.equal(mosaicId.toHex()); - expect(restrictions.targetAddress.plain()).to.be.equal(address.plain()); - expect(restrictions.restrictions.get('key')).not.to.be.undefined; - }); - - it('getMosaicAddressRestrictions', async () => { + it('search', async () => { when( - restrictionMosaicRoutesApi.getMosaicAddressRestrictions(mosaicId.toHex(), deepEqual({ addresses: [address.plain()] })), - ).thenReturn(Promise.resolve([mosaicAddressRestrictionDto])); - - const restrictions = await restrictionMosaicRepository.getMosaicAddressRestrictions(mosaicId, [address]).toPromise(); - expect(restrictions).to.be.not.null; - expect(restrictions[0].compositeHash).to.be.equal('hash'); - expect(restrictions[0].entryType.valueOf()).to.be.equal(0); - expect(restrictions[0].mosaicId.toHex()).to.be.equal(mosaicId.toHex()); - expect(restrictions[0].targetAddress.plain()).to.be.equal(address.plain()); - expect(restrictions[0].restrictions.get('key')).not.to.be.undefined; - }); - - it('getMosaicGlobalRestriction', async () => { - when(restrictionMosaicRoutesApi.getMosaicGlobalRestriction(mosaicId.toHex())).thenReturn( - Promise.resolve(mosaicGlobalRestrictionDto), - ); - - const restrictions = await restrictionMosaicRepository.getMosaicGlobalRestriction(mosaicId).toPromise(); - expect(restrictions).to.be.not.null; - expect(restrictions.compositeHash).to.be.equal('hash'); - expect(restrictions.entryType.valueOf()).to.be.equal(0); - expect(restrictions.mosaicId.toHex()).to.be.equal(mosaicId.toHex()); - expect(restrictions.restrictions.get('key')).not.to.be.undefined; + restrictionMosaicRoutesApi.searchMosaicRestriction( + mosaicId.toHex(), + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ), + ).thenReturn(Promise.resolve(body)); + + const page = await restrictionMosaicRepository.searchMosaicRestrictions({ mosaicId: mosaicId }).toPromise(); + expect(page).to.be.not.null; + expect(page.data.length).to.be.equal(2); + expect(page.data[1].compositeHash).to.be.equal('hash'); + expect(page.data[1].entryType.valueOf()).to.be.equal(0); + expect(page.data[1].mosaicId.toHex()).to.be.equal(mosaicId.toHex()); + expect((page.data[1] as MosaicAddressRestriction).targetAddress.plain()).to.be.equal(address.plain()); + expect(page.data[1].restrictions.get('key')).not.to.be.undefined; + expect(page.data[0]).to.be.not.null; + expect(page.data[0].compositeHash).to.be.equal('hash'); + expect(page.data[0].entryType.valueOf()).to.be.equal(0); + expect(page.data[0].mosaicId.toHex()).to.be.equal(mosaicId.toHex()); + expect(page.data[0].restrictions.get('key')).not.to.be.undefined; }); - it('getMosaicGlobalRestrictions', async () => { - when(restrictionMosaicRoutesApi.getMosaicGlobalRestrictions(deepEqual({ mosaicIds: [mosaicId.toHex()] }))).thenReturn( - Promise.resolve([mosaicGlobalRestrictionDto]), - ); - - const restrictions = await restrictionMosaicRepository.getMosaicGlobalRestrictions([mosaicId]).toPromise(); - expect(restrictions).to.be.not.null; - expect(restrictions[0].compositeHash).to.be.equal('hash'); - expect(restrictions[0].entryType.valueOf()).to.be.equal(0); - expect(restrictions[0].mosaicId.toHex()).to.be.equal(mosaicId.toHex()); - expect(restrictions[0].restrictions.get('key')).not.to.be.undefined; - }); - - it('getMosaicAddressRestriction - Error', async () => { - when(restrictionMosaicRoutesApi.getMosaicAddressRestriction(mosaicId.toHex(), address.plain())).thenReject( - new Error('Mocked Error'), - ); - await restrictionMosaicRepository - .getMosaicAddressRestriction(mosaicId, address) - .toPromise() - .catch((error) => expect(error).not.to.be.undefined); - }); - - it('getMosaicAddressRestrictions - Error', async () => { + it('search - Error', async () => { when( - restrictionMosaicRoutesApi.getMosaicAddressRestrictions(mosaicId.toHex(), deepEqual({ addresses: [address.plain()] })), + restrictionMosaicRoutesApi.searchMosaicRestriction( + mosaicId.toHex(), + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ), ).thenReject(new Error('Mocked Error')); await restrictionMosaicRepository - .getMosaicAddressRestrictions(mosaicId, [address]) - .toPromise() - .catch((error) => expect(error).not.to.be.undefined); - }); - - it('getMosaicGlobalRestriction - Error', async () => { - when(restrictionMosaicRoutesApi.getMosaicGlobalRestriction(mosaicId.toHex())).thenReject(new Error('Mocked Error')); - await restrictionMosaicRepository - .getMosaicGlobalRestriction(mosaicId) - .toPromise() - .catch((error) => expect(error).not.to.be.undefined); - }); - - it('getMosaicGlobalRestriction - Error', async () => { - when(restrictionMosaicRoutesApi.getMosaicGlobalRestrictions(deepEqual({ mosaicIds: [mosaicId.toHex()] }))).thenReject( - new Error('Mocked Error'), - ); - await restrictionMosaicRepository - .getMosaicGlobalRestrictions([mosaicId]) + .searchMosaicRestrictions({ mosaicId: mosaicId }) .toPromise() .catch((error) => expect(error).not.to.be.undefined); }); diff --git a/test/infrastructure/SerializeTransactionToJSON.spec.ts b/test/infrastructure/SerializeTransactionToJSON.spec.ts index 4fabf142ec..38de7f444c 100644 --- a/test/infrastructure/SerializeTransactionToJSON.spec.ts +++ b/test/infrastructure/SerializeTransactionToJSON.spec.ts @@ -403,8 +403,8 @@ describe('SerializeTransactionToJSON', () => { const votingKeyLinkTransaction = VotingKeyLinkTransaction.create( Deadline.create(), votingKey, - UInt64.fromUint(1), - UInt64.fromUint(3), + 1, + 3, LinkAction.Link, NetworkType.MIJIN_TEST, ); @@ -412,8 +412,8 @@ describe('SerializeTransactionToJSON', () => { const json = votingKeyLinkTransaction.toJSON(); expect(json.transaction.linkedPublicKey).to.be.equal(votingKey); - expect(json.transaction.startPoint).to.be.equal('1'); - expect(json.transaction.endPoint.toString()).to.be.equal('3'); + expect(json.transaction.startEpoch).to.be.equal('1'); + expect(json.transaction.endEpoch.toString()).to.be.equal('3'); expect(json.transaction.linkAction).to.be.equal(LinkAction.Link); }); }); diff --git a/test/infrastructure/streamer/MosaicRestrictionsPaginationStreamer.spec.ts b/test/infrastructure/streamer/MosaicRestrictionsPaginationStreamer.spec.ts new file mode 100644 index 0000000000..0f2049e050 --- /dev/null +++ b/test/infrastructure/streamer/MosaicRestrictionsPaginationStreamer.spec.ts @@ -0,0 +1,82 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { instance, mock } from 'ts-mockito'; +import { RestrictionMosaicPaginationStreamer } from '../../../src/infrastructure/paginationStreamer/RestrictionMosaicPaginationStreamer'; +import { PaginationStreamerTestHelper } from './PaginationStreamerTestHelper'; +import { RestrictionMosaicRepository } from '../../../src/infrastructure/RestrictionMosaicRepository'; + +describe('MosaicRestrictionPaginationStreamer - transaction', () => { + it('basicMultiPageTest', () => { + const mosaicRestrictionRepositoryMock: RestrictionMosaicRepository = mock(); + const streamer = RestrictionMosaicPaginationStreamer.MosaicRestrictions(instance(mosaicRestrictionRepositoryMock)); + const tester = new PaginationStreamerTestHelper( + streamer, + mock(), + { search: mosaicRestrictionRepositoryMock.searchMosaicRestrictions }, + {}, + ); + return tester.basicMultiPageTest(); + }); + + it('basicSinglePageTest', () => { + const mosaicRestrictionRepositoryMock: RestrictionMosaicRepository = mock(); + const streamer = RestrictionMosaicPaginationStreamer.MosaicRestrictions(instance(mosaicRestrictionRepositoryMock)); + const tester = new PaginationStreamerTestHelper( + streamer, + mock(), + { search: mosaicRestrictionRepositoryMock.searchMosaicRestrictions }, + {}, + ); + return tester.basicSinglePageTest(); + }); + + it('limitToTwoPages', () => { + const mosaicRestrictionRepositoryMock: RestrictionMosaicRepository = mock(); + const streamer = RestrictionMosaicPaginationStreamer.MosaicRestrictions(instance(mosaicRestrictionRepositoryMock)); + const tester = new PaginationStreamerTestHelper( + streamer, + mock(), + { search: mosaicRestrictionRepositoryMock.searchMosaicRestrictions }, + {}, + ); + return tester.limitToTwoPages(); + }); + + it('multipageWithLimit', () => { + const mosaicRestrictionRepositoryMock: RestrictionMosaicRepository = mock(); + const streamer = RestrictionMosaicPaginationStreamer.MosaicRestrictions(instance(mosaicRestrictionRepositoryMock)); + const tester = new PaginationStreamerTestHelper( + streamer, + mock(), + { search: mosaicRestrictionRepositoryMock.searchMosaicRestrictions }, + {}, + ); + return tester.multipageWithLimit(); + }); + + it('limitToThreePages', () => { + const mosaicRestrictionRepositoryMock: RestrictionMosaicRepository = mock(); + const streamer = RestrictionMosaicPaginationStreamer.MosaicRestrictions(instance(mosaicRestrictionRepositoryMock)); + const tester = new PaginationStreamerTestHelper( + streamer, + mock(), + { search: mosaicRestrictionRepositoryMock.searchMosaicRestrictions }, + {}, + ); + return tester.limitToThreePages(); + }); +}); diff --git a/test/model/account/AccountInfo.spec.ts b/test/model/account/AccountInfo.spec.ts index c1e4e15a41..2a3ad7c101 100644 --- a/test/model/account/AccountInfo.spec.ts +++ b/test/model/account/AccountInfo.spec.ts @@ -45,8 +45,8 @@ describe('AccountInfo', () => { publicKeys: [ { publicKey: '2E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F', - startPoint: '1', - endpoint: '3', + startEpoch: 1, + endEpoch: 3, }, ], }, @@ -88,12 +88,7 @@ describe('AccountInfo', () => { : undefined, accountInfoDTO.account.supplementalPublicKeys.voting ? accountInfoDTO.account.supplementalPublicKeys.voting?.publicKeys.map( - (v) => - new AccountLinkVotingKey( - v.publicKey, - UInt64.fromNumericString(v.startPoint), - UInt64.fromNumericString(v.startPoint), - ), + (v) => new AccountLinkVotingKey(v.publicKey, v.startEpoch, v.endEpoch), ) : undefined, ), diff --git a/test/model/account/AccountKey.spec.ts b/test/model/account/AccountKey.spec.ts index b32c598519..d2ad9290ed 100644 --- a/test/model/account/AccountKey.spec.ts +++ b/test/model/account/AccountKey.spec.ts @@ -17,7 +17,6 @@ import { expect } from 'chai'; import { AccountLinkPublicKey } from '../../../src/model/account/AccountLinkPublicKey'; import { AccountLinkVotingKey } from '../../../src/model/account/AccountLinkVotingKey'; -import { UInt64 } from '../../../src/model/UInt64'; import { SupplementalPublicKeys } from '../../../src/model/account/SupplementalPublicKeys'; describe('AccountLinkPublicKey', () => { @@ -29,10 +28,10 @@ describe('AccountLinkPublicKey', () => { describe('AccountLinkVotingKey', () => { it('should createComplete an AccountLinkVotingKey object', () => { - const accountKey = new AccountLinkVotingKey('abc', UInt64.fromUint(1), UInt64.fromUint(3)); + const accountKey = new AccountLinkVotingKey('abc', 1, 3); expect(accountKey.publicKey).to.be.equal('abc'); - expect(accountKey.startPoint.toString()).to.be.equal('1'); - expect(accountKey.endPoint.toString()).to.be.equal('3'); + expect(accountKey.startEpoch.toString()).to.be.equal('1'); + expect(accountKey.endEpoch.toString()).to.be.equal('3'); }); }); @@ -62,13 +61,11 @@ describe('SupplementalPublicKeys', () => { expect(accountKey.vrf?.publicKey).to.be.eq('abc'); expect(accountKey.linked).to.be.undefined; - accountKey = new SupplementalPublicKeys(undefined, undefined, undefined, [ - new AccountLinkVotingKey('abc', UInt64.fromUint(1), UInt64.fromUint(3)), - ]); + accountKey = new SupplementalPublicKeys(undefined, undefined, undefined, [new AccountLinkVotingKey('abc', 1, 3)]); expect(accountKey.voting).not.to.be.undefined; expect(accountKey.voting![0].publicKey).to.be.eq('abc'); - expect(accountKey.voting![0].startPoint.toString()).to.be.eq('1'); - expect(accountKey.voting![0].endPoint.toString()).to.be.eq('3'); + expect(accountKey.voting![0].startEpoch.toString()).to.be.eq('1'); + expect(accountKey.voting![0].endEpoch.toString()).to.be.eq('3'); expect(accountKey.node).to.be.undefined; expect(accountKey.vrf).to.be.undefined; expect(accountKey.linked).to.be.undefined; diff --git a/test/model/transaction/VotingKeyLinkTransaction.spec.ts b/test/model/transaction/VotingKeyLinkTransaction.spec.ts index 04f77385f7..f3c12381ee 100644 --- a/test/model/transaction/VotingKeyLinkTransaction.spec.ts +++ b/test/model/transaction/VotingKeyLinkTransaction.spec.ts @@ -28,8 +28,8 @@ import { Address } from '../../../src/model/account/Address'; describe('VotingKeyLinkTransaction', () => { let account: Account; let votingKey: string; - const startPoint = UInt64.fromUint(1); - const endPoint = UInt64.fromUint(10); + const startEpoch = 1; + const endEpoch = 10; const generationHash = '57F7DA205008026C776CB6AED843393F04CD458E0AA2D9F1D5F31A402072B2D6'; before(() => { account = TestingAccount; @@ -40,24 +40,24 @@ describe('VotingKeyLinkTransaction', () => { const votingKeyLinkTransaction = VotingKeyLinkTransaction.create( Deadline.create(), votingKey, - startPoint, - endPoint, + startEpoch, + endEpoch, LinkAction.Link, NetworkType.MIJIN_TEST, ); expect(votingKeyLinkTransaction.maxFee.higher).to.be.equal(0); expect(votingKeyLinkTransaction.maxFee.lower).to.be.equal(0); - expect(votingKeyLinkTransaction.startPoint.toString()).to.be.equal('1'); - expect(votingKeyLinkTransaction.endPoint.toString()).to.be.equal('10'); + expect(votingKeyLinkTransaction.startEpoch.toString()).to.be.equal('1'); + expect(votingKeyLinkTransaction.endEpoch.toString()).to.be.equal('10'); }); it('should filled maxFee override transaction maxFee', () => { const votingKeyLinkTransaction = VotingKeyLinkTransaction.create( Deadline.create(), votingKey, - startPoint, - endPoint, + startEpoch, + endEpoch, LinkAction.Link, NetworkType.MIJIN_TEST, new UInt64([1, 0]), @@ -65,29 +65,29 @@ describe('VotingKeyLinkTransaction', () => { expect(votingKeyLinkTransaction.maxFee.higher).to.be.equal(0); expect(votingKeyLinkTransaction.maxFee.lower).to.be.equal(1); - expect(votingKeyLinkTransaction.startPoint.toString()).to.be.equal('1'); - expect(votingKeyLinkTransaction.endPoint.toString()).to.be.equal('10'); + expect(votingKeyLinkTransaction.startEpoch.toString()).to.be.equal('1'); + expect(votingKeyLinkTransaction.endEpoch.toString()).to.be.equal('10'); }); it('should create an votingKeyLinkTransaction object with link action', () => { const votingKeyLinkTransaction = VotingKeyLinkTransaction.create( Deadline.create(), votingKey, - startPoint, - endPoint, + startEpoch, + endEpoch, LinkAction.Link, NetworkType.MIJIN_TEST, ); expect(votingKeyLinkTransaction.linkAction).to.be.equal(1); expect(votingKeyLinkTransaction.linkedPublicKey).to.be.equal(votingKey); - expect(votingKeyLinkTransaction.startPoint.toString()).to.be.equal('1'); - expect(votingKeyLinkTransaction.endPoint.toString()).to.be.equal('10'); + expect(votingKeyLinkTransaction.startEpoch.toString()).to.be.equal('1'); + expect(votingKeyLinkTransaction.endEpoch.toString()).to.be.equal('10'); const signedTransaction = votingKeyLinkTransaction.signWith(account, generationHash); expect(signedTransaction.payload.substring(256, signedTransaction.payload.length)).to.be.equal( - '344B9146A1F8DBBD8AFC830A2AAB7A83692E73AD775159B811355B1D2C0C27120243B10A16D4B5001B2AF0ED456C82D001000000000000000A0000000000000001', + '344B9146A1F8DBBD8AFC830A2AAB7A83692E73AD775159B811355B1D2C0C27120243B10A16D4B5001B2AF0ED456C82D0010000000A00000001', ); }); @@ -95,36 +95,36 @@ describe('VotingKeyLinkTransaction', () => { const votingKeyLinkTransaction = VotingKeyLinkTransaction.create( Deadline.create(), votingKey, - startPoint, - endPoint, + startEpoch, + endEpoch, LinkAction.Unlink, NetworkType.MIJIN_TEST, ); expect(votingKeyLinkTransaction.linkAction).to.be.equal(0); expect(votingKeyLinkTransaction.linkedPublicKey).to.be.equal(votingKey); - expect(votingKeyLinkTransaction.startPoint.toString()).to.be.equal('1'); - expect(votingKeyLinkTransaction.endPoint.toString()).to.be.equal('10'); + expect(votingKeyLinkTransaction.startEpoch.toString()).to.be.equal('1'); + expect(votingKeyLinkTransaction.endEpoch.toString()).to.be.equal('10'); const signedTransaction = votingKeyLinkTransaction.signWith(account, generationHash); expect(signedTransaction.payload.substring(256, signedTransaction.payload.length)).to.be.equal( - '344B9146A1F8DBBD8AFC830A2AAB7A83692E73AD775159B811355B1D2C0C27120243B10A16D4B5001B2AF0ED456C82D001000000000000000A0000000000000000', + '344B9146A1F8DBBD8AFC830A2AAB7A83692E73AD775159B811355B1D2C0C27120243B10A16D4B5001B2AF0ED456C82D0010000000A00000000', ); }); describe('size', () => { - it('should return 161 for VotingKeyLinkTransaction byte size', () => { + it('should return 185 for VotingKeyLinkTransaction byte size', () => { const votingKeyLinkTransaction = VotingKeyLinkTransaction.create( Deadline.create(), votingKey, - startPoint, - endPoint, + startEpoch, + endEpoch, LinkAction.Unlink, NetworkType.MIJIN_TEST, ); expect(Convert.hexToUint8(votingKeyLinkTransaction.serialize()).length).to.be.equal(votingKeyLinkTransaction.size); - expect(votingKeyLinkTransaction.size).to.be.equal(193); + expect(votingKeyLinkTransaction.size).to.be.equal(185); }); }); @@ -132,12 +132,12 @@ describe('VotingKeyLinkTransaction', () => { const votingKeyLinkTransaction = VotingKeyLinkTransaction.create( Deadline.create(), votingKey, - startPoint, - endPoint, + startEpoch, + endEpoch, LinkAction.Unlink, NetworkType.MIJIN_TEST, ).setMaxFee(2); - expect(votingKeyLinkTransaction.maxFee.compact()).to.be.equal(386); + expect(votingKeyLinkTransaction.maxFee.compact()).to.be.equal(370); const signedTransaction = votingKeyLinkTransaction.signWith(account, generationHash); expect(signedTransaction.hash).not.to.be.undefined; @@ -147,8 +147,8 @@ describe('VotingKeyLinkTransaction', () => { const tx = VotingKeyLinkTransaction.create( Deadline.create(), account.publicKey, - startPoint, - endPoint, + startEpoch, + endEpoch, LinkAction.Unlink, NetworkType.MIJIN_TEST, ); diff --git a/test/service/MosaicRestrictionTransactionservice.spec.ts b/test/service/MosaicRestrictionTransactionservice.spec.ts index 8c4b4bf04d..7515bfe7a6 100644 --- a/test/service/MosaicRestrictionTransactionservice.spec.ts +++ b/test/service/MosaicRestrictionTransactionservice.spec.ts @@ -36,6 +36,7 @@ import { TransactionType } from '../../src/model/transaction/TransactionType'; import { UInt64 } from '../../src/model/UInt64'; import { MosaicRestrictionTransactionService } from '../../src/service/MosaicRestrictionTransactionService'; import { TestingAccount } from '../conf/conf.spec'; +import { Page } from '../../src/infrastructure/Page'; describe('MosaicRestrictionTransactionService', () => { let account: Account; @@ -51,8 +52,8 @@ describe('MosaicRestrictionTransactionService', () => { const globalRestrictionType = MosaicRestrictionType.LE; const addressRestrictionValue = '10'; - function mockGlobalRestriction(): MosaicGlobalRestriction { - return new MosaicGlobalRestriction( + function mockGlobalRestriction(): Page { + const restriction = new MosaicGlobalRestriction( '59DFBA84B2E9E7000135E80C', MosaicRestrictionEntryType.GLOBAL, mosaicId, @@ -61,16 +62,19 @@ describe('MosaicRestrictionTransactionService', () => { new MosaicGlobalRestrictionItem(referenceMosaicId, globalRestrictionValue, globalRestrictionType), ), ); + + return new Page([restriction], 1, 1); } - function mockAddressRestriction(): MosaicAddressRestriction { - return new MosaicAddressRestriction( + function mockAddressRestriction(): Page { + const restriction = new MosaicAddressRestriction( '59DFBA84B2E9E7000135E80C', MosaicRestrictionEntryType.GLOBAL, mosaicId, account.address, new Map().set(key.toString(), addressRestrictionValue), ); + return new Page([restriction], 1, 1); } before(() => { @@ -83,9 +87,8 @@ describe('MosaicRestrictionTransactionService', () => { const mockRestrictionRepository = mock(); const mockNamespaceRepository = mock(); - when(mockRestrictionRepository.getMosaicGlobalRestriction(deepEqual(mosaicId))).thenReturn(observableOf(mockGlobalRestriction())); - when(mockRestrictionRepository.getMosaicGlobalRestriction(deepEqual(mosaicIdWrongKey))).thenThrow(new Error('Wrong mosaicId')); - when(mockRestrictionRepository.getMosaicAddressRestriction(deepEqual(mosaicId), deepEqual(account.address))).thenReturn( + when(mockRestrictionRepository.searchMosaicRestrictions(deepEqual({ mosaicId }))).thenReturn(observableOf(mockGlobalRestriction())); + when(mockRestrictionRepository.searchMosaicRestrictions(deepEqual({ mosaicId, targetAddress: account.address }))).thenReturn( observableOf(mockAddressRestriction()), ); when(mockNamespaceRepository.getLinkedMosaicId(deepEqual(unresolvedMosaicId))).thenReturn(observableOf(mosaicId));