diff --git a/Gruntfile.coffee b/Gruntfile.coffee index b04974dc88..26dd0e6b37 100644 --- a/Gruntfile.coffee +++ b/Gruntfile.coffee @@ -25,22 +25,11 @@ module.exports = (grunt) -> options: { context : { PRODUCTION: true - BETA: false } }, expand: true src: ['build/index.html'] dest: '' - beta: - options: { - context : { - PRODUCTION: true - BETA: true - } - }, - expand: true - src: ['build/admin.html', 'build/index-beta.html'] - dest: '' concat: options: @@ -94,17 +83,7 @@ module.exports = (grunt) -> 'build/application-dependencies.min.js' ] - dest: "dist/application.min.js" - - beta: - src: [ - "build/bower_components/jquery/dist/jquery.js" - "build/bower_components/angular/angular.min.js" - "build/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js" - "build/bower_components/bootstrap/dist/js/bootstrap.min.js" - "app/admin.js" - ] - dest: "dist/beta-admin.js" + dest: "dist/js/application.min.js" coffee: coffee_to_js: @@ -139,15 +118,8 @@ module.exports = (grunt) -> "build/css/blockchain.css" # Needs to be loaded first "build/css/**/*.css" ], - dest: "dist/application.css" - }, - beta: { - src: [ - "build/css/blockchain.css" - "build/css/navigation.css" - ], - dest: "dist/beta-admin.css" - }, + dest: "dist/css/application.css" + } }, autoprefixer: { @@ -201,8 +173,7 @@ module.exports = (grunt) -> main: files: [ {src: ["beep.wav"], dest: "dist/"} - {src: ["index.html", "index-beta.html"], dest: "dist/", cwd: "build", expand: true} - {src: ["admin.html"], dest: "dist/", cwd: "build", expand: true} + {src: ["index.html"], dest: "dist/", cwd: "build", expand: true} {src: ["img/*"], dest: "dist/", cwd: "build", expand: true} {src: ["locales/*"], dest: "dist/", cwd: "build", expand: true} {src: ["**/*"], dest: "dist/fonts", cwd: "build/fonts", expand: true} @@ -228,15 +199,6 @@ module.exports = (grunt) -> {src: ["*"], dest: "build/fonts", cwd: "assets/fonts/themify", expand: true} ] - beta: - files: [ - {src: ["beta/betaAdminServer.js"], dest: "dist/", cwd: "app", expand: true} - {src: ["beta/package.json"], dest: "dist/", cwd: "app", expand: true} - ] - - beta_index: - src: "build/index.html" - dest: "build/index-beta.html" images: files: [ @@ -280,7 +242,6 @@ module.exports = (grunt) -> options: client: false files: - "build/admin.html": "app/admin.jade" "build/index.html": "app/index.jade" babel: @@ -295,7 +256,7 @@ module.exports = (grunt) -> }] rename: - assets: # Renames all images, fonts, etc and updates application.min.js, application.css and admin.html with their new names. + assets: # Renames all images, fonts, etc and updates application.min.js and application.css with their new names. options: skipIfHashed: true startSymbol: "{{" @@ -322,7 +283,7 @@ module.exports = (grunt) -> publicdir = require("fs").realpathSync("dist") path = require("path") - for referring_file_path in ["dist/application.min.js", "dist/beta-admin.js", "dist/application.css", "dist/beta-admin.css", "dist/admin.html", "dist/index.html", "dist/index-beta.html"] + for referring_file_path in ["dist/js/application.min.js", "dist/css/application.css", "dist/index.html"] contents = grunt.file.read(referring_file_path) before = undefined after = undefined @@ -347,7 +308,7 @@ module.exports = (grunt) -> 'dist/beep.wav' ] - html: # Renames application/beta.min.js/css and updates index/admin.html + html: # Renames application.min.js/css and updates index.html options: skipIfHashed: true startSymbol: "{{" @@ -359,7 +320,7 @@ module.exports = (grunt) -> publicdir = require("fs").realpathSync("dist") path = require("path") - for referring_file_path in ["dist/index.html", "dist/index-beta.html", "dist/admin.html"] + for referring_file_path in ["dist/index.html"] contents = grunt.file.read(referring_file_path) before = undefined after = undefined @@ -375,10 +336,8 @@ module.exports = (grunt) -> files: src: [ - 'dist/application.min.js' - 'dist/application.css' - 'dist/beta-admin.js' - 'dist/beta-admin.css' + 'dist/js/application.min.js' + 'dist/css/application.css' ] shell: @@ -390,10 +349,6 @@ module.exports = (grunt) -> command: () -> 'rsync -rz --delete server.js hd-dev@server:' - deploy_beta_to_dev: - command: () -> - 'rsync -rz --delete node_modules/my-wallet-v3-beta-module hd-dev@server:node_modules/' - deploy_static_to_staging: command: () -> 'rsync -rz --delete dist hd-staging@server:' @@ -402,22 +357,6 @@ module.exports = (grunt) -> command: () -> 'rsync -rz --delete server.js hd-staging@server:' - deploy_beta_to_staging: - command: () -> - 'rsync -rz --delete node_modules/my-wallet-v3-beta-module hd-staging@server:node_modules/' - - deploy_static_to_alpha: - command: () -> - 'rsync -rz --delete dist hd-alpha@server:' - - deploy_server_to_alpha: - command: () -> - 'rsync -rz --delete server.js hd-alpha@server:' - - deploy_beta_to_alpha: - command: () -> - 'rsync -rz --delete node_modules/my-wallet-v3-beta-module hd-alpha@server:node_modules/' - deploy_start_dev: command: () -> 'ssh hd-dev@server "./start.sh"' @@ -513,11 +452,6 @@ module.exports = (grunt) -> "watch" ] - grunt.registerTask "dist_beta", [ - "concat:beta" - "concat_css:beta" - ] - # Default task(s). grunt.registerTask "dist", [ "clean" @@ -531,11 +465,8 @@ module.exports = (grunt) -> "concat:application" "concat_css:app" "jade" - "copy:beta_index" "preprocess" "copy:main" - "copy:beta" - "dist_beta" # We don't check beta dependencies against a whitelist "rename:assets" "rename:html" "git_changelog" @@ -550,11 +481,8 @@ module.exports = (grunt) -> "concat:application" "concat_css:app" "jade" - "copy:beta_index" "preprocess" "copy:main" - "copy:beta" - "dist_beta" "rename:assets" "rename:html" ] @@ -570,15 +498,9 @@ module.exports = (grunt) -> "shell:deploy_start_dev" ] - grunt.registerTask "deploy_beta_to_dev", [ - "shell:deploy_beta_to_dev" - "shell:deploy_start_dev" - ] - grunt.registerTask "deploy_to_dev", [ "dist" "shell:deploy_static_to_dev" - "shell:deploy_beta_to_dev" "shell:deploy_server_to_dev" "shell:deploy_start_dev" ] @@ -594,43 +516,13 @@ module.exports = (grunt) -> "shell:deploy_start_staging" ] - grunt.registerTask "deploy_beta_to_staging", [ - "shell:deploy_beta_to_staging" - "shell:deploy_start_staging" - ] - grunt.registerTask "deploy_to_staging", [ "dist" "shell:deploy_static_to_staging" - "shell:deploy_beta_to_staging" "shell:deploy_server_to_staging" "shell:deploy_start_staging" ] - grunt.registerTask "deploy_static_to_alpha", [ - "dist" - "shell:deploy_static_to_alpha" - "shell:deploy_start_alpha" - ] - - grunt.registerTask "deploy_server_to_alpha", [ - "shell:deploy_server_to_alpha" - "shell:deploy_start_alpha" - ] - - grunt.registerTask "deploy_beta_to_alpha", [ - "shell:deploy_beta_to_alpha" - "shell:deploy_start_alpha" - ] - - grunt.registerTask "deploy_to_alpha", [ - "dist" - "shell:deploy_static_to_alpha" - "shell:deploy_beta_to_alpha" - "shell:deploy_server_to_alpha" - "shell:deploy_start_alpha" - ] - grunt.registerTask "check_translations", [ "shell:check_translations" ] diff --git a/app/admin.jade b/app/admin.jade deleted file mode 100644 index ee5a33aec0..0000000000 --- a/app/admin.jade +++ /dev/null @@ -1,271 +0,0 @@ -doctype -html.overflow-scroll(ng-app="AdminInterface" lang='en') - head - meta(charset='utf-8') - title Beta Admin - - - script(src='../bower_components/jquery/dist/jquery.js') - script(src='../bower_components/angular/angular.js') - script(src="../bower_components/bootstrap/dist/js/bootstrap.min.js") - script(src='../bower_components/angular-bootstrap/ui-bootstrap-tpls.js') - - link(rel='stylesheet', href='../build/css/blockchain.css') - link(rel='stylesheet', href='../build/css/navigation.css') - - script(src='../app/admin.js') - - - - - body.overflow-scroll(ng-controller="AdminCtrl") - .navbar.navbar-default.navbar-inverse.navbar-unauth(role='navigation') - .container-fluid - .navbar-header - a.navbar-brand - img#logo(src="../img/logo-updated.png" alt="Blockchain") - .navbar-collapse.collapse - ul.nav.navbar-nav.navbar-right - li.item - a(href="/") Home - li.item - a(href="/") About - li.item.active - a(href="/") Wallet - li.item - a(href="/") Explorer - li.item - a(href="/") Merchant - li.item - a(href="/") Support - - div.container.login-form.mbl - h1 V3 Beta Admin Interface - .form-group.col-xs-6 - form.form-inline - button.btn.btn-default(ng-click="openModal('assignKeyModal.html', 'AssignKeyCtrl')") + New Key - button.btn.btn-default(ng-click="openModal('capturePageModal.html', 'CapturePageCtrl')") Capture Page - button.btn.btn-default(ng-click="openModal('activationModal.html', 'ActivateKeysCtrl')") - span.glyphicon.glyphicon-flash - span  Activate Keys - button.btn.btn-default(ng-click="retrieveCSV()") CSV - .form-group.col-xs-6 - form.form-inline.pull-right(name="searchForm" ng-submit="load()" novalidate) - input.form-control(ng-model="search.text" type="text" placeholder="Search" required) - select.form-control(ng-model="search.filter" ng-options="f for f in filters" required) - button.btn.btn-default(ng-disabled="searchForm.$invalid" type="submit") - span(class="glyphicon glyphicon-arrow-right") - .form-group.col-xs-6.ng-cloak - label {{ walletCount }} Wallets Created - .table-div.ng-cloak - table.table.table-hover.table-condensed - tr - th.pointer(ng-repeat="th in headers" ng-click="sort(th)") {{ th }} - th ios - th android - th edit - th revoke - tr(ng-repeat="item in tableData") - td {{ item.rowid }} - td {{ item.key }} - td {{ item.name }} - td {{ item.email }} - td {{ getDateFromTime(item.lastseen) }} - td {{ getDateFromTime(item.email_opened_at) }} - td {{ getDateFromTime(item.email_link_followed_at) }} - td {{ item.guid }} - td {{ (item.activated) ? 'Activated' : 'Pending' }} - td {{ displayIOSStatus(item) }} - td {{ displayAndroidStatus(item) }} - td - a(ng-click="openModal('editModal.html', 'EditKeyCtrl', item)") edit - td - a(ng-click="revokeKey(item.rowid)") revoke - .flex.flex-justify.pal - button.btn.btn-primary.mrl(ng-click="load(-1)") - | Prev Page - button.btn.btn-primary.mll(ng-click="load(1)") - | Next Page - - // Assign new key modal - script(type="text/ng-template" id="assignKeyModal.html"). - - - - // Edit/Activate key modal - script(type="text/ng-template" id="editModal.html"). - - - - // Capture page settings modal - script(type="text/ng-template" id="capturePageModal.html"). - - - - // Activate many keys modal - script(type="text/ng-template" id="activationModal.html"). - - diff --git a/app/admin.js b/app/admin.js deleted file mode 100644 index 31049c3670..0000000000 --- a/app/admin.js +++ /dev/null @@ -1,204 +0,0 @@ -var admin = angular.module('AdminInterface', ['ui.bootstrap']); - -// Main Controller -admin.controller('AdminCtrl', function ($rootScope, $scope, $http, $modal, InterfaceHelper) { - - $rootScope.percentRequested = 0; - - // Declare scope variables - $scope.tableData = []; - $scope.headers = ['rowid', 'key', 'name', 'email', 'lastseen', 'email opened','link followed', 'guid', 'status']; - $scope.filters = ['name', 'email', 'key', 'guid']; - $scope.search = { text: '', filter: '', sort: 'rowid', order: 'Z' }; - $scope.offset = 0; - - // Convert timestamp to readable - $scope.getDateFromTime = function (time) { - return (time) ? new Date(time).toDateString() : 'Never'; - }; - - $scope.displayIOSStatus = function (item) { - if (item.ios_sent) return 'Sent'; - if (item.ios_approved) return 'Approved'; - if (item.ios) return 'Requested'; - return 'Not Requested'; - }; - - $scope.displayAndroidStatus = function (item) { - if (item.android_sent) return 'Sent'; - if (item.android_approved) return 'Approved'; - if (item.android) return 'Requested'; - return 'Not Requested'; - }; - - $scope.sort = function (header) { - if ($scope.search.sort === header) { - $scope.search.order = ($scope.search.order === 'A') ? 'Z' : 'A'; - } else { - $scope.search.sort = header; - $scope.search.order = 'A'; - } - $scope.load(); - }; - - // API functions - - $scope.revokeKey = function (id) { - InterfaceHelper.callApi('/delete-key', { rowid: id }) - .success($scope.load); - }; - - $scope.getPercent = function () { - $http.get('/percent_requested') - .success(function(res){ $rootScope.percentRequested = res.width; }) - .error(InterfaceHelper.error); - }; - - $scope.setPercent = function (value) { - InterfaceHelper.callApi('/set-percent-requested', {percent:value}) - .success($scope.getPercent); - }; - - $scope.getNumWalletsCreated = function () { - InterfaceHelper.callApi('/wallets-created') - .success(function (data) { - $scope.walletCount = data.count - }); - }; - - $scope.retrieveCSV = function () { - location.assign(InterfaceHelper.getRootUrl() + '/get-csv'); - }; - - $scope.load = function (offset) { - var filter = {}; - $scope.offset = $scope.offset + (offset|0); - if ($scope.offset < 0) $scope.offset = 0; - filter[$scope.search.filter] = $scope.search.text; - InterfaceHelper.callApi('/get-sorted-keys', { - sort: $scope.search.sort, - order: $scope.search.order, - filter: filter, - offset: 100 * $scope.offset - }).success(function (response) { - $scope.tableData = response.data; - }); - }; - - // Modal opening - $scope.openModal = function (tmpl, ctrl, entry) { - $modal.open({ - templateUrl: tmpl, - controller: ctrl, - resolve: { - getPercent: function () { return $scope.getPercent; }, - setPercent: function () { return $scope.setPercent; }, - load: function () { return $scope.load; }, - entry: function () { return entry; } - } - }); - }; - - // Initial data load - $scope.load(); - $scope.getNumWalletsCreated(); -}); - -// Modal Controllers -admin.controller('AssignKeyCtrl', function ($scope, $uibModalInstance, InterfaceHelper, load) { - $scope.fields = { name: '', email: '', guid: '' }; - $scope.assignKey = function (name, email, guid) { - if (guid === '') guid = null; - InterfaceHelper.callApi('/assign-key', {name:name,email:email,guid:guid}) - .success(load); - $uibModalInstance.dismiss(); - }; -}); - -admin.controller('CapturePageCtrl', function ($scope, getPercent, setPercent) { - $scope.setPercent = setPercent; - getPercent(); -}); - -admin.controller('EditKeyCtrl', function ($scope, $uibModalInstance, InterfaceHelper, load, entry) { - $scope.fields = angular.copy(entry); - $scope.submitEdit = function (doActivate) { - var endpoint = (doActivate) ? '/activate-key' : '/update-key'; - var selection = { rowid: entry.rowid }; - var update = InterfaceHelper.compareProperties($scope.fields, entry); - update.activated = doActivate; - InterfaceHelper.callApi(endpoint, {selection: selection, update: update}) - .success(function () { - load(); - $uibModalInstance.dismiss(); - }); - }; - $scope.resendText = 'Resend Invitation Email' - $scope.resending = false; - $scope.resendActivationEmail = function () { - $scope.resending = true; $scope.resendText = 'Sending...'; - InterfaceHelper.callApi('/resend-activation', {key: $scope.fields.key}) - .success(function(res){ - if (res.error) console.error(res.error); - $scope.resendText = res.error ? 'Error' : 'Sent!'; - }); - }; -}); - -admin.controller('ActivateKeysCtrl', function ($scope, InterfaceHelper, load) { - $scope.step = 0; - $scope.numKeys = $scope.numEmails = 0; - $scope.activate = function (min, max) { - $scope.step = 1; - InterfaceHelper.callApi('/activate-all', {min:min||null,max:max||null}) - .success(function (res) { - load(); - if (res.error) $scope.error = res.error; - if (typeof res.data === 'object') { - $scope.numKeys = res.data.count; - $scope.numEmails = res.data.successful; - } - $scope.step = 2; - }); - }; - $scope.resendText = 'Resend Invitation Emails' - $scope.resend = function (min, max) { - $scope.step = 1; - InterfaceHelper.callApi('/resend-many', {min:min||null,max:max||null}) - .success(function(res){ - if (res.error) $scope.error = res.error; - if (typeof res.data === 'object') { - $scope.numKeys = res.data.count; - $scope.numEmails = res.data.successful; - } - $scope.step = 3; - }); - }; -}); - -// Helper Service -admin.factory('InterfaceHelper', function ($http, $httpParamSerializerJQLike) { - var helper = {}; - var rootUrl = '/admin/api'; - helper.error = function (response) { - if (!response || !response.error) return; - console.error(response.error) - }; - helper.callApi = function (endpoint, data) { - return $http.get(rootUrl + endpoint, { - params: data, - paramSerializer: $httpParamSerializerJQLike - }).error(helper.error); - }; - helper.getRootUrl = function () { - return rootUrl; - }; - helper.compareProperties = function (o1, o2) { - var object = {}; - for (p in o1) { - if (o1[p] !== o2[p]) object[p] = o1[p]; - } - return object; - }; - return helper; -}); diff --git a/app/index.jade b/app/index.jade index 16a4154fcc..e063528778 100644 --- a/app/index.jade +++ b/app/index.jade @@ -1,7 +1,6 @@ doctype - - - + + head meta(charset='utf-8') meta(name="viewport",content="width=device-width, initial-scale=1.0, maximum-scale=1") @@ -69,7 +68,6 @@ head script(src='build/js/controllers/claimModal.controller.js') script(src='build/js/controllers/confirmRecoveryPhrase.controller.js') script(src='build/js/controllers/home.controller.js') - script(src='build/js/controllers/feedback.controller.js') script(src='build/js/controllers/firstTime.controller.js') script(src='build/js/controllers/login.controller.js') script(src='build/js/controllers/navigation.controller.js') @@ -86,6 +84,7 @@ head script(src='build/js/controllers/modalNotification.controller.js') script(src='build/js/controllers/recoverFunds.controller.js') script(src='build/js/controllers/lostGuid.controller.js') + script(src='build/js/controllers/feedback.controller.js') script(src='build/js/controllers/walletNavigation.controller.js') script(src='build/js/controllers/settings/settings.controller.js') script(src='build/js/controllers/settings/info.controller.js') @@ -165,8 +164,8 @@ head //- Whitelist by copying script from browser and putting it in a file diff --git a/app/partials/signup.jade b/app/partials/signup.jade index c6050c17c5..462dbce4bc 100644 --- a/app/partials/signup.jade +++ b/app/partials/signup.jade @@ -1,41 +1,34 @@ div header - h2.em-300(translate="NEW_ACCT_WELCOME", ng-show="currentStep == 1") - form.form-horizontal(ng-show="betaCheckError") - .form-group - p - p - p {{ betaCheckError }} - form.form-horizontal(role="form",name="form",novalidate, ng-show="betaCheckSuccess") - div(ng-switch="currentStep") - div(ng-switch-when="1") - .security-red.mbl.em-400.flex-center - i.ti-hand-stop.mrm.h3.mvn.hidden-xs - span(translate="ALPHA_WARNING") - .form-group(ng-class="{'has-error': errors.email, 'has-success': success.email}") - label.col-sm-4.control-label(translate="EMAIL") - .col-sm-8 - input.form-control(type="email",ng-model="fields.email",autofocus,ng-blur="validate()", ng-focus="errors.email = null") - span.help-block - p {{ errors.email }} - .form-group(ng-class="{'has-error': errors.password, 'has-success': success.password}") - label.col-sm-4.control-label(translate="NEW_PASSWORD") - .col-sm-8 - input.form-control(type="password", name="password",ng-model="fields.password",autofocus,ng-blur="validate()", ng-focus="errors.password = null", ng-maxlength="255", min-entropy="25" required) - password-entropy(password="fields.password").help-block - span.help-block {{ errors.password }} - .form-group(ng-class="{'has-error': errors.confirmation, 'has-success': success.confirmation}") - label.col-sm-4.control-label(translate="CONFIRM_PASSWORD") - .col-sm-8 - input.form-control(type="password",ng-model="fields.confirmation",on-enter="tryNextStep()",autofocus,ng-blur="validate()", ng-focus="errors.confirmation = null") - span.help-block - p {{ errors.confirmation }} - .form-group.flex-center.mtm - .col-sm-4 - input#agreement_accept.pull-right(ng-model="fields.acceptedAgreement" type="checkbox" name="agreement_accept" ng-change="validate()") - label.em-300.col-sm-8 - | I have read and agree to the - a.em-500(ng-click="showAgreement()") Alpha Program Participation Agreement + h2.em-300(translate="NEW_ACCT_WELCOME") + form.form-horizontal(role="form",name="form",novalidate) + .security-red.mbl.em-400.flex-center + i.ti-hand-stop.mrm.h3.mvn.hidden-xs + span(translate="ALPHA_WARNING") + .form-group(ng-class="{'has-error': errors.email, 'has-success': success.email}") + label.col-sm-4.control-label(translate="EMAIL") + .col-sm-8 + input.form-control(type="email",ng-model="fields.email",autofocus,ng-blur="validate()", ng-focus="errors.email = null") + span.help-block + p {{ errors.email }} + .form-group(ng-class="{'has-error': errors.password, 'has-success': success.password}") + label.col-sm-4.control-label(translate="NEW_PASSWORD") + .col-sm-8 + input.form-control(type="password", name="password",ng-model="fields.password",autofocus,ng-blur="validate()", ng-focus="errors.password = null", ng-maxlength="255", min-entropy="25" required) + password-entropy(password="fields.password").help-block + span.help-block {{ errors.password }} + .form-group(ng-class="{'has-error': errors.confirmation, 'has-success': success.confirmation}") + label.col-sm-4.control-label(translate="CONFIRM_PASSWORD") + .col-sm-8 + input.form-control(type="password",ng-model="fields.confirmation",on-enter="trySignup()",autofocus,ng-blur="validate()", ng-focus="errors.confirmation = null") + span.help-block + p {{ errors.confirmation }} + .form-group.flex-center.mtm + .col-sm-4 + input#agreement_accept.pull-right(ng-model="fields.acceptedAgreement" type="checkbox" name="agreement_accept" ng-change="validate()") + label.em-300.col-sm-8 + | I have read and agree to the + a.em-500(ng-click="showAgreement()") Alpha Program Participation Agreement .flex-center.flex-end.mbl - button.button-primary(ng-click="nextStep()",ng-disabled="!form.$valid || !isValid[0] || !fields.acceptedAgreement", translate="CONTINUE", ng-show="currentStep == 1 && !working") + button.button-primary(ng-click="signup()",ng-disabled="!form.$valid || !isValid || !fields.acceptedAgreement", translate="CONTINUE", ng-show="!working") img(ng-show="working" src="img/spinner.gif") diff --git a/assets/js/controllers/recoverFunds.controller.js b/assets/js/controllers/recoverFunds.controller.js index 12cc2480ee..fb08dba205 100644 --- a/assets/js/controllers/recoverFunds.controller.js +++ b/assets/js/controllers/recoverFunds.controller.js @@ -17,7 +17,6 @@ function RecoverFundsCtrl($scope, $rootScope, $state, $timeout, $translate, Wall $scope.working = true; const success = (wallet) => { - $rootScope.beta = false; $scope.working = false; $scope.nextStep(); $rootScope.$safeApply(); diff --git a/assets/js/controllers/signup.controller.js b/assets/js/controllers/signup.controller.js index f9a7a7a434..1ebe6671c7 100644 --- a/assets/js/controllers/signup.controller.js +++ b/assets/js/controllers/signup.controller.js @@ -3,10 +3,7 @@ angular .controller("SignupCtrl", SignupCtrl); function SignupCtrl($scope, $rootScope, $log, Wallet, Alerts, currency, $uibModal, $translate, $cookieStore, $filter, $state, $http, languages) { - $scope.currentStep = 1; $scope.working = false; - $scope.languages = languages; - $scope.currencies = currency.currencies; $scope.alerts = Alerts.alerts; $scope.status = Wallet.status; @@ -17,43 +14,20 @@ function SignupCtrl($scope, $rootScope, $log, Wallet, Alerts, currency, $uibModa } }); - $scope.isValid = [true, true]; + $scope.isValid = true; let language_guess = $filter("getByProperty")("code", $translate.use(), languages); if (language_guess == null) { - language_guess = $filter("getByProperty")("code", "en", languages); + $scope.language_guess = $filter("getByProperty")("code", "en", languages); } - const currency_guess = $filter("getByProperty")("code", "USD", currency.currencies); + $scope.currency_guess = $filter("getByProperty")("code", "USD", currency.currencies); + $scope.fields = { email: "", password: "", confirmation: "", - language: language_guess, - currency: currency_guess, acceptedAgreement: false }; - $scope.betaCheckSuccess = false; - - - // If BETA=1 is set in .env then in index.html/jade $rootScope.beta is set. - // The following checks are not ideal as they can be bypassed with some creative Javascript commands. - if ($rootScope.beta) { - // Check if we allow signups at the moment: - $http.post("/check_beta", {}).success((data) => { - if (data.open) { - $scope.betaCheckSuccess = true; - } else { - if (data.error && data.error.message) { - $scope.betaCheckError = data.error.message; - } - } - }).error(() => { - $scope.betaCheckError = "There is a problem with our alpha wallet access control system, please try again later."; - }); - } else { - $scope.betaCheckSuccess = true; - } - $scope.showAgreement = () => { const modalInstance = $uibModal.open({ templateUrl: "partials/alpha-agreement.jade", @@ -67,33 +41,29 @@ function SignupCtrl($scope, $rootScope, $log, Wallet, Alerts, currency, $uibModa $state.go("wallet.common.home"); }; - $scope.tryNextStep = () => { - if ($scope.isValid[0]) $scope.nextStep(); + $scope.trySignup = () => { + if ($scope.isValid) $scope.signup(); }; - $scope.nextStep = () => { + $scope.signup = () => { $scope.validate(); - if ($scope.isValid[$scope.currentStep - 1]) { - if ($scope.currentStep === 1) { - $scope.working = true; - $scope.createWallet( uid => { - $scope.working = false; - if (uid != null) { - $cookieStore.put("uid", uid); - } - if ($scope.savePassword) { - $cookieStore.put("password", $scope.fields.password); - } - $scope.currentStep++; - $scope.close(""); - }); - } + if ($scope.isValid) { + $scope.working = true; + $scope.createWallet( uid => { + $scope.working = false; + if (uid != null) { + $cookieStore.put("uid", uid); + } + if ($scope.savePassword) { + $cookieStore.put("password", $scope.fields.password); + } + $scope.close(""); + }); } }; $scope.createWallet = successCallback => { Wallet.create($scope.fields.password, $scope.fields.email, $scope.fields.language, $scope.fields.currency, uid => { - $cookieStore.put("uid", uid); successCallback(uid); }); }; @@ -108,8 +78,7 @@ function SignupCtrl($scope, $rootScope, $log, Wallet, Alerts, currency, $uibModa if (visual == null) { visual = true; } - $scope.isValid[0] = true; - $scope.isValid[1] = true; + $scope.isValid = true; $scope.errors = { email: null, password: null, @@ -121,12 +90,12 @@ function SignupCtrl($scope, $rootScope, $log, Wallet, Alerts, currency, $uibModa confirmation: false }; if ($scope.fields.email === "") { - $scope.isValid[0] = false; + $scope.isValid = false; $translate("EMAIL_ADDRESS_REQUIRED").then( translation => { $scope.errors.email = translation; }); } else if ($scope.form && $scope.form.$error.email) { - $scope.isValid[0] = false; + $scope.isValid = false; $translate("EMAIL_ADDRESS_INVALID").then( translation => { $scope.errors.email = translation; }); @@ -135,25 +104,25 @@ function SignupCtrl($scope, $rootScope, $log, Wallet, Alerts, currency, $uibModa } if ($scope.form && $scope.form.$error) { if ($scope.form.$error.minEntropy) { - $scope.isValid[0] = false; + $scope.isValid = false; $translate("TOO_WEAK").then( translation => { $scope.errors.password = translation; }); } if ($scope.form.$error.maxlength) { - $scope.isValid[0] = false; + $scope.isValid = false; $translate("TOO_LONG").then( translation => { $scope.errors.password = translation; }); } } if ($scope.fields.confirmation === "") { - $scope.isValid[0] = false; + $scope.isValid = false; } else { if ($scope.fields.confirmation === $scope.fields.password) { $scope.success.confirmation = true; } else { - $scope.isValid[0] = false; + $scope.isValid = false; if (visual) { $translate("NO_MATCH").then( translation => { $scope.errors.confirmation = translation; @@ -162,19 +131,19 @@ function SignupCtrl($scope, $rootScope, $log, Wallet, Alerts, currency, $uibModa } } if (!$scope.fields.acceptedAgreement) { - $scope.isValid[0] = false; + $scope.isValid = false; } }; $scope.validate(); - $scope.$watch("fields.language", (newVal, oldVal) => { + $scope.$watch("language_guess", (newVal, oldVal) => { if (newVal != null) { $translate.use(newVal.code); Wallet.changeLanguage(newVal); } }); - $scope.$watch("fields.currency", (newVal, oldVal) => { + $scope.$watch("currency_guess", (newVal, oldVal) => { if (newVal != null) { Wallet.changeCurrency(newVal); } diff --git a/assets/js/services/wallet.service.js b/assets/js/services/wallet.service.js index 95caa9f9fc..9bea4ab0dd 100644 --- a/assets/js/services/wallet.service.js +++ b/assets/js/services/wallet.service.js @@ -178,45 +178,22 @@ function Wallet($http, $window, $timeout, Alerts, MyWallet, MyBlockchainApi, MyB wallet.applyIfNeeded(); }; - let betaCheckFinished = () => { - $window.root = 'https://blockchain.info/'; - wallet.my.login( - uid, - null, // sharedKey - password, - two_factor_code, - didLogin, - needsTwoFactorCode, - wrongTwoFactorCode, - authorizationRequired, - loginError, - () => {}, // fetchSuccess - () => {}, // decryptSucces - () => {} // buildHDSucces - ); - currency.fetchExchangeRate(); - }; - - // If BETA=1 is set in .env then in index.html/jade $rootScope.beta is set. - if ($rootScope.beta) { - $http.post('/check_guid_for_beta_key', { - guid: uid - }).success((data) => { - if (data.verified) { - betaCheckFinished(); - } else { - if (data.error && data.error.message) { - Alerts.displayError(data.error.message); - } - errorCallback(); - } - }).error(() => { - Alerts.displayError('Unable to verify your wallet UID.'); - errorCallback(); - }); - } else { - betaCheckFinished(); - } + $window.root = 'https://blockchain.info/'; + wallet.my.login( + uid, + null, // sharedKey + password, + two_factor_code, + didLogin, + needsTwoFactorCode, + wrongTwoFactorCode, + authorizationRequired, + loginError, + () => {}, // fetchSuccess + () => {}, // decryptSucces + () => {} // buildHDSucces + ); + currency.fetchExchangeRate(); }; wallet.upgrade = (successCallback, cancelSecondPasswordCallback) => { @@ -308,24 +285,7 @@ function Wallet($http, $window, $timeout, Alerts, MyWallet, MyBlockchainApi, MyB Alerts.displayError('Unable to login to new wallet'); }; - if ($rootScope.beta) { - $http.post('/register_guid', { - guid: uid, - email: email - }).success((data) => { - if (data.success) { - wallet.login(uid, password, null, null, loginSuccess, loginError); - } else { - if (data.error && data.error.message) { - Alerts.displayError(data.error.message); - } - } - }).error(() => { - Alerts.displayWarning('Unable to associate your new wallet with your invite code. Please try to login using your UID ' + uid + ' or register again.', true); - }); - } else { - wallet.login(uid, password, null, null, loginSuccess, loginError); - } + wallet.login(uid, password, null, null, loginSuccess, loginError); }; let error = (error) => { diff --git a/betakeys-template.MDF b/betakeys-template.MDF deleted file mode 100644 index 407d5614da..0000000000 Binary files a/betakeys-template.MDF and /dev/null differ diff --git a/e2e-tests/config.js b/e2e-tests/config.js deleted file mode 100755 index b5118db996..0000000000 --- a/e2e-tests/config.js +++ /dev/null @@ -1,46 +0,0 @@ -exports.config = { - - // The address of a running selenium server - seleniumAddress: 'http://localhost:4444/wd/hub', - - // Spec patterns are relative to the location of this config - specs: ['**/*_spec.js'], - - suites: { - trans: '**/transactions/*_spec.js', - global: '**/global/*_spec.js', - settings: '**/settings/*_spec.js', - securityCenter: '**/security-center/*_spec.js' - }, - - params: { - login: { - uidfake: 'c5825g04-8ke3-25r1-p103-3g000wr4-123', - pwweak: 'asdf', - pwregular: 'asdfgh123456', - pwnormal: 'asdf!@#$', - email: 'example@example.com', - nums: '1234567890', - chars: '$^*%(^*#$&@', - } - }, - - jasmineNodeOpts: { - showColors: true, - isVerbose: true, - includeStackTrace: true - }, - - onPrepare: function() { - browser.driver.manage().window().setSize(1400, 1200); - }, - - // Capabilities to be passed to the webdriver instance - multiCapabilities: [{ - 'browserName': 'chrome' - // }, { - // 'browserName': 'firefox' - }] - -} - diff --git a/e2e-tests/global/login_spec.js b/e2e-tests/global/login_spec.js deleted file mode 100755 index b8dad79f12..0000000000 --- a/e2e-tests/global/login_spec.js +++ /dev/null @@ -1,170 +0,0 @@ -describe('login-page', function() { - - // Required JS files - var login = require('../ignore.js'); - var util = require('../util.js'); - - // These are log in fields - var loginUIDField = browser.element(by.model('uid')); - var loginPasswordField = browser.element(by.model('password')); - - // These are create login fields - var passwordField = element(by.model('fields.password')); - var confField = element(by.model('fields.confirmation')); - var emailField = element(by.model('fields.email')); - - // These are log in buttons - var loginButton = element(by.id('login')); - - // Clear log in test fields - var clearLoginFields = function (){ - loginUIDField.clear(); - loginPasswordField.clear(); - } - - // Click field, see invalid error, clear email field - var validateInvalid = function(){ - passwordField.click(); - util.shouldContainCSS('p.ng-binding', 'Invalid'); - emailField.clear(); - } - - beforeEach(function() { - - util.getURL(); - - }); - - afterEach(function() { - - // Refresh to begin test on login page - browser.refresh(); - - }); - - xit('should validate top navigation items', function() { - - browser.findElement(by.id('logo')); - browser.findElement(by.linkText('Home')); - browser.findElement(by.linkText('About')); - browser.findElement(by.linkText('Wallet')); - browser.findElement(by.linkText('Explorer')); - browser.findElement(by.linkText('Merchant')); - browser.findElement(by.linkText('Support')); - - }); - - it('should have login page elements', function() { - - // Find UID label and text field - browser.findElement(by.css('[translate="UID"]')); - browser.findElement(by.model('uid')); - - // Find password label and text field - browser.findElement(by.css('[translate="PASSWORD"]')); - browser.findElement(by.model('password')); - - // Find login and create wallet buttons - browser.findElement(by.id('login')); - browser.findElement(by.css('[ng-click="register()"]')); - - }); - - it('should test password strength', function() { - - util.submitBetaKey(); - - // Test weak password - passwordField.sendKeys(browser.params.login.pwweak); - browser.findElement(by.css('.progress-bar-danger')); - passwordField.clear(); - - // Test regular password - passwordField.sendKeys(browser.params.login.pwregular); - browser.findElement(by.css('.progress-bar-warning')); - passwordField.clear(); - - // Test normal password - passwordField.sendKeys(browser.params.login.pwnormal); - browser.findElement(by.css('.progress-bar-info')); - passwordField.clear(); - - // Test strong password - passwordField.sendKeys(login.pw); - browser.findElement(by.css('.progress-bar-success')); - passwordField.clear(); - - }); - - it('should test password matching', function() { - - // Enter key and click Create Wallet button - util.submitBetaKey(); - - // Enter non-matching passwords - passwordField.sendKeys(login.pw); - confField.sendKeys(browser.params.login.pwweak); - - // Submit and validate error messaging - passwordField.click(); - util.shouldContainCSS('p.ng-binding', 'Does not match'); - - // Clear both fields - passwordField.clear(); - confField.clear(); - - }); - - // Invite key pre-fills email address and disables editing, this test case is disabled - xit('should test email address validation', function() { - - // Enter beta key and click Create Wallet button - util.submitBetaKey(); - - // Test email address with only letters - emailField.sendKeys(browser.params.login.pwweak); - validateInvalid(); - - // Test email address with only numbers - emailField.sendKeys(browser.params.login.nums); - validateInvalid(); - - // Test email address with only special characters - emailField.sendKeys(browser.params.login.chars); - validateInvalid(); - - }); - - it('should test unsuccessful login, invalid UID', function() { - - // Clear log in text fields - clearLoginFields(); - - // Enter bogus wallet identifier and password - loginUIDField.sendKeys(browser.params.login.uidfake); - loginPasswordField.sendKeys(login.pw); - - // Submit and validate error messaging - loginButton.click(); - // TODO This element isn't being found - //util.shouldContainCSS('alert.ng-isolate-scope.alert-danger.alert-dismissable', 'This wallet is not associated with a beta invite key.'); - - }); - - it('should test unsuccessful login, invalid password', function() { - - // Clear log in text fields - clearLoginFields(); - - // Enter valid wallet identifier and incorrect password - loginUIDField.sendKeys(login.uid); - loginPasswordField.sendKeys(browser.params.login.pwweak); - - // Submit and validate error messaging - loginButton.click(); - browser.sleep(3000); - util.shouldContainCSS('.help-block', 'Error Decrypting Wallet. Please check your password is correct.'); - - }); - -}); diff --git a/e2e-tests/security-center/block_tor_spec.js b/e2e-tests/security-center/block_tor_spec.js deleted file mode 100644 index 6ca9065923..0000000000 --- a/e2e-tests/security-center/block_tor_spec.js +++ /dev/null @@ -1,48 +0,0 @@ -describe('block-tor', function() { - // Required JS files - var login = require('../ignore.js'); - var util = require('../util.js'); - - - beforeEach(function() { - util.getURL(); - util.logIn(); - util.navigateTo("SECURITY"); - browser.sleep(4000); - browser.findElement(by.cssContainingText('.ng-binding', 'Tor Blocked')).isDisplayed().then(function(result) { - if (result) { - util.navigateTo("SETTINGS"); - util.navigateTo("ADVANCED"); - browser.sleep(1000);//wait for animation - browser.findElement(by.css('[translate="DISABLE_BLOCK_TOR"]')).click(); - browser.findElement(by.css('[translate="HOME"]')).click(); - util.navigateTo("SECURITY"); - } - else { - util.navigateTo("SECURITY"); - } - }); - }); - - afterEach(function() { - - browser.refresh(); - - }); - - it('should be able to block tor', function() { - - - browser.findElement(by.css('[translate="ADD_BLOCK_TOR"]')).click(); - browser.findElement(by.css('[translate="BLOCK_TOR_EXPLAIN"]')) - - //enable the button - browser.findElement(by.css('[ng-click="enableBlockTOR()"]')).click(); - - //wait for animation to complete - browser.sleep(2000); - browser.findElement(by.cssContainingText('.ng-binding', 'Tor Blocked')) - }); - -}); - diff --git a/e2e-tests/settings/accounts_spec.js b/e2e-tests/settings/accounts_spec.js deleted file mode 100755 index ae6888f15a..0000000000 --- a/e2e-tests/settings/accounts_spec.js +++ /dev/null @@ -1,35 +0,0 @@ -describe('accounts-page', function() { - - // Required JS files - var login = require('../ignore.js'); - var util = require('../util.js'); - - - beforeEach(function() { - - util.getURL(); - util.logIn(); - util.validateHome(); - - // Navigate to Settings and validate page - browser.findElement(by.css('[translate="SETTINGS"]')).click(); - browser.findElement(by.css('[translate="WALLET_SETTINGS_EXPLAIN"]')); - - // Navigate to Wallet Settings and validate page - browser.findElement(by.css('[translate="MY_ACCOUNTS"]')).click(); - browser.findElement(by.css('[translate="ACCOUNT_MANAGEMENT_EXPLAIN"]')); - - }); - - afterEach(function() { - - // Refresh to begin test on login page - browser.refresh(); - - }); - - xit('should have page elements', function() { - - }); - -}); \ No newline at end of file diff --git a/e2e-tests/settings/advanced_spec.js b/e2e-tests/settings/advanced_spec.js deleted file mode 100755 index 31446fa5e7..0000000000 --- a/e2e-tests/settings/advanced_spec.js +++ /dev/null @@ -1,35 +0,0 @@ -describe('advanced-page', function() { - - // Required JS files - var login = require('../ignore.js'); - var util = require('../util.js'); - - - beforeEach(function() { - - util.getURL(); - util.logIn(); - util.validateHome(); - - // Navigate to Settings and validate page - browser.findElement(by.css('[translate="SETTINGS"]')).click(); - browser.findElement(by.css('[translate="WALLET_SETTINGS_EXPLAIN"]')); - - // Navigate to Wallet Settings and validate page - browser.findElement(by.css('[translate="ADVANCED"]')).click(); - browser.findElement(by.css('[translate="ADVANCED_EXPLAIN"]')); - - }); - - afterEach(function() { - - // Refresh to begin test on login page - browser.refresh(); - - }); - - xit('should have page elements', function() { - - }); - -}); \ No newline at end of file diff --git a/e2e-tests/settings/my_addresses_spec.js b/e2e-tests/settings/my_addresses_spec.js deleted file mode 100755 index af08e6e9cd..0000000000 --- a/e2e-tests/settings/my_addresses_spec.js +++ /dev/null @@ -1,35 +0,0 @@ -describe('my-addresses-page', function() { - - // Required JS files - var login = require('../ignore.js'); - var util = require('../util.js'); - - - beforeEach(function() { - - util.getURL(); - util.logIn(); - util.validateHome(); - - // Navigate to Settings and validate page - browser.findElement(by.css('[translate="SETTINGS"]')).click(); - browser.findElement(by.css('[translate="WALLET_SETTINGS_EXPLAIN"]')); - - // Navigate to Wallet Settings and validate page - browser.findElement(by.css('[translate="MY_ADDRESSES"]')).click(); - browser.findElement(by.css('[translate="MY_ADDRESSES_EXPLAIN"]')); - - }); - - afterEach(function() { - - // Refresh to begin test on login page - browser.refresh(); - - }); - - xit('should have page elements', function() { - - }); - -}); diff --git a/e2e-tests/settings/my_details_spec.js b/e2e-tests/settings/my_details_spec.js deleted file mode 100755 index 03075e0e5d..0000000000 --- a/e2e-tests/settings/my_details_spec.js +++ /dev/null @@ -1,97 +0,0 @@ -describe('my-details-page', function() { - - // Required JS files - var login = require('../ignore.js'); - var util = require('../util.js'); - - // My Details specific variables - var passwordHintCSS = '[translate="PASSWORD_HINT"]'; - - beforeEach(function() { - - util.getURL(); - util.logIn(); - util.validateHome(); - - // Navigate to Settings and validate page - browser.findElement(by.css('[translate="SETTINGS"]')).click(); - browser.findElement(by.css('[translate="WALLET_SETTINGS_EXPLAIN"]')); - - // Navigate to My Details and validate page - browser.findElement(by.css('[translate="PREFERENCES"]')).click(); - - // Click is to bring focus to scrollable portion of page - browser.findElement(by.css('[translate="PREFERENCES_EXPLAIN"]')).click(); - - }); - - afterEach(function() { - - // Refresh to begin test on login page - browser.refresh(); - - }); - - - it('should have wallet password elements', function() { - - // Scroll to password hint section - util.scrollTo(passwordHintCSS); - - - // Validate password elements - browser.findElement(by.css('[translate="WALLET_PASSWORD"]')); - browser.findElement(by.css('[translate="WALLET_PASSWORD_EXPLAIN"]')); - browser.findElement(by.css('[translate="PASSWORD_SET"]')); - - }); - - it('should have a wallet password modal', function() { - - // Scroll to password hint section - util.scrollTo(passwordHintCSS); - - // Click Change Button - browser.findElement(by.css('[translate="CHANGE"]')).click(); - - // Validate modal open - browser.findElement(by.css('.modal-content')); - - // Validate modal elements - browser.findElement(by.css('[translate="CURRENT_PASSWORD"]')); - browser.findElement(by.css('[translate="NEW_PASSWORD"]')); - browser.findElement(by.css('[translate="CONFIRM_PASSWORD"]')); - - }); - - it('should change the wallet password hint', function() { - - // Bring focus to scrollable portion - browser.findElement(by.css('[translate="UID"]')).click(); - - // Validate password hint elements - browser.findElement(by.css(passwordHintCSS)); - browser.findElement(by.css('[translate="PASSWORD_HINT_EXPLAIN"]')); - - // Scroll to password hint section - util.scrollTo(passwordHintCSS); - - // Set new password hint - browser.element(by.css('[ng-model="user.passwordHint"]')).element(by.css('[ng-click="edit()"]')).click(); - browser.element(by.css('[ng-model="user.passwordHint"]')).element(by.css('[ng-model="form.newValue"]')).clear(); - browser.element(by.css('[ng-model="user.passwordHint"]')).element(by.css('[ng-model="form.newValue"]')).sendKeys('new password hint'); - browser.element(by.css('[ng-model="user.passwordHint"]')).element(by.css('[type="submit"]')).click(); - browser.sleep(1000); - util.shouldContainCSS('h2.status', 'new password hint'); - - // Reset old password hint - browser.element(by.css('[ng-model="user.passwordHint"]')).element(by.css('[ng-click="edit()"]')).click(); - browser.element(by.css('[ng-model="user.passwordHint"]')).element(by.css('[ng-model="form.newValue"]')).clear(); - browser.element(by.css('[ng-model="user.passwordHint"]')).element(by.css('[ng-model="form.newValue"]')).sendKeys('original password hint'); - browser.element(by.css('[ng-model="user.passwordHint"]')).element(by.css('[type="submit"]')).click(); - browser.sleep(1000); - util.shouldContainCSS('h2.status', 'original password hint'); - - }); - -}); diff --git a/e2e-tests/settings/wallet_recovery_spec.js b/e2e-tests/settings/wallet_recovery_spec.js deleted file mode 100755 index e472b14a31..0000000000 --- a/e2e-tests/settings/wallet_recovery_spec.js +++ /dev/null @@ -1,35 +0,0 @@ -describe('wallet-recovery-page', function() { - - // Required JS files - var login = require('../ignore.js'); - var util = require('../util.js'); - - - beforeEach(function() { - - util.getURL(); - util.logIn(); - util.validateHome(); - - // Navigate to Settings and validate page - browser.findElement(by.css('[translate="SETTINGS"]')).click(); - browser.findElement(by.css('[translate="WALLET_SETTINGS_EXPLAIN"]')); - - // Navigate to Wallet Settings and validate page - browser.findElement(by.css('[translate="WALLET_RECOVERY"]')).click(); - browser.findElement(by.css('[translate="WALLET_RECOVERY_EXPLAIN"]')); - - }); - - afterEach(function() { - - // Refresh to begin test on login page - browser.refresh(); - - }); - - xit('should have page elements', function() { - - }); - -}); \ No newline at end of file diff --git a/e2e-tests/settings/wallet_settings_spec.js b/e2e-tests/settings/wallet_settings_spec.js deleted file mode 100755 index 32e1e077e9..0000000000 --- a/e2e-tests/settings/wallet_settings_spec.js +++ /dev/null @@ -1,42 +0,0 @@ -describe('wallet-settings-page', function() { - - // Required JS files - var login = require('../ignore.js'); - var util = require('../util.js'); - - - beforeEach(function() { - - util.getURL(); - util.logIn(); - util.validateHome(); - - // Navigate to Settings and validate page - browser.findElement(by.css('[translate="SETTINGS"]')).click(); - browser.findElement(by.css('[translate="WALLET_SETTINGS_EXPLAIN"]')).click(); - - }); - - afterEach(function() { - - // Refresh to begin test on login page - browser.refresh(); - - }); - - it('should validate wallet language elements', function() { - - browser.findElement(by.css('[translate="LANGUAGE"]')); - browser.findElement(by.css('[translate="LANGUAGE_EXPLAIN"]')); - browser.findElement(by.css('[language="settings.language"]')); - - }); - - it('should change language settings', function() { - - browser.findElement(by.css('[language="settings.language"]')).findElement(by.css('.ui-select-toggle')).click(); - - - }); - -}); diff --git a/e2e-tests/transactions/transactions_spec.js b/e2e-tests/transactions/transactions_spec.js deleted file mode 100755 index 2da8880c27..0000000000 --- a/e2e-tests/transactions/transactions_spec.js +++ /dev/null @@ -1,188 +0,0 @@ -describe('transactions-page', function() { - - // Required JS files - var login = require('../ignore.js'); - var util = require('../util.js'); - - // Account name variables - var account1Name = 'DONT EDIT 1'; - var account2Name = 'DONT EDIT 2'; - var account3Name = 'DONT EDIT 3'; - var account4Name = 'Spending'; - - // Account transaction value variables - var account1TransValue = '0.00087847 BTC'; - var account1TransValueTx = '0.00077847 BTC'; - var account3TransValue = '0.00042116 BTC'; - var account3TransLocationPage = 'h1.ng-binding'; - - // Account date variables - var account1TransDate = 'April 7 @ 03:51 PM'; - var account3TransDate = 'February 18 @ 06:56 PM'; - - - beforeEach(function() { - - util.getURL(); - util.logIn(); - util.validateHome(); - - }); - - afterEach(function() { - - // Refresh to begin test on login page - browser.refresh(); - - }); - - it('should log out via the "Log Out" button', function() { - - // Open Profile drop down menu, click Logout, and dismiss alert - util.logOut(); - - // Protractor waits 5 seconds until 'Logged Out' message dismisses - - // Find UID label and text field - browser.sleep(4000); //Required wait for UID field - browser.findElement(by.css('[translate="UID"]')); - browser.findElement(by.model('uid')); - - // Find password label and text field - browser.findElement(by.css('[translate="PASSWORD"]')); - browser.findElement(by.model('password')); - - // Find login and create wallet buttons - browser.findElement(by.id('login')); - browser.findElement(by.css('[ng-click="register()"]')); - - }); - - it('should validate account names and balances', function() { - - // Open Transactions drawer in left navigation - browser.findElement(by.css('[translate="MY_TRANSACTIONS"]')).click(); - - // Validate all account names - browser.findElement(by.css('[translate="ALL_ACCOUNTS"]')); - util.shouldContainCSS('[ng-repeat="account in accounts()"]', account1Name); - util.shouldContainCSS('[ng-repeat="account in accounts()"]', account2Name); - util.shouldContainCSS('[ng-repeat="account in accounts()"]', account3Name); - util.shouldContainCSS('[ng-repeat="account in accounts()"]', account4Name); - - // Validate two account balances - util.shouldContainCSS('[ng-repeat="account in accounts()"]', account1TransValue); - util.shouldContainCSS('[ng-repeat="account in accounts()"]', account3TransValue); - - }); - - it('should show account balance and transaction history when selecting account name', function() { - - // Open Transactions drawer in left navigation - browser.findElement(by.css('[translate="MY_TRANSACTIONS"]')).click(); - - // Click on 4th account and validate value and date - browser.element.all(by.repeater('account in accounts()')).get(3).click(); - util.shouldContainCSS(account3TransLocationPage, account3TransValue); - util.shouldContainCSS('date', account3TransDate); - - }); - - it('should show transaction details when clicking on date/time of transaction', function() { - - // Open Transactions drawer in left navigation - browser.findElement(by.css('[translate="MY_TRANSACTIONS"]')).click(); - - // Click on 4th account and validate value and date - browser.element.all(by.repeater('account in accounts()')).get(3).click() - browser.sleep(500); // Resolves test from failing intermittently - util.shouldContainCSS(account3TransLocationPage, account3TransValue); - browser.findElement(by.cssContainingText('date', account3TransDate)).click(); - - // Validate transaction details page - browser.sleep(500); // Required for next steps to pass in Chrome - browser.findElement(by.css('[translate="BACK_TO_FEED"]')); - browser.findElement(by.css('[translate="TRANSACTION_DETAILS"]')); - browser.findElement(by.css('[translate="FROM"]')); - browser.findElement(by.css('[translate="TO"]')); - browser.findElement(by.css('[translate="NOTES"]')); - browser.findElement(by.css('[translate="TRANSACTION_COMPLETE"]')); - browser.findElement(by.css('[translate="VALUE_AT_SEND"]')); - util.shouldContainCSS('[btc="transaction.result"]', '$0.10'); - browser.findElement(by.css('[translate="VALUE_NOW"]')); - browser.findElement(by.css('[translate="VERIFY_ON_BCI"]')); - - }); - - it('should return to account balance and transaction history from transaction details', function() { - - // Open Transactions drawer in left navigation - browser.findElement(by.css('[translate="MY_TRANSACTIONS"]')).click(); - - // Click on 4th account in list and view transaction details - browser.element.all(by.repeater('account in accounts()')).get(3).click(); - browser.element.all(by.repeater("transaction in transactions | filter:transactionFilter | orderBy:'-txTime'")).get(0).click(); - - // Return to account details and validate Request/Send buttons - browser.findElement(by.css('h4.back')).click(); - browser.findElement(by.css('[translate="REQUEST"]')); - browser.findElement(by.css('[translate="SEND"]')); - - }); - - it('should show transacted bitcoin address for each listed transaction', function() { - - // Open Transactions drawer in left navigation - browser.findElement(by.css('[translate="MY_TRANSACTIONS"]')).click(); - - // Click on account 'DONT EDIT 1' and validate transaction date - browser.element.all(by.repeater('account in accounts()')).get(1).click(); - browser.sleep(500); - util.shouldContainCSS('date.ng-binding', account1TransDate); - - // Validate address labels within account details - util.shouldContainCSS('.ng-binding', '1FV6M8WSJLRKECvGzXwVZyfRgdVHxZmjrX'); - util.shouldContainCSS('.ng-binding', '1DPrsgPctXtgN1GQcshPJhwEYr7xykWpVJ'); - util.shouldContainCSS('.ng-binding', '1H5Me956D9N39tbq8hFBJiBc6dJbRaAmxe'); - - }); - - it('should auto populate account name on Send/Receive modal', function() { - - // Open Transactions drawer in left navigation - browser.findElement(by.css('[translate="MY_TRANSACTIONS"]')).click(); - - // Click on account 'DONT EDIT 1' and validate transaction date - browser.element.all(by.repeater('account in accounts()')).get(1).click(); - browser.findElement(by.css('[translate="SEND"]')).click(); - - // Validate Send modal details - browser.findElement(by.css('[translate="FROM:"]')); - util.shouldContainCSS('span.ng-binding.ng-scope', account1TransValueTx); - - // Close Send modal, wait for and click Request button - browser.findElement(by.css('[ng-click="close()"]')).click(); - expect(element(by.css('[ng-click="request()"]')).isPresent()).toBe(true); - browser.findElement(by.css('[translate="REQUEST"]')).click(); - - // Validate Receive modal details - browser.findElement(by.css('[translate="RECEIVE_TO"]')); - util.shouldContainCSS('span.ng-binding.ng-scope', account1Name); - browser.findElement(by.css('[ng-click="close()"]')).click(); - - }); - - it('should filter by transaction type', function() { - - util.navigateTo("MY_TRANSACTIONS"); - element.all(by.css('.filter-bar')).all(by.css('[translate="SENT"]')).click(); - browser.sleep(1000); - expect(element.all(by.css('.transaction-feed')).all(by.css('[translate="RECEIVED_BITCOIN_FROM"]')).count()).toEqual(0); - - - element.all(by.css('.filter-bar')).all(by.css('[translate="RECEIVED_BITCOIN_FROM"]')).click(); - expect(element.all(by.css('.transaction-feed')).all(by.css('[translate="MOVE_BITCOIN_TO"]')).count()).toEqual(0); - - }); - -}); diff --git a/e2e-tests/util.js b/e2e-tests/util.js deleted file mode 100644 index bb76ad4403..0000000000 --- a/e2e-tests/util.js +++ /dev/null @@ -1,115 +0,0 @@ -var login = require('./ignore.js'); - -module.exports = { - - getURL: function() { - - // Visit URL and validate page title - // Use ONE of the following two lines to enable tests on staging versus localhost. - browser.driver.get('https://dev.blockchain.info/#/login'); // Dev server - //browser.driver.get('https://staging.blockchain.info/#/login'); // Staging server - //browser.driver.get('https://alpha.blockchain.info/#/login'); // Alpha server - //browser.driver.get('http://local.blockchain.com:8080/#/login'); // Localhost - - expect(browser.getTitle()).toEqual('Blockchain Wallet HD'); - - }, - - logIn: function() { - - // Clear login text fields - element(by.model('uid')).clear(); - element(by.model('password')).clear(); - - // Fill text fields with login credentials, submit - element(by.model('uid')).sendKeys(login.uid); - element(by.model('password')).sendKeys(login.pw); - element(by.id('login')).click(); - - }, - - logOut: function () { - - // Open Profile drop down menu, click Logout, and dismiss alert - element.all(by.css('[ng-click="logout()"]')).first().click(); - browser.sleep(200); - browser.switchTo().alert().accept(); - - }, - - validateHome: function () { - - // Validate account homepage details - browser.sleep(3000); // Required wait for Request and Send button validation - browser.findElement(by.css('[translate="REQUEST"]')); - browser.findElement(by.css('[translate="SEND"]')); - browser.findElement(by.css('.bc-well')); - - }, - - navigateTo: function(section) { - browser.sleep(2000); - browser.findElement(by.css('[translate="' + section + '"]')).click(); - }, - - submitBetaKey: function () { - - var promise = browser.getCurrentUrl(); - promise.then(function(currentURL) { - - // Is this still valid for localhost? - if (currentURL == 'http://local.blockchain.com:8080/#/login') { - console.log('URL is local.blockchain.com:8080'); - - // Click Create Wallet button - browser.findElement(by.css('[translate="CREATE_WALLET"]')).click(); - - } - - else if (currentURL == 'https://dev.blockchain.info/#/login') { - console.log('URL is dev.blockchain.info'); - - // Click invite key link - browser.findElement(by.css('[ng-click="prepareRegister()"]')).click(); - - // Enter beta key and click Create Wallet button - element(by.css('[ng-model="key"]')).sendKeys(login.betaKey); - browser.findElement(by.css('[ng-click="register()"]')).click(); - - } - - else if (currentURL == 'https://alpha.blockchain.info/#/login') { - console.log('URL is dev.blockchain.info'); - - // Click invite key link - browser.findElement(by.css('[ng-click="status.enterkey = !status.enterkey"]')).click(); - - // Enter beta key and click Create Wallet button - element(by.css('[ng-model="key"]')).sendKeys(login.betaKey); - browser.findElement(by.css('[ng-click="register()"]')).click(); - - } - - else { - console.log('Unable to determine server instance') - - } - }) - - }, - - shouldContainCSS: function (selector, text) { - - browser.findElement(by.cssContainingText(selector, text)); - - }, - - scrollTo: function (selector) { - var filter = browser.findElement(by.css(selector)); - var scrollIntoView = function () { - arguments[0].scrollIntoView(); - }; - browser.executeScript(scrollIntoView, filter); - } - -} diff --git a/karma.conf.js b/karma.conf.js index e1e760cda9..fa3d3646b4 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -112,11 +112,6 @@ module.exports = function(karma){ browsers : ['PhantomJS'], - junitReporter : { - outputFile: 'test_out/unit.xml', - suite: 'unit' - }, - reporters: ['progress','osx', 'coverage'], coverageReporter: { diff --git a/package.json b/package.json index 6a4b2df320..41e1c9a189 100644 --- a/package.json +++ b/package.json @@ -4,22 +4,12 @@ "version": "0.0.0", "description": "AngularJS front-end to My-Wallet-V3.", "dependencies": { - "basic-auth": "^1.0.3", - "body-parser": "^1.14.1", - "compression": "^1.6.0", - "errorhandler": "^1.4.2", - "express": "^4.13.3", - "method-override": "^2.3.5", - "morgan": "^1.6.1", - "request": "^2.55.0" }, "devDependencies": { + "express": "^4.13.3", "bower": "^1.3.1", - "chalk": "^0.5.1", "coffee-script": "^1.9.1", - "compression": "^1.3.0", "ejs": "~0.8.4", - "get-stdin": "^3.0.0", "git-changelog": "^0.1.8", "grunt": "^0.4.5", "grunt-autoprefixer": "^3.0.0", @@ -48,29 +38,15 @@ "jade": "*", "karma": "^0.12.16", "karma-babel-preprocessor": "^5.2.2", - "karma-chrome-launcher": "^0.2.0", "karma-coffee-preprocessor": "^0.2.1", "karma-coverage": "^0.5.1", "karma-jade-preprocessor": "0.0.11", "karma-jasmine": "^0.2.0", - "karma-junit-reporter": "^0.2.2", "karma-ng-jade2js-preprocessor": "^0.1.5", "karma-osx-reporter": "^0.1.0", "karma-phantomjs-launcher": "^0.1.4", - "mkdir": "0.0.2", - "mkdirp": "^0.5.0", - "mocha": "^1.21.5", - "nan": "^1.3.0", "node-env-file": "^0.1.4", - "node-watch": "^0.3.4", - "nodemon": "^1.8.1", - "object-assign": "^1.0.0", - "protractor": "~1.0.0", - "shelljs": "^0.3.0", - "sinon": "^1.10.3", - "spies": "^0.1.6", - "tmp": "0.0.23", - "yargs": "^1.3.2" + "shelljs": "^0.3.0" }, "scripts": { "postinstall": "node_modules/bower/bin/bower install", @@ -85,7 +61,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/blockchain/My-Wallet-HD-Frontend" + "url": "https://github.com/blockchain/My-Wallet-V3-Frontend" }, "keywords": [ "blockchain" diff --git a/server.js b/server.js index 1eae668bc5..b32da1d740 100644 --- a/server.js +++ b/server.js @@ -1,40 +1,19 @@ 'use strict'; var express = require('express') - , compression = require('compression') - , bodyParser = require('body-parser') - , morgan = require('morgan') - , errorhandler = require('errorhandler') - , methodOverride = require('method-override') , ejs = require('ejs') - , auth = require('basic-auth') - , request = require('request') , path = require('path') - , fs = require('fs'); loadEnv('.env'); var port = process.env.PORT || 8080 , dist = parseInt(process.env.DIST) === 1 - , beta = parseInt(process.env.BETA) === 1 , origins = (process.env.BLOCKCHAIN || '').split(' ') , whitelist = (process.env.IP_WHITELIST || '').split(' ') - , admin = { user: 'blockchain', pass: process.env.ADMIN_PASSWORD }; // App configuration var app = express(); -app.use(morgan('combined')); -app.use(bodyParser.json()); -app.use(compression({ - threshold: 512 -})); - -app.use(errorhandler({ - dumpExceptions: true, - showStack: true -})); - app.use(function (req, res, next) { if (req.url === '/') { var cspHeader = ([ @@ -54,8 +33,6 @@ app.use(function (req, res, next) { if (whitelist != '' && whitelist.indexOf(ip.split(', ')[0]) < 0) { console.log(ip); res.status(403).send('I\'m sorry Dave, I can\'t let you do that.'); - } else if (dist && beta) { - res.render('index-beta.html'); } else if (dist) { res.render('index.html'); } else { @@ -64,9 +41,7 @@ app.use(function (req, res, next) { return; } - if (req.url.indexOf('beta_key')) { - res.setHeader('Cache-Control', 'public, max-age=0, no-cache'); - } else if (dist) { + if (dist) { res.setHeader('Cache-Control', 'public, max-age=31557600'); } else { res.setHeader('Cache-Control', 'public, max-age=0, no-cache'); @@ -81,271 +56,11 @@ if (dist) { app.set('views', path.join(__dirname, 'dist')); } else { console.log('Development mode: multiple javascript files, not cached'); - app.use(methodOverride()); app.use(express.static(__dirname)); app.set('view engine', 'jade'); app.set('views', __dirname); } -// Routing -if (beta) { - // Beta system enabled - console.log('Enabling beta invite system'); - var v3Beta = require('my-wallet-v3-beta-module')(path.join(__dirname, process.env.BETA_DATABASE_PATH || '')); - - app.get(/^\/key-.{8}$/, function (req, res) { - var key = req.path.split(path.sep)[1].split('-')[1]; - v3Beta.emailLinkFollowed({key:key}); - res.cookie('key', '"' + key + '"'); - res.redirect('/'); - }); - - // *.blockchain.info/logo-key-{key} redirects to image on Amazon - app.get(/^\/key-logo-.{8}$/, function (req, res) { - var key = req.path.split(path.sep)[1].split('-')[2]; - v3Beta.emailOpened({key:key}); - res.redirect('https://s3.amazonaws.com/blockchainwallet/bc-logo-family.png'); - }); - - app.post('/check_beta', function (req, res) { - v3Beta.verifyLimit(function (err, open) { - if (err) res.json({ open: false, error: {message: err} }); - else res.json({ open: open }); - }); - }); - - app.post('/verify_wallet_created', function (req, res) { - v3Beta.verifyLimit(function (err, open) { - if (err) res.json({ success: false, error: {message: err} }); - else res.json({ success: open }); - }); - }); - - app.post('/check_guid_for_beta_key', function (req, res) { - v3Beta.isGuidAssociatedWithBetaKey(req.body.guid, function (err, verified) { - if (err) { - res.json({ - verified: false, - error: { - message: 'There was a problem verifying your access permission. Please try again later.', - err: err - } - }); - } else if (verified) { - res.json({ verified: true }); - } else { - res.json({ - verified: false, - error: { message: 'Please create a new Alpha wallet first.' } - }); - } - }); - }); - - app.post('/register_guid', function (req, res) { - v3Beta.verifyLimit(function (err, open) { - if (err) { - res.json({ success: false, error: {message: err} }); - } else { - v3Beta.assignKey('', req.body.email, req.body.guid, function (key) { - v3Beta.newWalletCreated(key, function () { - res.json({ success: true }); - }); - }); - } - }); - }); - - app.post('/whitelist_guid', function (req, res) { - if (req.body == null) { - res.json({ error: 'no request body' }); - } else if (req.body.secret !== process.env.WHITELIST_SECRET) { - res.json({ error: 'incorrect secret' }); - } else if (req.body.guid == null) { - res.json({ error: 'missing request body guid parameter' }); - } else { - var name = req.body.name || 'Mobile Tester'; - v3Beta.assignKey(name, req.body.email, req.body.guid, function (err, key) { - res.json({ - error: err, - key: key - }); - }); - } - }); - - app.get('/admin/?', authenticate(admin), function (req, res) { - var adminIndex = dist ? 'admin.html' : 'app/admin.jade'; - res.render(adminIndex); - }); - - app.get("/admin/api/:method", authenticate(admin), function (req, res) { - switch (req.params.method) { - case 'get-all-keys': - v3Beta.getKeys(function (err, data) { - res.send(JSON.stringify(data)); - }); - break; - case 'get-sorted-keys': - v3Beta.getKeys(req.query, function (err, data) { - res.json({ - error: err, - data: data - }); - }); - break; - case 'assign-key': - v3Beta.assignKey(req.query.name, req.query.email, req.query.guid, function (err, key) { - res.json({ - error: err, - key: key - }); - }); - break; - case 'delete-key': - v3Beta.deleteKey(req.query, function (err) { - res.json({ error: err }); - }); - break; - case 'update-key': - v3Beta.updateKey(req.query.selection, req.query.update, function (err) { - res.json({ error: err }); - }); - break; - case 'activate-key': - v3Beta.activateKey(req.query.selection, req.query.update, function (err, data) { - res.json({ - error: err, - data: data - }); - }); - break; - case 'remind-email': - v3Beta.remindEmail(req.query.key, function (err, data) { - res.json({ - error: err, - data: data - }); - }); - break; - case 'activate-all': - var range = [req.query.min || 0, req.query.max || 100000]; - v3Beta.activateAll(range, function (err, data) { - res.json({ - error: err, - data: data - }); - }); - break; - case 'remind-all': - var range = [req.query.min || 0, req.query.max || 100000]; - v3Beta.remindAll(range, function (err, data) { - res.json({ - error: err, - data: data - }); - }); - break; - case 'resend-activation': - v3Beta.resendActivationEmail(req.query.key, function (err, data) { - res.json({ - error: err, - data: data - }); - }); - break; - case 'resend-many': - var range = [req.query.min || 0, req.query.max || 100000]; - v3Beta.resendMany(range, function (err, data) { - res.json({ - error: err, - data: data - }); - }); - break; - case 'wallets-created': - v3Beta.fetchNumWalletsCreated(function (err, count) { - res.json({ - error: err, - count: count - }); - }); - break; - case 'get-csv': - v3Beta.fetchCSV({}, function (err, csv) { - fs.writeFileSync('tmp.csv', csv); - res.download('tmp.csv', 'emails.csv', function () { - fs.unlink('tmp.csv'); - }); - }); - break; - case 'set-percent-requested': - var percent = parseInt(req.query.percent) - , isNumber = !isNaN(percent); - if (isNumber) process.env.PERCENT_REQUESTED = percent; - res.json({ - success: Boolean(isNumber) - }); - break; - default: - res.status(400).json({ - error: { message: 'Unknown request method' }, - success: false - }); - } - }); -} - -app.get('/verify-email', function (req, res) { - request.get('https://blockchain.info/wallet' + req.originalUrl); - res.cookie('email-verified', true); - res.redirect('/'); -}); - -app.get('/authorize-approve', function (req, res) { - var approveHTML = '\ - \n\ - \n\ - \n\ - \n\ - Verifying authorization request\n\ - \n\ - \n\ - '; - res.send(approveHTML); -}); - -app.post('/feedback', function (req, res) { - var jira = 'https://blockchain.atlassian.net/rest/collectors/1.0/template/feedback/e6ce4d72' - , headers = { 'X-Atlassian-Token': 'nocheck' }; - request.post({ - url: jira, - headers: headers, - form: req.body - }, function (err, httpResponse, body) { - res.json({ success: !(err != null) }); - }); -}); - -app.get('/unsubscribe', function (req, res) { - request.get('https://blockchain.info/wallet' + req.originalUrl); - res.redirect('/'); -}); - -app.get(/^\/.{8}-.{4}-.{4}-.{4}-.{12}$/, function (req, res) { - res.cookie('uid', '"' + req.path.split(path.sep)[1] + '"'); - res.redirect('/'); -}); - app.use(function (req, res) { res.send('

