From 469f3e6b9917529e1d884a67dee7a63b9ac60b6b Mon Sep 17 00:00:00 2001 From: Valentine Wallace Date: Wed, 12 Sep 2018 22:48:22 -0700 Subject: [PATCH 1/4] Add notification parameter to TransactionAction. The purpose of adding this parameter is so we'll then be able to notify the user when they receive an invoice payment. --- src/action/index.js | 2 +- src/action/transaction.js | 3 ++- stories/screen-story.js | 2 +- test/integration/action/action-integration.spec.js | 4 ++-- test/unit/action/transaction.spec.js | 5 ++++- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/action/index.js b/src/action/index.js index 0bc6474ec..57894a8c5 100644 --- a/src/action/index.js +++ b/src/action/index.js @@ -36,7 +36,7 @@ export const grpc = new GrpcAction(store, ipc); export const notify = new NotificationAction(store, nav); export const wallet = new WalletAction(store, grpc, db, nav, notify); export const info = new InfoAction(store, grpc, nav, notify); -export const transaction = new TransactionAction(store, grpc, nav); +export const transaction = new TransactionAction(store, grpc, nav, notify); export const channel = new ChannelAction(store, grpc, nav, notify); export const invoice = new InvoiceAction(store, grpc, nav, notify, Clipboard); export const payment = new PaymentAction(store, grpc, nav, notify); diff --git a/src/action/transaction.js b/src/action/transaction.js index 703e8ca3d..bfe35d99e 100644 --- a/src/action/transaction.js +++ b/src/action/transaction.js @@ -7,10 +7,11 @@ import * as log from './log'; import { parseDate, parseSat, toHex } from '../helper'; class TransactionAction { - constructor(store, grpc, nav) { + constructor(store, grpc, nav, notification) { this._store = store; this._grpc = grpc; this._nav = nav; + this._notification = notification; } /** diff --git a/stories/screen-story.js b/stories/screen-story.js index 689b31a1b..db1ab112f 100644 --- a/stories/screen-story.js +++ b/stories/screen-story.js @@ -67,7 +67,7 @@ sinon.stub(wallet, 'checkSeed'); sinon.stub(wallet, 'checkNewPassword'); sinon.stub(wallet, 'checkPassword'); sinon.stub(wallet, 'getExchangeRate'); -const transaction = new TransactionAction(store, grpc, nav); +const transaction = new TransactionAction(store, grpc, nav, notify); sinon.stub(transaction, 'update'); const invoice = new InvoiceAction(store, grpc, nav, notify, Clipboard); sinon.stub(invoice, 'generateUri'); diff --git a/test/integration/action/action-integration.spec.js b/test/integration/action/action-integration.spec.js index b2347c06e..281594c77 100644 --- a/test/integration/action/action-integration.spec.js +++ b/test/integration/action/action-integration.spec.js @@ -149,7 +149,7 @@ describe('Action Integration Tests', function() { grpc1 = new GrpcAction(store1, ipc1); info1 = new InfoAction(store1, grpc1, nav1, notify1); wallet1 = new WalletAction(store1, grpc1, db1, nav1, notify1); - transactions1 = new TransactionAction(store1, grpc1, nav1); + transactions1 = new TransactionAction(store1, grpc1, nav1, notify1); channels1 = new ChannelAction(store1, grpc1, nav1, notify1); invoice1 = new InvoiceAction(store1, grpc1, nav1, notify1); payments1 = new PaymentAction(store1, grpc1, nav1, notify1); @@ -161,7 +161,7 @@ describe('Action Integration Tests', function() { grpc2 = new GrpcAction(store2, ipc2); info2 = new InfoAction(store2, grpc2, nav2, notify2); wallet2 = new WalletAction(store2, grpc2, db2, nav2, notify2); - transactions2 = new TransactionAction(store2, grpc2, nav2); + transactions2 = new TransactionAction(store2, grpc2, nav2, notify2); channels2 = new ChannelAction(store2, grpc2, nav2, notify2); invoice2 = new InvoiceAction(store2, grpc2, nav2, notify2); payments2 = new PaymentAction(store2, grpc2, nav2, notify2); diff --git a/test/unit/action/transaction.spec.js b/test/unit/action/transaction.spec.js index c71bef776..9d6892c89 100644 --- a/test/unit/action/transaction.spec.js +++ b/test/unit/action/transaction.spec.js @@ -2,6 +2,7 @@ import { Store } from '../../../src/store'; import GrpcAction from '../../../src/action/grpc'; import TransactionAction from '../../../src/action/transaction'; import NavAction from '../../../src/action/nav'; +import NotificationAction from '../../../src/action/notification'; import * as logger from '../../../src/action/log'; describe('Action Transactions Unit Tests', () => { @@ -9,6 +10,7 @@ describe('Action Transactions Unit Tests', () => { let sandbox; let grpc; let nav; + let notification; let transaction; beforeEach(() => { @@ -18,7 +20,8 @@ describe('Action Transactions Unit Tests', () => { require('../../../src/config').RETRY_DELAY = 1; grpc = sinon.createStubInstance(GrpcAction); nav = sinon.createStubInstance(NavAction); - transaction = new TransactionAction(store, grpc, nav); + notification = sinon.createStubInstance(NotificationAction); + transaction = new TransactionAction(store, grpc, nav, notification); }); afterEach(() => { From c34cd69a5dc7095c613ac2de0b01ba760744ebe3 Mon Sep 17 00:00:00 2001 From: Valentine Wallace Date: Wed, 12 Sep 2018 22:49:04 -0700 Subject: [PATCH 2/4] Notify the user if they receive an invoice that is settled. Tell them how much they've been paid, and give them the option of navigating to the details view for the invoice. --- src/action/transaction.js | 21 ++++++++++++++++++++- test/unit/action/transaction.spec.js | 25 +++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/action/transaction.js b/src/action/transaction.js index bfe35d99e..cffc4b5e7 100644 --- a/src/action/transaction.js +++ b/src/action/transaction.js @@ -134,12 +134,31 @@ class TransactionAction { async subscribeInvoices() { const stream = this._grpc.sendStreamCommand('subscribeInvoices'); await new Promise((resolve, reject) => { - stream.on('data', () => this.update()); + stream.on('data', invoice => this._receiveInvoice(invoice)); stream.on('end', resolve); stream.on('error', reject); stream.on('status', status => log.info(`Invoices update: ${status}`)); }); } + + // + // Helper functions + // + + async _receiveInvoice(invoice) { + await this.update(); + if (invoice.settled) { + const invoiceId = toHex(invoice.r_hash); + let inv = this._store.computedTransactions.find( + invoice => invoice.id === invoiceId + ); + this._notification.display({ + msg: `Invoice success: received ${inv.amountLabel}`, + handler: () => this.select({ item: inv }), + handlerLbl: 'View details', + }); + } + } } export default TransactionAction; diff --git a/test/unit/action/transaction.spec.js b/test/unit/action/transaction.spec.js index 9d6892c89..88f0e7b11 100644 --- a/test/unit/action/transaction.spec.js +++ b/test/unit/action/transaction.spec.js @@ -222,6 +222,31 @@ describe('Action Transactions Unit Tests', () => { expect(transaction.update, 'was called once'); }); + it('should notify the user on settled invoice', async () => { + store.computedTransactions = [{ id: 'cdab' }]; + onStub.withArgs('data').yields({ + settled: true, + r_hash: Buffer.from('cdab', 'hex'), + }); + onStub.withArgs('end').yields(); + grpc.sendStreamCommand + .withArgs('subscribeInvoices') + .returns({ on: onStub }); + await transaction.subscribeInvoices(); + expect(notification.display, 'was called once'); + }); + + it('should not notify the user on an unsettled invoice', async () => { + onStub.withArgs('data').yields({ settled: false }); + onStub.withArgs('end').yields(); + grpc.sendStreamCommand + .withArgs('subscribeInvoices') + .returns({ on: onStub }); + await transaction.subscribeInvoices(); + expect(transaction.update, 'was called once'); + expect(notification.display, 'was not called'); + }); + it('should reject in case of error', async () => { onStub.withArgs('error').yields(new Error('Boom!')); grpc.sendStreamCommand From 1db3732ef0537c889d0e2bc1f9dc3c43c0196daf Mon Sep 17 00:00:00 2001 From: Tankred Hase Date: Fri, 5 Oct 2018 14:16:46 +0200 Subject: [PATCH 3/4] Cleanup transaction notification and add unitLabel to amount --- src/action/transaction.js | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/action/transaction.js b/src/action/transaction.js index cffc4b5e7..f70ca3d8b 100644 --- a/src/action/transaction.js +++ b/src/action/transaction.js @@ -147,17 +147,15 @@ class TransactionAction { async _receiveInvoice(invoice) { await this.update(); - if (invoice.settled) { - const invoiceId = toHex(invoice.r_hash); - let inv = this._store.computedTransactions.find( - invoice => invoice.id === invoiceId - ); - this._notification.display({ - msg: `Invoice success: received ${inv.amountLabel}`, - handler: () => this.select({ item: inv }), - handlerLbl: 'View details', - }); - } + if (!invoice.settled) return; + const { computedTransactions, unitLabel } = this._store; + let inv = computedTransactions.find(tx => tx.id === toHex(invoice.r_hash)); + this._notification.display({ + type: 'success', + msg: `Invoice success: received ${inv.amountLabel} ${unitLabel}`, + handler: () => this.select({ item: inv }), + handlerLbl: 'View details', + }); } } From 4e09142b1795bcf578d4698889ac194ab781e080 Mon Sep 17 00:00:00 2001 From: Tankred Hase Date: Fri, 5 Oct 2018 14:17:02 +0200 Subject: [PATCH 4/4] Fix uncaught error in unit tests --- test/unit/action/transaction.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/action/transaction.spec.js b/test/unit/action/transaction.spec.js index 88f0e7b11..6821710fd 100644 --- a/test/unit/action/transaction.spec.js +++ b/test/unit/action/transaction.spec.js @@ -213,7 +213,7 @@ describe('Action Transactions Unit Tests', () => { }); it('should update invoices on data event', async () => { - onStub.withArgs('data').yields(); + onStub.withArgs('data').yields({}); onStub.withArgs('end').yields(); grpc.sendStreamCommand .withArgs('subscribeInvoices')