Skip to content

Commit

Permalink
perf(ApostilleAccount): Improve ApostilleAccount code and methods
Browse files Browse the repository at this point in the history
Changed all any object into specific object, added getCreationInfo and getTransactionById methods,
and added new tests for ApostilleAccount class
  • Loading branch information
aizaiz committed Jul 17, 2018
1 parent 234d24b commit f0c42e6
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 41 deletions.
83 changes: 46 additions & 37 deletions src/ApostilleAccount.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { sortBy } from 'lodash';
import { AccountHttp, Address, BlockchainHttp, MultisigAccountInfo, NetworkType, PublicAccount, Transaction, TransactionHttp, TransactionInfo, TransactionType } from 'nem2-sdk';
import { AccountHttp, AccountInfo, Address, AggregateTransaction, BlockchainHttp, NetworkType, PublicAccount, Transaction, TransactionHttp, TransactionInfo, TransactionType, TransferTransaction } from 'nem2-sdk';
import { Observable } from 'rxjs';
import { Errors, HistoricalEndpoints, TransactionsStreams } from '../index';

Expand Down Expand Up @@ -35,7 +35,7 @@ export class ApostilleAccount {
* @returns {Promise<boolean>}
* @memberof ApostilleAccount
*/
public async isOwned() {
public async isOwned(): Promise<boolean> {
const cossignatories = await this.getCosignatories();
if (cossignatories.length > 0) {
return true;
Expand All @@ -54,9 +54,7 @@ export class ApostilleAccount {
const accountHttp = new AccountHttp(this.urls);
return new Promise(async (resolve, reject) => {
accountHttp.getMultisigAccountInfo(this.publicAccount.address).subscribe(
(accountInfo) => {
const multisigAccountInfo: MultisigAccountInfo = Object.assign(MultisigAccountInfo, accountInfo);

(multisigAccountInfo) => {
resolve(multisigAccountInfo.cosignatories);
},
(err) => reject(err),
Expand All @@ -82,71 +80,82 @@ export class ApostilleAccount {
* @memberof ApostilleAccount
*/
public async getCreationTransactionInfo(): Promise<TransactionInfo> {
const transaction: Transaction = await this.getCreationTransaction();
const transaction: TransferTransaction = await this.getCreationTransaction();
if (transaction.transactionInfo instanceof TransactionInfo) {
const transactionInfo: TransactionInfo = transaction.transactionInfo;
return transactionInfo;
return transaction.transactionInfo;
}
throw new Error(Errors[Errors.COULD_NOT_FOUND_TRANSACTION_INFO]);
}

/**
* @description - get first transaction
* @param {string} urls
* @returns {Promise<Transaction>}
* @returns {Promise<TransferTransaction>}
* @memberof ApostilleAccount
*/
public getCreationTransaction(): Promise<Transaction> {
public getCreationTransaction(): Promise<TransferTransaction> {
const accountHttp = new AccountHttp(this.urls);
return new Promise((resolve, reject) => {
accountHttp.getAccountInfo(this.publicAccount.address).subscribe(
(accountInfo) => {
(accountInfo: AccountInfo) => {
const blockchainHttp = new BlockchainHttp(this.urls);
const firstTransactionBlock = accountInfo.addressHeight.lower;
// find the first block of this account
blockchainHttp.getBlockTransactions(firstTransactionBlock).subscribe(
(block: any[]) => {
const filteredTransaction: any[] = [];
(block: Transaction[]) => {
// console.log(JSON.stringify(block));
const filteredTransaction: Transaction[] = [];
for (const transaction of block) {
if (transaction.type === TransactionType.TRANSFER) {
const address = Address.createFromRawAddress(transaction.recipient.address);
if (this.equals(address)) {
if (transaction instanceof TransferTransaction) {
const transferTransaction: TransferTransaction = transaction;
if (this.equals(transferTransaction.recipient)) {
filteredTransaction.push(transaction);
}
} else if (transaction.type === TransactionType.AGGREGATE_COMPLETE) {
for (const innerTransaction of transaction.innerTransactions) {
if (innerTransaction.type === TransactionType.TRANSFER) {
const address = Address.createFromRawAddress(
innerTransaction.recipient.address);
if (this.equals(address)) {
filteredTransaction.push(transaction);
} else if (transaction instanceof AggregateTransaction) {
if (transaction.type === TransactionType.AGGREGATE_COMPLETE) {
for (const innerTransaction of transaction.innerTransactions) {
if (innerTransaction instanceof TransferTransaction) {
if (this.equals(innerTransaction.recipient)) {
filteredTransaction.push(transaction);
}
break;
}
break;
}
}
}
}

// sort the block by index
const sortedTransaction = sortBy(filteredTransaction, ['transactionInfo.index']);
if (sortedTransaction[0].type === TransactionType.AGGREGATE_COMPLETE) {
// if the smallest index is aggregate transaction, then sort innertransaction by index
const sortedAggregateTransaction = sortBy(
sortedTransaction[0].innerTransactions, ['transactionInfo.index']);
resolve(Object.assign(
Transaction, sortedAggregateTransaction[0]));
const sortedTransaction: Transaction[] = sortBy(
filteredTransaction, ['transactionInfo.index']);
if (sortedTransaction.length > 0) {
const firstTransaction = sortedTransaction[0];
if (firstTransaction instanceof TransferTransaction) {
resolve (firstTransaction);
} else if (firstTransaction instanceof AggregateTransaction) {
// if the smallest index is aggregate transaction, then sort it by index
const innerTransactions = firstTransaction.innerTransactions;
const sortedInnerTransactions = sortBy(
innerTransactions, ['transactionInfo.index']);
const firstInnerTransaction = sortedInnerTransactions[0];
if (firstInnerTransaction instanceof TransferTransaction) {
resolve (firstInnerTransaction);
} else {
reject (Errors[Errors.CREATION_TRANSACTIONS_NOT_FOUND]);
}
} else {
reject (Errors[Errors.CREATION_TRANSACTIONS_NOT_FOUND]);
}
} else {
reject (Errors[Errors.CREATION_TRANSACTIONS_NOT_FOUND]);
}

resolve(Object.assign(Transaction, sortedTransaction[0]));
},
(err) => {
console.error(err.message);
reject(undefined);
reject(err);
});
},
(err) => {
console.error(err.message);
reject(undefined);
reject(err);
});
});
}
Expand Down
2 changes: 2 additions & 0 deletions src/Errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ export enum Errors {
NOT_PRIVATE_APOSTILLE,

NOT_APOSTILLE,

CREATION_TRANSACTIONS_NOT_FOUND,
}
56 changes: 52 additions & 4 deletions tests/unit/ApostilleAccount.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { NetworkType, PublicAccount } from 'nem2-sdk';
import { ApostilleAccount } from '../../index';
import { NetworkType, PublicAccount, TransactionInfo, TransferTransaction } from 'nem2-sdk';
import { ApostilleAccount, Errors } from '../../index';

describe('apostille accound methods should work properly', () => {
it('throws error if publicAccount parameter made from MIJIN and urls parameter is empty', () => {
const publicKey = 'E15CAB00A5A34216A8A29034F950A18DFC6F4F27BCCFBF9779DC6886653B7E56';

expect(() => new ApostilleAccount(PublicAccount.createFromPublicKey(publicKey, NetworkType.MIJIN)))
.toThrow(Errors[Errors.MIJIN_ENDPOINT_NEEDED]);
});

it(' should return 2 cosignataries of the accounts', () => {
const publicKey = 'E15CAB00A5A34216A8A29034F950A18DFC6F4F27BCCFBF9779DC6886653B7E56';
const apostilleAccount = new ApostilleAccount(PublicAccount.createFromPublicKey(publicKey, NetworkType.MIJIN_TEST));
Expand Down Expand Up @@ -29,12 +36,53 @@ describe('apostille accound methods should work properly', () => {
});
});

it('Should return creation transaction', () => {
it('Should return creation transaction when it is transfer transaction', () => {
const publicKey = '901C9D46840BB74F4649EF3AF65A910A9F162DFA0FD5AD7E2739E5B82C2579F0';
const apostilleAccount = new ApostilleAccount(PublicAccount.createFromPublicKey(publicKey, NetworkType.MIJIN_TEST));

return apostilleAccount.getCreationTransaction().then((data: TransferTransaction) => {
expect(data.message.payload).toEqual('');
});
});

it('Should return creation transaction when the it is an aggregate complete transaction', () => {
const publicKey = 'E15CAB00A5A34216A8A29034F950A18DFC6F4F27BCCFBF9779DC6886653B7E56';
const apostilleAccount = new ApostilleAccount(PublicAccount.createFromPublicKey(publicKey, NetworkType.MIJIN_TEST));

return apostilleAccount.getCreationTransaction().then((data: any) => {
return apostilleAccount.getCreationTransaction().then((data: TransferTransaction) => {
expect(data.message.payload).toEqual('I am really really awesomeee');
});
});

it('Throws error if there is no first transactions', () => {
const publicKey = '043E9D2BB4F38348F4ECA088CF0E76B3749389CFDE3E8D091889477F9F33F630';
const apostilleAccount = new ApostilleAccount(PublicAccount.createFromPublicKey(publicKey, NetworkType.MIJIN_TEST));

return apostilleAccount.getCreationTransaction().then((data: TransferTransaction) => {
console.log(TransferTransaction);
}).catch((err) => {
expect(err.message).toEqual('Not Found');
});
});

it('Should return creation transaction info', () => {
const publicKey = 'E15CAB00A5A34216A8A29034F950A18DFC6F4F27BCCFBF9779DC6886653B7E56';
const apostilleAccount = new ApostilleAccount(PublicAccount.createFromPublicKey(publicKey, NetworkType.MIJIN_TEST));

return apostilleAccount.getCreationTransactionInfo().then((transactionInfo: TransactionInfo) => {
expect(transactionInfo.id).toEqual('5B160E18C60E680001790BA2');
});
});

it('returns correct transaction by ID', () => {
const transactionID = '5B160E18C60E680001790BA2';
const publicKey = 'E15CAB00A5A34216A8A29034F950A18DFC6F4F27BCCFBF9779DC6886653B7E56';
const apostilleAccount = new ApostilleAccount(PublicAccount.createFromPublicKey(publicKey, NetworkType.MIJIN_TEST));

apostilleAccount.getTransactionById(transactionID)
.subscribe((transaction) => {
expect(transaction.transactionInfo.id).toEqual(transactionID);
});
});

});

0 comments on commit f0c42e6

Please sign in to comment.