404 Not Found

'); }); @@ -366,20 +81,6 @@ function allowOrigins(origins) { }; } -function authenticate(options) { - return function (req, res, next) { - var credentials = auth(req) - , authorized = credentials && - credentials.name === options.user && - credentials.pass === options.pass; - authorized ? next() : issueChallenge(); - function issueChallenge() { - res.setHeader('WWW-Authenticate', 'Basic realm="blockchain-wallet-v3"'); - res.sendStatus(401); - } - }; -} - // Helper functions function loadEnv(envFile) { try { diff --git a/tests/controllers/signup_controller_spec.coffee b/tests/controllers/signup_controller_spec.coffee index 572777ea27..93b0ac4e87 100644 --- a/tests/controllers/signup_controller_spec.coffee +++ b/tests/controllers/signup_controller_spec.coffee @@ -9,15 +9,14 @@ describe "SignupCtrl", -> beforeEach -> angular.mock.inject ($injector, $rootScope, $controller) -> Wallet = $injector.get("Wallet") - MyWallet = $injector.get("MyWallet") - - MyWallet.createNewWallet = (email, pass, translation, lang, currency, success, error) -> success() - MyWallet.isValidateBIP39Mnemonic = () -> true Wallet.login = (uid, pass, code, twoFactor, success, error) -> success() + Wallet.create = (password, email, currency, language, success) -> success("new_guid") + Wallet.settings_api = + change_language: (code, success) -> success() + change_local_currency: () -> + Wallet.changeCurrency = () -> - Wallet.settings_api.change_language = (-> ) - Wallet.settings_api.change_local_currency = (-> ) scope = $rootScope.$new() @@ -26,12 +25,6 @@ describe "SignupCtrl", -> $stateParams: {}, $uibModalInstance: modalInstance - scope.isValid = [false, false] - scope.fields.email = "a@b.com" - scope.fields.password = "testing" - scope.fields.confirmation = "testing" - scope.fields.acceptedAgreement = true - scope.form = {$error: {email: null}} scope.validate() return @@ -44,101 +37,152 @@ describe "SignupCtrl", -> expect(Alerts.clear).toHaveBeenCalled() ) - describe "first step", -> - it "should be step 1", -> - expect(scope.currentStep).toBe(1) + it "should have initial values", -> + expect(scope.fields.email).toBeDefined() + expect(scope.fields.password).toBeDefined() + expect(scope.fields.confirmation).toBeDefined() + expect(scope.fields.acceptedAgreement).toBe(false) + + describe "password", -> + beforeEach -> + scope.fields.acceptedAgreement = true + scope.fields.email = "a@b.com" + + it "should not display an error if password confirmation matches", -> + scope.fields.password = "testing" + scope.fields.confirmation = "testing" + + scope.validate() - it "should go to second step", -> - scope.nextStep() - expect(scope.currentStep).toBe(2) + expect(scope.isValid).toBe(true) + expect(scope.errors.confirmation).toBeNull() it "should not display an error if password is still empty", -> - scope.fields.currentPassword = "test" scope.fields.password = "" scope.validate() - expect(scope.isValid[0]).toBe(false) + expect(scope.isValid).toBe(false) expect(scope.errors.password).toBeNull() - # it "should display an error if password is too short", -> - # scope.fields.currentPassword = "test" - # scope.fields.password = "1" - # scope.validate() - # expect(scope.isValid[0]).toBe(false) - # expect(scope.errors.password).not.toBeNull() - it "should not display an error if password confirmation is still empty", -> - scope.fields.currentPassword = "test" scope.fields.password = "testing" scope.fields.confirmation = "" scope.validate() - expect(scope.isValid[0]).toBe(false) + expect(scope.isValid).toBe(false) expect(scope.errors.confirmation).toBeNull() - it "should not display an error if password confirmation matches", -> - scope.fields.currentPassword = "test" + it "should display an error if password confirmation does not match", -> scope.fields.password = "testing" - scope.fields.confirmation = "testing" + scope.fields.confirmation = "wrong" scope.validate() - expect(scope.isValid[0]).toBe(true) - expect(scope.errors.confirmation).toBeNull() + expect(scope.isValid).toBe(false) + expect(scope.errors.confirmation).not.toBeNull() - it "should display an error if password confirmation does not match", -> - scope.fields.currentPassword = "test" - scope.fields.password = "testing" - scope.fields.confirmation = "wrong" + describe "agreement", -> + beforeEach -> + scope.fields.email = "a@b.com" + scope.fields.password = "1234" + scope.fields.confirmation = "1234" + + it "should not be signed by default", -> + expect(scope.fields.acceptedAgreement).toBe(false) + + it "should be signed by the user to register", -> + expect(scope.isValid).toBe(false) + scope.fields.acceptedAgreement = true scope.validate() + expect(scope.isValid).toBe(true) - expect(scope.isValid[0]).toBe(false) - expect(scope.errors.confirmation).not.toBeNull() + it "should not register when invalid", -> + scope.fields.password = "" # invalid + scope.validate() + spyOn(scope, "signup") + scope.trySignup() + expect(scope.signup).not.toHaveBeenCalled() - it "should not go to second step is invalid", -> - scope.fields.password = "" # invalid - scope.nextStep() - expect(scope.currentStep).toBe(1) - - describe "wallet creation", -> - - it "should create a new wallet", (done) -> - inject((MyWallet) -> - spyOn(MyWallet, 'createNewWallet') - scope.createWallet (-> ) - expect(MyWallet.createNewWallet).toHaveBeenCalled() - done() - ) - - it "should add uid to cookieStore", (done) -> - inject(($cookieStore) -> - spyOn($cookieStore, 'put') - scope.createWallet (uid) -> - expect($cookieStore.put).toHaveBeenCalledWith('uid', uid) - done() - ) - - describe "second step", -> + describe "signup()", -> + shouldBeValid = true beforeEach -> - scope.currentStep = 2 + spyOn(scope, "validate").and.callFake(() -> + scope.isValid = shouldBeValid # Side-effect + shouldBeValid + ) + - it "should have a list of languages", -> - expect(scope.languages.length).toBeGreaterThan(1) + it "should validate once more", -> + scope.signup() + expect(scope.validate).toHaveBeenCalled() - it "should have a list of currencies", -> - expect(scope.currencies.length).toBeGreaterThan(1) + # Check the test is configured correctly: + expect(scope.isValid).toBe(true) + it "should call createWallet()", -> + spyOn(scope, "createWallet") + scope.signup() + expect(scope.createWallet).toHaveBeenCalled() + + it "should not call createWallet() if validation failed", -> + spyOn(scope, "createWallet") + shouldBeValid = false + scope.signup() + expect(scope.createWallet).not.toHaveBeenCalled() + shouldBeValid = true # Sorry... + + + it "should create a new wallet", inject((Wallet) -> + spyOn(Wallet, 'create') + scope.createWallet (-> ) + expect(Wallet.create).toHaveBeenCalled() + ) + + it "should add uid to cookieStore", inject(($cookieStore) -> + spyOn($cookieStore, 'put') + scope.signup() + expect($cookieStore.put).toHaveBeenCalledWith('uid', "new_guid") + ) + + it "should add password to cookieStore in dev mode", inject(($cookieStore) -> + spyOn($cookieStore, 'put') + scope.savePassword = true + scope.fields.password = "testing" + + scope.signup() + expect($cookieStore.put).toHaveBeenCalledWith('password', "testing") + ) + + it "should not add password to cookieStore in production mode", inject(($cookieStore) -> + spyOn($cookieStore, 'put') + scope.savePassword = false + scope.fields.password = "testing" + + scope.signup() + expect($cookieStore.put).not.toHaveBeenCalledWith('password', "testing") + ) + + describe "language", -> it "should guess the correct language", -> - expect(scope.fields.language.code).toBe("en") + expect(scope.language_guess.code).toBe("en") - it "should switch interface language when new language is selected", inject(($translate) -> + it "should switch interface language to guessed language", inject(($translate, languages) -> spyOn($translate, "use") - expect(scope.fields.language.code).not.toBe(scope.languages[0].code) - scope.fields.language = scope.languages[0] + expect(scope.language_guess.code).not.toBe(languages[0].code) + scope.language_guess = languages[0] scope.$digest() - expect($translate.use).toHaveBeenCalledWith(scope.languages[0].code) + expect($translate.use).toHaveBeenCalledWith(languages[0].code) ) + describe "currency", -> it "should guess the correct currency", -> - expect(scope.fields.currency.code).toBe("USD") + expect(scope.currency_guess.code).toBe("USD") + + it "should switch to the guessed currency", inject((currency, Wallet) -> + spyOn(Wallet, "changeCurrency") + expect(scope.currency_guess.code).not.toBe(currency.currencies[1].code) + scope.currency_guess = currency.currencies[1] + scope.$digest() + expect(Wallet.changeCurrency).toHaveBeenCalledWith(currency.currencies[1]) + )