From e8b53b31406f08915abd592cb171b3c1324342ed Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Tue, 30 May 2017 16:16:09 +0200 Subject: [PATCH 1/6] Move passphrase related code to a folder --- src/components/login/login.js | 1 - .../{login => passphrase}/passphrase.js | 25 +++++++++---------- .../{login => passphrase}/passphrase.less | 0 .../{login => passphrase}/passphrase.pug | 0 .../passphrase/passphraseService.js} | 0 .../savePassphrase.less} | 0 .../savePassphrase.pug} | 0 src/liskNano.js | 4 +-- 8 files changed, 14 insertions(+), 16 deletions(-) rename src/components/{login => passphrase}/passphrase.js (95%) rename src/components/{login => passphrase}/passphrase.less (100%) rename src/components/{login => passphrase}/passphrase.pug (100%) rename src/{services/passphrase.js => components/passphrase/passphraseService.js} (100%) rename src/components/{login/save.less => passphrase/savePassphrase.less} (100%) rename src/components/{login/save.pug => passphrase/savePassphrase.pug} (100%) diff --git a/src/components/login/login.js b/src/components/login/login.js index fcb99ac04..cea0090a0 100644 --- a/src/components/login/login.js +++ b/src/components/login/login.js @@ -1,5 +1,4 @@ import './login.less'; -import './save.less'; app.component('login', { template: require('./login.pug')(), diff --git a/src/components/login/passphrase.js b/src/components/passphrase/passphrase.js similarity index 95% rename from src/components/login/passphrase.js rename to src/components/passphrase/passphrase.js index 421524c8d..d3401e30d 100644 --- a/src/components/login/passphrase.js +++ b/src/components/passphrase/passphrase.js @@ -1,4 +1,5 @@ import './passphrase.less'; +import './savePassphrase.less'; app.directive('passphrase', ($rootScope, $document, Passphrase, $mdDialog, $mdMedia, $timeout) => { /* eslint no-param-reassign: ["error", { "props": false }] */ @@ -26,15 +27,6 @@ app.directive('passphrase', ($rootScope, $document, Passphrase, $mdDialog, $mdMe const generateAndDoubleCheck = (seed) => { const passphrase = Passphrase.generatePassPhrase(seed); - const ok = () => { - // this.input_passphrase = passphrase; - $timeout(() => { - $rootScope.$broadcast('onAfterSignup', { - passphrase, - target: attrs.target, - }); - }, 100); - }; $mdDialog.show({ controllerAs: '$ctrl', @@ -61,18 +53,25 @@ app.directive('passphrase', ($rootScope, $document, Passphrase, $mdDialog, $mdMe } ok() { - ok(); - this.close(); + this.$mdDialog.hide(); + this.$state.reload(); } close() { - this.$mdDialog.hide(); + this.$mdDialog.cancel(); this.$state.reload(); } }, - template: require('./save.pug')(), + template: require('./savePassphrase.pug')(), fullscreen: ($mdMedia('xs')), + }).then(() => { + $timeout(() => { + $rootScope.$broadcast('onAfterSignup', { + passphrase, + target: attrs.target, + }); + }, 100); }); }; diff --git a/src/components/login/passphrase.less b/src/components/passphrase/passphrase.less similarity index 100% rename from src/components/login/passphrase.less rename to src/components/passphrase/passphrase.less diff --git a/src/components/login/passphrase.pug b/src/components/passphrase/passphrase.pug similarity index 100% rename from src/components/login/passphrase.pug rename to src/components/passphrase/passphrase.pug diff --git a/src/services/passphrase.js b/src/components/passphrase/passphraseService.js similarity index 100% rename from src/services/passphrase.js rename to src/components/passphrase/passphraseService.js diff --git a/src/components/login/save.less b/src/components/passphrase/savePassphrase.less similarity index 100% rename from src/components/login/save.less rename to src/components/passphrase/savePassphrase.less diff --git a/src/components/login/save.pug b/src/components/passphrase/savePassphrase.pug similarity index 100% rename from src/components/login/save.pug rename to src/components/passphrase/savePassphrase.pug diff --git a/src/liskNano.js b/src/liskNano.js index 821a9a29c..adb5553a3 100644 --- a/src/liskNano.js +++ b/src/liskNano.js @@ -6,7 +6,8 @@ import './components/main/main'; import './components/main/setSecondPassService'; import './components/main/setSecondPassDirective'; import './components/login/login'; -import './components/login/passphrase'; +import './components/passphrase/passphrase'; +import './components/passphrase/passphraseService'; import './components/top/top'; import './components/header/header'; import './components/send/send'; @@ -25,7 +26,6 @@ import './components/delegateRegistration/delegateRegistration'; import './services/api/peers'; import './services/lsk'; import './services/dialog'; -import './services/passphrase'; import './services/signVerify'; import './services/account'; import './services/api/delegateApi'; From a7f5ee48590b5c7531327a2d3ab3035280d130d2 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Tue, 30 May 2017 16:38:54 +0200 Subject: [PATCH 2/6] Refactor save passphrase modal into a component #189 --- src/components/passphrase/passphrase.js | 40 +++------------- src/components/passphrase/savePassphrase.js | 40 ++++++++++++++++ src/components/passphrase/savePassphrase.less | 2 +- src/components/passphrase/savePassphrase.pug | 47 +++++++++---------- src/liskNano.js | 1 + 5 files changed, 71 insertions(+), 59 deletions(-) create mode 100644 src/components/passphrase/savePassphrase.js diff --git a/src/components/passphrase/passphrase.js b/src/components/passphrase/passphrase.js index d3401e30d..dc173d6b7 100644 --- a/src/components/passphrase/passphrase.js +++ b/src/components/passphrase/passphrase.js @@ -1,7 +1,6 @@ import './passphrase.less'; -import './savePassphrase.less'; -app.directive('passphrase', ($rootScope, $document, Passphrase, $mdDialog, $mdMedia, $timeout) => { +app.directive('passphrase', ($rootScope, $document, Passphrase, dialog, $mdMedia, $timeout) => { /* eslint no-param-reassign: ["error", { "props": false }] */ const PassphraseLink = function (scope, element, attrs) { const bindEvents = (listener) => { @@ -28,43 +27,16 @@ app.directive('passphrase', ($rootScope, $document, Passphrase, $mdDialog, $mdMe const passphrase = Passphrase.generatePassPhrase(seed); - $mdDialog.show({ + dialog.modal({ controllerAs: '$ctrl', controller: /* @ngInject*/ class save { - constructor($scope, $state) { - this.$mdDialog = $mdDialog; + // eslint-disable-next-line no-shadow + constructor(passphrase) { this.passphrase = passphrase; - this.$state = $state; - - $scope.$watch('$ctrl.missing_input', () => { - this.missing_ok = this.missing_input && this.missing_input === this.missing_word; - }); - } - - next() { - this.enter = true; - - const words = this.passphrase.split(' '); - const missingNumber = parseInt(Math.random() * words.length, 10); - - this.missing_word = words[missingNumber]; - this.pre = words.slice(0, missingNumber).join(' '); - this.pos = words.slice(missingNumber + 1).join(' '); - } - - ok() { - this.$mdDialog.hide(); - this.$state.reload(); - } - - close() { - this.$mdDialog.cancel(); - this.$state.reload(); } }, - - template: require('./savePassphrase.pug')(), - fullscreen: ($mdMedia('xs')), + template: '', + locals: { passphrase }, }).then(() => { $timeout(() => { $rootScope.$broadcast('onAfterSignup', { diff --git a/src/components/passphrase/savePassphrase.js b/src/components/passphrase/savePassphrase.js new file mode 100644 index 000000000..467986580 --- /dev/null +++ b/src/components/passphrase/savePassphrase.js @@ -0,0 +1,40 @@ +import './savePassphrase.less'; + +app.component('savePassphrase', { + template: require('./savePassphrase.pug')(), + bindings: { + passphrase: '<', + }, + controller: class savePassphrase { + constructor($scope, $state, $mdDialog) { + this.$mdDialog = $mdDialog; + this.$state = $state; + + $scope.$watch('$ctrl.missing_input', () => { + this.missing_ok = this.missing_input && this.missing_input === this.missing_word; + }); + } + + next() { + this.enter = true; + + const words = this.passphrase.split(' '); + const missingNumber = parseInt(Math.random() * words.length, 10); + + this.missing_word = words[missingNumber]; + this.pre = words.slice(0, missingNumber).join(' '); + this.pos = words.slice(missingNumber + 1).join(' '); + } + + ok() { + this.$mdDialog.hide(); + this.$state.reload(); + } + + close() { + this.$mdDialog.cancel(); + this.$state.reload(); + } + }, +}); + diff --git a/src/components/passphrase/savePassphrase.less b/src/components/passphrase/savePassphrase.less index 1febe73d9..dd06c3187 100644 --- a/src/components/passphrase/savePassphrase.less +++ b/src/components/passphrase/savePassphrase.less @@ -1,4 +1,4 @@ -.dialog-save { +save-passphrase { .missing { padding: 0 5px 0; font-weight: bold; diff --git a/src/components/passphrase/savePassphrase.pug b/src/components/passphrase/savePassphrase.pug index cbbb24181..6e1561f2c 100644 --- a/src/components/passphrase/savePassphrase.pug +++ b/src/components/passphrase/savePassphrase.pug @@ -1,24 +1,23 @@ -md-dialog.dialog-save(flex='80', aria-label='Save your passphrase in a safe place!') - form - md-toolbar - .md-toolbar-tools - h2 - span(ng-if="!$ctrl.enter") Save your passphrase in a safe place! - span(ng-if="$ctrl.enter") Enter the missing word to continue - md-dialog-content - .md-dialog-content - md-input-container.md-block(ng-if="!$ctrl.enter") - textarea.passphrase(ng-bind='$ctrl.passphrase', md-autofocus, readonly) - div(ng-if="$ctrl.enter") - p.passphrase - span {{ $ctrl.pre }} - span.missing ----- - span {{ $ctrl.pos }} - md-input-container.md-block(md-is-error='!$ctrl.missing_ok') - label Enter the missing word - input(ng-model='$ctrl.missing_input') - md-dialog-actions(layout='row') - md-button(ng-click="$ctrl.close()") Close - span(flex) - md-button.yes-its-save-button(ng-click="$ctrl.next()", ng-show='!$ctrl.enter') Yes! It's safe! - md-button.ok-button(ng-click="$ctrl.ok()", ng-show='$ctrl.enter', ng-disabled='!$ctrl.missing_ok') OK +form + md-toolbar + .md-toolbar-tools + h2 + span(ng-if="!$ctrl.enter") Save your passphrase in a safe place! + span(ng-if="$ctrl.enter") Enter the missing word to continue + md-dialog-content + .md-dialog-content + md-input-container.md-block(ng-if="!$ctrl.enter") + textarea.passphrase(ng-bind='$ctrl.passphrase', md-autofocus, readonly) + div(ng-if="$ctrl.enter") + p.passphrase + span {{ $ctrl.pre }} + span.missing ----- + span {{ $ctrl.pos }} + md-input-container.md-block(md-is-error='!$ctrl.missing_ok') + label Enter the missing word + input(ng-model='$ctrl.missing_input') + md-dialog-actions(layout='row') + md-button(ng-click="$ctrl.close()") Close + span(flex) + md-button.yes-its-save-button(ng-click="$ctrl.next()", ng-show='!$ctrl.enter') Yes! It's safe! + md-button.ok-button(ng-click="$ctrl.ok()", ng-show='$ctrl.enter', ng-disabled='!$ctrl.missing_ok') OK diff --git a/src/liskNano.js b/src/liskNano.js index adb5553a3..541885af4 100644 --- a/src/liskNano.js +++ b/src/liskNano.js @@ -7,6 +7,7 @@ import './components/main/setSecondPassService'; import './components/main/setSecondPassDirective'; import './components/login/login'; import './components/passphrase/passphrase'; +import './components/passphrase/savePassphrase'; import './components/passphrase/passphraseService'; import './components/top/top'; import './components/header/header'; From 752b8e850e846214b3b140025b29f27cfeef075b Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Tue, 30 May 2017 17:34:08 +0200 Subject: [PATCH 3/6] Create unit tests for savePassphrase component --- src/components/passphrase/savePassphrase.pug | 2 +- .../passphrase/savePassphrase.spec.js | 83 +++++++++++++++++++ test/test.js | 1 + 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 test/components/passphrase/savePassphrase.spec.js diff --git a/src/components/passphrase/savePassphrase.pug b/src/components/passphrase/savePassphrase.pug index 6e1561f2c..25e257c14 100644 --- a/src/components/passphrase/savePassphrase.pug +++ b/src/components/passphrase/savePassphrase.pug @@ -17,7 +17,7 @@ form label Enter the missing word input(ng-model='$ctrl.missing_input') md-dialog-actions(layout='row') - md-button(ng-click="$ctrl.close()") Close + md-button.close-button(ng-click="$ctrl.close()") Close span(flex) md-button.yes-its-save-button(ng-click="$ctrl.next()", ng-show='!$ctrl.enter') Yes! It's safe! md-button.ok-button(ng-click="$ctrl.ok()", ng-show='$ctrl.enter', ng-disabled='!$ctrl.missing_ok') OK diff --git a/test/components/passphrase/savePassphrase.spec.js b/test/components/passphrase/savePassphrase.spec.js new file mode 100644 index 000000000..0f0925c1b --- /dev/null +++ b/test/components/passphrase/savePassphrase.spec.js @@ -0,0 +1,83 @@ +const chai = require('chai'); +const sinon = require('sinon'); +const sinonChai = require('sinon-chai'); + +const expect = chai.expect; +chai.use(sinonChai); +const PASSPHRASE = 'illegal symbol search tree deposit youth mixture craft amazing tool soon unit'; + +describe('Save passphrase component', () => { + let $compile; + let $rootScope; + let element; + let $scope; + + beforeEach(angular.mock.module('app')); + + beforeEach(inject((_$compile_, _$rootScope_) => { + $compile = _$compile_; + $rootScope = _$rootScope_; + })); + + beforeEach(() => { + $scope = $rootScope.$new(); + $scope.passphrase = PASSPHRASE; + element = $compile('')($scope); + $rootScope.$digest(); + }); + + it('should contain an input field with the passphrase', () => { + expect(element.find('textarea').val()).to.equal(PASSPHRASE); + }); + + it('should ask for a missing word when "yes-its-save-button" clicked', () => { + element.find('.yes-its-save-button').click(); + expect(element.find('label').text()).to.equal('Enter the missing word'); + }); + + describe('Save passphrase component controller', () => { + let controller; + let $componentController; + let dialogMock; + let stateMock; + + beforeEach(inject((_$componentController_) => { + $componentController = _$componentController_; + })); + + beforeEach(() => { + $scope = $rootScope.$new(); + $scope.passphrase = PASSPHRASE; + controller = $componentController('savePassphrase', $scope, {}); + + dialogMock = sinon.mock(controller.$mdDialog); + stateMock = sinon.mock(controller.$state); + }); + + afterEach(() => { + dialogMock.verify(); + dialogMock.restore(); + stateMock.verify(); + stateMock.restore(); + }); + + describe('ok()', () => { + it('calls $mdDialog.hide and $state.reload', () => { + dialogMock.expects('hide'); + stateMock.expects('reload'); + + controller.ok(); + }); + }); + + describe('close()', () => { + it('calls $mdDialog.cancel and $state.reload', () => { + dialogMock.expects('cancel'); + stateMock.expects('reload'); + + controller.close(); + }); + }); + }); +}); + diff --git a/test/test.js b/test/test.js index da5d967d8..fe9da1e9e 100644 --- a/test/test.js +++ b/test/test.js @@ -4,6 +4,7 @@ require('./components/delegates/vote.spec'); require('./components/header/header.spec'); require('./components/login/login.spec'); require('./components/login/passphrase.spec'); +require('./components/passphrase/savePassphrase.spec'); require('./components/main/main.spec'); require('./components/main/setSecondPassDirective.spec'); require('./components/main/setSecondPassService.spec'); From 62fd705e5c8f05c14dd338e974a61c077d183c61 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Wed, 31 May 2017 09:00:13 +0200 Subject: [PATCH 4/6] Move passphrase unit test to match src --- test/components/{login => passphrase}/passphrase.spec.js | 0 test/test.js | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename test/components/{login => passphrase}/passphrase.spec.js (100%) diff --git a/test/components/login/passphrase.spec.js b/test/components/passphrase/passphrase.spec.js similarity index 100% rename from test/components/login/passphrase.spec.js rename to test/components/passphrase/passphrase.spec.js diff --git a/test/test.js b/test/test.js index fe9da1e9e..3d16ef705 100644 --- a/test/test.js +++ b/test/test.js @@ -3,7 +3,7 @@ require('./components/delegates/delegates.spec'); require('./components/delegates/vote.spec'); require('./components/header/header.spec'); require('./components/login/login.spec'); -require('./components/login/passphrase.spec'); +require('./components/passphrase/passphrase.spec'); require('./components/passphrase/savePassphrase.spec'); require('./components/main/main.spec'); require('./components/main/setSecondPassDirective.spec'); From 8e412fb74a835eeedbafb3d0611a2cee9a1d6953 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Wed, 31 May 2017 09:15:03 +0200 Subject: [PATCH 5/6] Sort imports alphabetically --- src/liskNano.js | 42 +++++++++++++++++++++--------------------- test/test.js | 26 +++++++++++++------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/liskNano.js b/src/liskNano.js index 541885af4..933f5f752 100644 --- a/src/liskNano.js +++ b/src/liskNano.js @@ -1,40 +1,40 @@ import './index.less'; -import './theme/theme'; -import './util/animateOnChange/animateOnChange'; +import './components/delegateRegistration/delegateRegistration'; +import './components/delegates/delegates'; +import './components/delegates/vote'; +import './components/forging/forging'; +import './components/header/header'; +import './components/login/login'; +import './components/lsk/lsk'; import './components/main/main'; -import './components/main/setSecondPassService'; import './components/main/setSecondPassDirective'; -import './components/login/login'; +import './components/main/setSecondPassService'; import './components/passphrase/passphrase'; -import './components/passphrase/savePassphrase'; import './components/passphrase/passphraseService'; -import './components/top/top'; -import './components/header/header'; +import './components/passphrase/savePassphrase'; import './components/send/send'; -import './components/send/sendModalService'; import './components/send/sendModalDirective'; -import './components/transactions/transactions'; -import './components/timestamp/timestamp'; -import './components/lsk/lsk'; -import './components/forging/forging'; -import './components/delegates/delegates'; -import './components/delegates/vote'; +import './components/send/sendModalService'; import './components/signVerify/signMessage'; import './components/signVerify/verifyMessage'; -import './components/delegateRegistration/delegateRegistration'; +import './components/timestamp/timestamp'; +import './components/top/top'; +import './components/transactions/transactions'; +import './theme/theme'; +import './util/animateOnChange/animateOnChange'; -import './services/api/peers'; -import './services/lsk'; -import './services/dialog'; -import './services/signVerify'; import './services/account'; +import './services/api/accountApi'; import './services/api/delegateApi'; import './services/api/forgingApi'; -import './services/api/accountApi'; +import './services/api/peers'; +import './services/dialog'; +import './services/lsk'; +import './services/signVerify'; import './services/sync'; import './filters/lsk'; -import './states'; import './run'; +import './states'; diff --git a/test/test.js b/test/test.js index 3d16ef705..d098badbe 100644 --- a/test/test.js +++ b/test/test.js @@ -1,30 +1,30 @@ -require('./components/forging/forging.spec'); +require('./components/delegateRegistration/delegateRegistration.spec.js'); require('./components/delegates/delegates.spec'); require('./components/delegates/vote.spec'); +require('./components/forging/forging.spec'); require('./components/header/header.spec'); require('./components/login/login.spec'); -require('./components/passphrase/passphrase.spec'); -require('./components/passphrase/savePassphrase.spec'); require('./components/main/main.spec'); require('./components/main/setSecondPassDirective.spec'); require('./components/main/setSecondPassService.spec'); +require('./components/passphrase/passphrase.spec'); +require('./components/passphrase/savePassphrase.spec'); require('./components/send/send.spec'); require('./components/send/sendModalDirective.spec'); -require('./components/top/top.spec'); -require('./components/timestamp/timestamp.spec'); -require('./components/transactions/transactions.spec'); require('./components/signVerify/signMessage.spec'); require('./components/signVerify/verifyMessage.spec'); -require('./components/delegateRegistration/delegateRegistration.spec.js'); +require('./components/timestamp/timestamp.spec'); +require('./components/top/top.spec'); +require('./components/transactions/transactions.spec'); -require('./services/passphrase.spec'); -require('./services/signVerify.spec'); -require('./services/lsk.spec'); -require('./services/api/peers.spec'); +require('./services/account.spec'); +require('./services/api/accountApi.spec'); require('./services/api/delegateApi.spec'); require('./services/api/forgingApi.spec'); -require('./services/api/accountApi.spec'); -require('./services/account.spec'); +require('./services/api/peers.spec'); +require('./services/lsk.spec'); +require('./services/passphrase.spec'); +require('./services/signVerify.spec'); require('./run.spec'); From 99f94449026030c196cf39d634f3599adee995f0 Mon Sep 17 00:00:00 2001 From: Vit Stanislav Date: Wed, 31 May 2017 09:49:30 +0200 Subject: [PATCH 6/6] Update e2e tests --- features/step_definitions/generic.step.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/features/step_definitions/generic.step.js b/features/step_definitions/generic.step.js index 75a9fe086..c2c6da51d 100644 --- a/features/step_definitions/generic.step.js +++ b/features/step_definitions/generic.step.js @@ -98,20 +98,20 @@ defineSupportCode(({ Given, When, Then, setDefaultTimeout }) => { }); When('I remember passphrase, click "{nextButtonSelector}", fill in missing word', (nextButtonSelector, callback) => { - waitForElemAndCheckItsText('.dialog-save h2', 'Save your passphrase in a safe place!'); + waitForElemAndCheckItsText('save-passphrase h2', 'Save your passphrase in a safe place!'); - element(by.css('.dialog-save textarea.passphrase')).getText().then((passphrase) => { + element(by.css('save-passphrase textarea.passphrase')).getText().then((passphrase) => { // eslint-disable-next-line no-unused-expressions expect(passphrase).to.not.be.undefined; const passphraseWords = passphrase.split(' '); expect(passphraseWords.length).to.equal(12); waitForElemAndClickIt(`.${nextButtonSelector.replace(/ /g, '-')}`); - element.all(by.css('.dialog-save p.passphrase span')).get(0).getText().then((firstPartOfPassphrase) => { + element.all(by.css('save-passphrase p.passphrase span')).get(0).getText().then((firstPartOfPassphrase) => { const missingWordIndex = firstPartOfPassphrase.length ? firstPartOfPassphrase.split(' ').length : 0; - element(by.css('.dialog-save input')).sendKeys(passphraseWords[missingWordIndex]).then(callback); + element(by.css('save-passphrase input')).sendKeys(passphraseWords[missingWordIndex]).then(callback); }); }); });