diff --git a/js/src/mobx/hardwareStore.js b/js/src/mobx/hardwareStore.js
index 65213ad4e..46bf3fa58 100644
--- a/js/src/mobx/hardwareStore.js
+++ b/js/src/mobx/hardwareStore.js
@@ -120,20 +120,22 @@ export default class HardwareStore {
});
}
- createAccountInfo (entry) {
+ createAccountInfo (entry, original = {}) {
const { address, manufacturer, name } = entry;
return Promise
.all([
- this._api.parity.setAccountName(address, name),
- this._api.parity.setAccountMeta(address, {
+ original.name
+ ? Promise.resolve(true)
+ : this._api.parity.setAccountName(address, name),
+ this._api.parity.setAccountMeta(address, Object.assign({
description: `${manufacturer} ${name}`,
hardware: {
manufacturer
},
tags: ['hardware'],
timestamp: Date.now()
- })
+ }, original.meta || {}))
])
.catch((error) => {
console.warn('HardwareStore::createEntry', error);
diff --git a/js/src/mobx/hardwareStore.spec.js b/js/src/mobx/hardwareStore.spec.js
index 14feb5740..784fc3f10 100644
--- a/js/src/mobx/hardwareStore.spec.js
+++ b/js/src/mobx/hardwareStore.spec.js
@@ -130,25 +130,58 @@ describe('mobx/HardwareStore', () => {
describe('operations', () => {
describe('createAccountInfo', () => {
- beforeEach(() => {
- return store.createAccountInfo({
- address: 'testAddr',
- manufacturer: 'testMfg',
- name: 'testName'
+ describe('when not existing', () => {
+ beforeEach(() => {
+ return store.createAccountInfo({
+ address: 'testAddr',
+ manufacturer: 'testMfg',
+ name: 'testName'
+ });
+ });
+
+ it('calls into parity_setAccountName', () => {
+ expect(api.parity.setAccountName).to.have.been.calledWith('testAddr', 'testName');
+ });
+
+ it('calls into parity_setAccountMeta', () => {
+ expect(api.parity.setAccountMeta).to.have.been.calledWith('testAddr', sinon.match({
+ description: 'testMfg testName',
+ hardware: {
+ manufacturer: 'testMfg'
+ },
+ tags: ['hardware']
+ }));
});
});
- it('calls into parity_setAccountName', () => {
- expect(api.parity.setAccountName).to.have.been.calledWith('testAddr', 'testName');
- });
+ describe('when already exists', () => {
+ beforeEach(() => {
+ return store.createAccountInfo({
+ address: 'testAddr',
+ manufacturer: 'testMfg',
+ name: 'testName'
+ }, {
+ name: 'originalName',
+ meta: {
+ description: 'originalDescription',
+ tags: ['tagA', 'tagB']
+ }
+ });
+ });
- it('calls into parity_setAccountMeta', () => {
- expect(api.parity.setAccountMeta).to.have.been.calledWith('testAddr', sinon.match({
- description: 'testMfg testName',
- hardware: {
- manufacturer: 'testMfg'
- }
- }));
+ it('does not call into parity_setAccountName', () => {
+ expect(api.parity.setAccountName).not.to.have.been.called;
+ });
+
+ it('calls into parity_setAccountMeta', () => {
+ expect(api.parity.setAccountMeta).to.have.been.calledWith('testAddr', sinon.match({
+ description: 'originalDescription',
+ hardware: {
+ manufacturer: 'testMfg'
+ },
+ tags: ['tagA', 'tagB']
+ }));
+ });
});
});
diff --git a/js/src/views/Accounts/accounts.js b/js/src/views/Accounts/accounts.js
index 7067e8cb1..107fcc248 100644
--- a/js/src/views/Accounts/accounts.js
+++ b/js/src/views/Accounts/accounts.js
@@ -394,8 +394,12 @@ class Accounts extends Component {
Object
.keys(wallets)
- .filter((address) => !accountsInfo[address])
- .forEach((address) => this.hwstore.createAccountInfo(wallets[address]));
+ .filter((address) => {
+ const account = accountsInfo[address];
+
+ return !account || !account.meta || !account.meta.hardware;
+ })
+ .forEach((address) => this.hwstore.createAccountInfo(wallets[address], accountsInfo[address]));
this.setVisibleAccounts();
}
diff --git a/js/src/views/Accounts/accounts.spec.js b/js/src/views/Accounts/accounts.spec.js
new file mode 100644
index 000000000..7bd798105
--- /dev/null
+++ b/js/src/views/Accounts/accounts.spec.js
@@ -0,0 +1,122 @@
+// Copyright 2015-2017 Parity Technologies (UK) Ltd.
+// This file is part of Parity.
+
+// Parity is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity. If not, see .
+
+import { shallow } from 'enzyme';
+import React from 'react';
+import sinon from 'sinon';
+
+import Accounts from './';
+
+let api;
+let component;
+let hwstore;
+let instance;
+let redux;
+
+function createApi () {
+ api = {};
+
+ return api;
+}
+
+function createHwStore (walletAddress = '0x456') {
+ hwstore = {
+ wallets: {
+ [walletAddress]: {
+ address: walletAddress
+ }
+ },
+ createAccountInfo: sinon.stub()
+ };
+
+ return hwstore;
+}
+
+function createRedux () {
+ redux = {
+ dispatch: sinon.stub(),
+ subscribe: sinon.stub(),
+ getState: () => {
+ return {
+ personal: {
+ accounts: {},
+ accountsInfo: {
+ '0x123': { meta: '1' },
+ '0x999': { meta: { hardware: {} } }
+ }
+ },
+ balances: {
+ balances: {}
+ }
+ };
+ }
+ };
+
+ return redux;
+}
+
+function render (props = {}) {
+ component = shallow(
+ ,
+ {
+ context: {
+ store: createRedux()
+ }
+ }
+ ).find('Accounts').shallow({
+ context: {
+ api: createApi()
+ }
+ });
+ instance = component.instance();
+
+ return component;
+}
+
+describe('views/Accounts', () => {
+ beforeEach(() => {
+ render();
+ });
+
+ it('renders defaults', () => {
+ expect(component).to.be.ok;
+ });
+
+ describe('instance event methods', () => {
+ describe('onHardwareChange', () => {
+ it('detects completely new entries', () => {
+ instance.hwstore = createHwStore();
+ instance.onHardwareChange();
+
+ expect(hwstore.createAccountInfo).to.have.been.calledWith({ address: '0x456' });
+ });
+
+ it('detects addressbook entries', () => {
+ instance.hwstore = createHwStore('0x123');
+ instance.onHardwareChange();
+
+ expect(hwstore.createAccountInfo).to.have.been.calledWith({ address: '0x123' }, { meta: '1' });
+ });
+
+ it('ignores existing hardware entries', () => {
+ instance.hwstore = createHwStore('0x999');
+ instance.onHardwareChange();
+
+ expect(hwstore.createAccountInfo).not.to.have.been.called;
+ });
+ });
+ });
+});