Skip to content
This repository has been archived by the owner on Apr 15, 2019. It is now read-only.

Commit

Permalink
Merge pull request #70 from LiskHQ/unit-tests
Browse files Browse the repository at this point in the history
Adding unit tests for login and timestamp components.
  • Loading branch information
karmacoma authored Mar 21, 2017
2 parents d0c8c38 + f632ec7 commit f8c3136
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 37 deletions.
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
language: node_js
node_js:
- 'node' # Latest stable Node.js release
cache:
directories:
- src/node_modules/
env:
- ON_TRAVIS=true
before_install: cd src
before_script:
- npm install -g grunt
- npm install -g grunt-cli
- npm install
script:
- npm run test
Expand Down
34 changes: 17 additions & 17 deletions src/app/components/login/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ app.component('login', {
this.$mdMedia = $mdMedia;
this.$cookies = $cookies;

this.$scope.$watch('$ctrl.input_passphrase', this.isValid.bind(this));
this.$scope.$watch('$ctrl.input_passphrase', this.isValidPassphrase.bind(this));
this.$timeout(this.devTestAccount.bind(this), 200);

this.$scope.$watch(() => this.$mdMedia('xs') || this.$mdMedia('sm'), (wantsFullScreen) => {
Expand All @@ -35,20 +35,20 @@ app.component('login', {
this.seed = login.emptyBytes().map(() => '00');
}

stop() {
this.random = false;
stopNewPassphraseGeneration() {
this.generatingNewPassphrase = false;
this.$document.unbind('mousemove', this.listener);
}

go() {
this.passphrase = login.fix(this.input_passphrase);
doTheLogin() {
this.passphrase = login.fixCaseAndWhitespace(this.input_passphrase);

this.reset();
this.$timeout(this.onLogin);
}

isValid(value) {
const fixedValue = login.fix(value);
isValidPassphrase(value) {
const fixedValue = login.fixCaseAndWhitespace(value);

if (fixedValue === '') {
this.valid = 2;
Expand All @@ -59,10 +59,10 @@ app.component('login', {
}
}

start() {
startGenratingNewPassphrase() {
this.reset();

this.random = true;
this.generatingNewPassphrase = true;

let last = [0, 0];
let used = login.emptyBytes();
Expand Down Expand Up @@ -108,8 +108,8 @@ app.component('login', {
}

if (count >= total) {
this.stop();
this.setNew();
this.stopNewPassphraseGeneration();
this.setNewPassphrase(this.seed);
return;
}
}
Expand All @@ -119,15 +119,15 @@ app.component('login', {
this.$timeout(() => this.$document.mousemove(this.listener), 300);
}

asd() {
simulateMousemove() {
this.$document.mousemove();
}

setNew() {
const passphrase = (new mnemonic(new Buffer(this.seed.join(''), 'hex'))).toString();
setNewPassphrase(seed) {
const passphrase = (new mnemonic(new Buffer(seed.join(''), 'hex'))).toString();
const ok = () => {
this.input_passphrase = passphrase;
this.$timeout(this.go.bind(this), 100);
this.$timeout(this.doTheLogin.bind(this), 100);
};

this.$mdDialog.show({
Expand Down Expand Up @@ -172,11 +172,11 @@ app.component('login', {
const passphrase = this.$cookies.get('passphrase');
if (passphrase) {
this.input_passphrase = passphrase;
this.$timeout(this.go.bind(this), 10);
this.$timeout(this.doTheLogin.bind(this), 10);
}
}

static fix(v) {
static fixCaseAndWhitespace(v) {
return (v || '').replace(/ +/g, ' ').trim().toLowerCase();
}

Expand Down
10 changes: 5 additions & 5 deletions src/app/components/login/login.pug
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ md-card
form(ng-submit='$ctrl.go()')
md-input-container.md-block(md-is-error='$ctrl.valid === 0')
label Enter your passphrase
input(type="{{ $ctrl.show_passphrase ? 'text' : 'password' }}", ng-model='$ctrl.input_passphrase', ng-disabled='$ctrl.random', autofocus)
input(type="{{ $ctrl.show_passphrase ? 'text' : 'password' }}", ng-model='$ctrl.input_passphrase', ng-disabled='$ctrl.generatingNewPassphrase', autofocus)
md-input-container.md-block
md-checkbox.md-primary(ng-model="$ctrl.show_passphrase", aria-label="Show passphrase") Show passphrase
md-content(layout='row', layout-align='center center')
// md-button(ng-disabled='$ctrl.random', ng-click='$ctrl.devTestAccount()') Dev Test Account
md-button.md-primary(ng-disabled='$ctrl.random', ng-click='$ctrl.start()') NEW ACCOUNT
// md-button(ng-disabled='$ctrl.generatingNewPassphrase', ng-click='$ctrl.devTestAccount()') Dev Test Account
md-button.md-primary(ng-disabled='$ctrl.random', ng-click='$ctrl.startGenratingNewPassphrase()') NEW ACCOUNT
md-button.md-raised.md-primary(md-autofocus, ng-disabled='$ctrl.valid !== 1', ng-click='$ctrl.go()') Login
md-content(layout-padding, layout='column', layout-align='center center', ng-show='$ctrl.random')
md-content(layout-padding, layout='column', layout-align='center center', ng-show='$ctrl.generatingNewPassphrase')
h4.move(ng-show='$ctrl.mobileAndTabletcheck()') Enter text below to generate random bytes
h4.move(ng-hide='$ctrl.mobileAndTabletcheck()') Move your mouse to generate random bytes
input.random-input(type="text", ng-keydown='$ctrl.asd()', ng-show='$ctrl.mobileAndTabletcheck()')
input.random-input(type="text", ng-keydown='$ctrl.simulateMousemove()', ng-show='$ctrl.mobileAndTabletcheck()')
md-progress-linear(md-mode='determinate', value='{{ $ctrl.progress }}')
md-content.bytes
span.byte(ng-repeat='byte in $ctrl.seed track by $index', ng-bind='byte', animate-on-change='byte')
5 changes: 3 additions & 2 deletions src/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ preprocessors[test] = ['webpack'];

var opts = {
onTravis: process.env.ON_TRAVIS,
live: process.env.LIVE,
};

module.exports = function(config) {
Expand Down Expand Up @@ -57,7 +58,7 @@ module.exports = function(config) {


// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
autoWatch: opts.live,

ngHtml2JsPreprocessor: {
stripPrefix: 'app/components/',
Expand All @@ -77,7 +78,7 @@ module.exports = function(config) {

// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: true,
singleRun: !opts.live,
client: {
mocha: {
opts: 'test/mocha.opts' // You can set opts to equal true then plugin will load opts from default location 'test/mocha.opts'
Expand Down
5 changes: 4 additions & 1 deletion src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"scripts": {
"build": "webpack --profile --progress --display-modules --display-exclude --display-chunks --display-cached --display-cached-assets",
"dev": "webpack-dev-server --host 0.0.0.0 --profile --progress",
"test": "export NODE_ENV=test && karma start"
"test": "export NODE_ENV=test && karma start",
"test-live": "export NODE_ENV=test && export LIVE=true && karma start"
},
"dependencies": {
"angular": "=1.5.8",
Expand Down Expand Up @@ -70,6 +71,8 @@
"pug-loader": "=2.3.0",
"raw-loader": "=0.5.1",
"should": "=11.2.0",
"sinon": "=2.0.0",
"sinon-chai": "=2.8.0",
"style-loader": "=0.13.1",
"url-loader": "=0.5.7",
"webpack": "=1.13.1",
Expand Down
105 changes: 100 additions & 5 deletions src/test/components/login/login.spec.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,118 @@
var sinon = require('sinon');
var sinonChai = require('sinon-chai');
var expect = chai.expect;
chai.use(sinonChai);

describe('Login component', function() {
var $compile,
$rootScope;
$rootScope,
element;

// Load the myApp module, which contains the directive
beforeEach(angular.mock.module("app"));

// Store references to $rootScope and $compile
// so they are available to all tests in this describe block
beforeEach(inject(function(_$compile_, _$rootScope_){
beforeEach(inject(function(_$compile_, _$rootScope_) {
// The injector unwraps the underscores (_) from around the parameter names when matching
$compile = _$compile_;
$rootScope = _$rootScope_;
}));

it('should contain header', function() {
beforeEach(function() {
// Compile a piece of HTML containing the directive
var element = $compile("<login></login>")($rootScope);
element = $compile('<login></login>')($rootScope);
$rootScope.$digest();
expect(element.html()).to.contain("Sign In");
});

var HEADER_TEXT = 'Sign In';
it('should contain header saying "' + HEADER_TEXT + '"', function() {
expect(element.find('.md-title').text()).to.equal(HEADER_TEXT);
});

var LABEL_TEXT = 'Enter your passphrase';
it('should contain a form with label saying "' + LABEL_TEXT + '"', function() {
expect(element.find('form label').text()).to.equal(LABEL_TEXT);
});

it('should contain an input field', function() {
expect(element.find('form input').html()).to.equal('');
});

var LOGIN_BUTTON_TEXT = 'Login';
it('should contain a button saying "' + LOGIN_BUTTON_TEXT + '"', function() {
expect(element.find('.md-raised').text()).to.equal(LOGIN_BUTTON_TEXT);
});
});

describe('Login controller', function() {
beforeEach(angular.mock.module('app'));

var $controller,
$rootScope;

beforeEach(inject(function(_$componentController_, _$rootScope_) {
$componentController = _$componentController_;
$rootScope = _$rootScope_;
}));

describe('$scope.reset()', function() {
var $scope,
controller;

beforeEach(function() {
$scope = $rootScope.$new();
controller = $componentController('login', $scope, {});
});

it('makes input_passphrase empty', function() {
passphrase = 'TEST';
controller.input_passphrase = passphrase;
expect(controller.input_passphrase).to.equal(passphrase);
controller.reset();
expect(controller.input_passphrase).to.equal('');
});
});

describe('$scope.setNewPassphrase()', function() {
var $scope,
controller;

beforeEach(function() {
$scope = $rootScope.$new();
controller = $componentController('login', $scope, {});
});

it('opens a material design dialog', function() {
var seed = ['23', '34', '34', '34', '34', '34', '34', '34'];
var dialogSpy = sinon.spy(controller.$mdDialog, 'show');
controller.setNewPassphrase(seed);
expect(dialogSpy).to.have.been.calledWith();
});
});

describe('$scope.isValidPassphrase(value)', function() {
var $scope,
controller;

beforeEach(function() {
$scope = $rootScope.$new();
controller = $componentController('login', $scope, {});
});

it('sets $scope.valid = 2 if value is empty', function() {
controller.isValidPassphrase('');
expect(controller.valid).to.equal(2);
});

it('sets $scope.valid = 1 if value is valid', function() {
controller.isValidPassphrase('ability theme abandon abandon abandon abandon abandon abandon abandon abandon abandon absorb');
expect(controller.valid).to.equal(1);
});

it('sets $scope.valid = 0 if value is invalid', function() {
controller.isValidPassphrase('INVALID VALUE');
expect(controller.valid).to.equal(0);
});
});
});
28 changes: 28 additions & 0 deletions src/test/components/timestamp/timestamp.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
describe('timestamp component', function() {
var $compile,
$rootScope,
element;

// Load the myApp module, which contains the directive
beforeEach(angular.mock.module('app'));

// Store references to $rootScope and $compile
// so they are available to all tests in this describe block
beforeEach(inject(function(_$compile_, _$rootScope_) {
// The injector unwraps the underscores (_) from around the parameter names when matching
$compile = _$compile_;
$rootScope = _$rootScope_;
}));

beforeEach(function() {
var liskEpoch = Date.UTC(2016, 4, 24, 17, 0, 0, 0);
$rootScope.currentTimestamp = Math.floor((new Date().valueOf() - liskEpoch) / 1000);

element = $compile('<timestamp data="currentTimestamp"></timestamp>')($rootScope);
$rootScope.$digest();
});

it('should contain a timeago of the date', function() {
expect(element.text()).to.equal('a few seconds');
});
});
9 changes: 4 additions & 5 deletions src/test/components/top/top.spec.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@

describe('Top component', function() {
var $compile,
$rootScope;

// Load the myApp module, which contains the directive
beforeEach(angular.mock.module("app"));
beforeEach(angular.mock.module('app'));

// Store references to $rootScope and $compile
// so they are available to all tests in this describe block
beforeEach(inject(function(_$compile_, _$rootScope_){
beforeEach(inject(function(_$compile_, _$rootScope_) {
// The injector unwraps the underscores (_) from around the parameter names when matching
$compile = _$compile_;
$rootScope = _$rootScope_;
}));

it('should contain address', function() {
// Compile a piece of HTML containing the directive
var element = $compile("<top></top>")($rootScope);
var element = $compile('<top></top>')($rootScope);
// fire all the watches, so the scope expression {{1 + 1}} will be evaluated
$rootScope.$digest();
// Check that the compiled element contains the templated content
expect(element.html()).to.contain("address");
expect(element.html()).to.contain('address');
});
});
1 change: 1 addition & 0 deletions src/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ require('chai');

require('./components/login/login.spec');
require('./components/top/top.spec');
require('./components/timestamp/timestamp.spec');

0 comments on commit f8c3136

Please sign in to comment.