Dapp visibility save/load tests (#4150)

* Start of tests to replicate issue

* Expand visibility tests

* Cleanups

* typo

* Extend saving tests as requested (pre-emptive)

* tests for new setDisplayApps action

* Address PR oversights
This commit is contained in:
Jaco Greeff 2017-01-23 16:45:56 +01:00 committed by GitHub
parent 512612424c
commit 3d1162e3d9
3 changed files with 236 additions and 5 deletions

View File

@ -34,13 +34,17 @@ export default class Contracts {
this._signaturereg = new SignatureReg(api, this._registry); this._signaturereg = new SignatureReg(api, this._registry);
this._tokenreg = new TokenReg(api, this._registry); this._tokenreg = new TokenReg(api, this._registry);
this._githubhint = new GithubHint(api, this._registry); this._githubhint = new GithubHint(api, this._registry);
this.badgeReg = new BadgeReg(api, this._registry); this._badgeReg = new BadgeReg(api, this._registry);
} }
get registry () { get registry () {
return this._registry; return this._registry;
} }
get badgeReg () {
return this._badgeReg;
}
get dappReg () { get dappReg () {
return this._dappreg; return this._dappreg;
} }

View File

@ -0,0 +1,220 @@
// Copyright 2015, 2016 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 <http://www.gnu.org/licenses/>.
import BigNumber from 'bignumber.js';
import sinon from 'sinon';
import localStore from 'store';
import Contracts from '~/contracts';
import Store, { LS_KEY_DISPLAY } from './dappsStore';
const APPID_BASICCOIN = '0xf9f2d620c2e08f83e45555247146c62185e4ab7cf82a4b9002a265a0d020348f';
const APPID_DAPPREG = '0x7bbc4f1a27628781b96213e781a1b8eec6982c1db8fac739af6e4c5a55862c03';
const APPID_GHH = '0x058740ee9a5a3fb9f1cfa10752baec87e09cc45cd7027fd54708271aca300c75';
const APPID_LOCALTX = '0xae74ad174b95cdbd01c88ac5b73a296d33e9088fc2a200e76bcedf3a94a7815d';
const FETCH_OK = {
ok: true,
status: 200
};
let globalContractsGet;
let globalFetch;
function stubGlobals () {
globalContractsGet = Contracts.get;
globalFetch = global.fetch;
Contracts.get = () => {
return {
dappReg: {
at: sinon.stub().resolves([[0, 1, 2, 3], 'appOwner']),
count: sinon.stub().resolves(new BigNumber(1)),
getContract: sinon.stub().resolves({}),
getContent: sinon.stub().resolves([0, 1, 2, 3]),
getImage: sinon.stub().resolves([0, 1, 2, 3]),
getManifest: sinon.stub().resolves([0, 1, 2, 3])
}
};
};
global.fetch = (url) => {
switch (url) {
case '/api/apps':
return Promise.resolve(Object.assign({}, FETCH_OK, {
json: sinon.stub().resolves([]) // TODO: Local stubs in here
}));
default:
console.log('Unknown fetch stub endpoint', url);
return Promise.reject();
}
};
}
function restoreGlobals () {
Contracts.get = globalContractsGet;
global.fetch = globalFetch;
}
let api;
let store;
function create () {
api = {};
store = new Store(api);
return store;
}
describe('views/Dapps/DappStore', () => {
beforeEach(() => {
stubGlobals();
});
afterEach(() => {
restoreGlobals();
});
describe('@action', () => {
const defaultViews = {
[APPID_BASICCOIN]: { visible: false },
[APPID_DAPPREG]: { visible: true }
};
describe('setDisplayApps', () => {
beforeEach(() => {
create();
store.setDisplayApps(defaultViews);
});
it('sets from empty start', () => {
expect(store.displayApps).to.deep.equal(defaultViews);
});
it('overrides single keys, keeping existing', () => {
store.setDisplayApps({ [APPID_BASICCOIN]: { visible: true } });
expect(store.displayApps).to.deep.equal(
Object.assign({}, defaultViews, { [APPID_BASICCOIN]: { visible: true } })
);
});
it('extends with new keys, keeping existing', () => {
store.setDisplayApps({ 'test': { visible: true } });
expect(store.displayApps).to.deep.equal(
Object.assign({}, defaultViews, { 'test': { visible: true } })
);
});
});
describe('hideApp/showApp', () => {
beforeEach(() => {
localStore.set(LS_KEY_DISPLAY, defaultViews);
create().readDisplayApps();
});
afterEach(() => {
localStore.set(LS_KEY_DISPLAY, {});
});
it('disables visibility', () => {
store.hideApp(APPID_DAPPREG);
expect(store.displayApps[APPID_DAPPREG].visible).to.be.false;
expect(localStore.get(LS_KEY_DISPLAY)).to.deep.equal(
Object.assign({}, defaultViews, { [APPID_DAPPREG]: { visible: false } })
);
});
it('enables visibility', () => {
store.showApp(APPID_BASICCOIN);
expect(store.displayApps[APPID_BASICCOIN].visible).to.be.true;
expect(localStore.get(LS_KEY_DISPLAY)).to.deep.equal(
Object.assign({}, defaultViews, { [APPID_BASICCOIN]: { visible: true } })
);
});
it('keeps visibility state', () => {
store.hideApp(APPID_BASICCOIN);
store.showApp(APPID_DAPPREG);
expect(store.displayApps[APPID_BASICCOIN].visible).to.be.false;
expect(store.displayApps[APPID_DAPPREG].visible).to.be.true;
expect(localStore.get(LS_KEY_DISPLAY)).to.deep.equal(defaultViews);
});
});
describe('readDisplayApps/writeDisplayApps', () => {
beforeEach(() => {
localStore.set(LS_KEY_DISPLAY, defaultViews);
create().readDisplayApps();
});
afterEach(() => {
localStore.set(LS_KEY_DISPLAY, {});
});
it('loads visibility from storage', () => {
expect(store.displayApps).to.deep.equal(defaultViews);
});
it('saves visibility to storage', () => {
store.setDisplayApps({ [APPID_BASICCOIN]: { visible: true } });
store.writeDisplayApps();
expect(localStore.get(LS_KEY_DISPLAY)).to.deep.equal(
Object.assign({}, defaultViews, { [APPID_BASICCOIN]: { visible: true } })
);
});
});
});
describe('saved views', () => {
beforeEach(() => {
localStore.set(LS_KEY_DISPLAY, {
[APPID_BASICCOIN]: { visible: false },
[APPID_DAPPREG]: { visible: true }
});
return create().loadAllApps();
});
afterEach(() => {
localStore.set(LS_KEY_DISPLAY, {});
});
it('disables based on saved keys', () => {
expect(store.displayApps[APPID_BASICCOIN].visible).to.be.false;
});
it('enables based on saved keys', () => {
expect(store.displayApps[APPID_DAPPREG].visible).to.be.true;
});
it('keeps non-sepcified disabled keys', () => {
expect(store.displayApps[APPID_GHH].visible).to.be.false;
});
it('keeps non-specified enabled keys', () => {
expect(store.displayApps[APPID_LOCALTX].visible).to.be.true;
});
});
});

View File

@ -39,7 +39,6 @@ export default class DappsStore extends EventEmitter {
_api = null; _api = null;
_subscriptions = {}; _subscriptions = {};
_cachedApps = {}; _cachedApps = {};
_manifests = {}; _manifests = {};
_registryAppsIds = null; _registryAppsIds = null;
@ -246,12 +245,12 @@ export default class DappsStore extends EventEmitter {
} }
@action hideApp = (id) => { @action hideApp = (id) => {
this.displayApps = Object.assign({}, this.displayApps, { [id]: { visible: false } }); this.setDisplayApps({ [id]: { visible: false } });
this.writeDisplayApps(); this.writeDisplayApps();
} }
@action showApp = (id) => { @action showApp = (id) => {
this.displayApps = Object.assign({}, this.displayApps, { [id]: { visible: true } }); this.setDisplayApps({ [id]: { visible: true } });
this.writeDisplayApps(); this.writeDisplayApps();
} }
@ -263,6 +262,10 @@ export default class DappsStore extends EventEmitter {
store.set(LS_KEY_DISPLAY, this.displayApps); store.set(LS_KEY_DISPLAY, this.displayApps);
} }
@action setDisplayApps = (displayApps) => {
this.displayApps = Object.assign({}, this.displayApps, displayApps);
};
@action addApps = (_apps = []) => { @action addApps = (_apps = []) => {
transaction(() => { transaction(() => {
const apps = _apps.filter((app) => app); const apps = _apps.filter((app) => app);
@ -285,7 +288,11 @@ export default class DappsStore extends EventEmitter {
} }
}); });
this.displayApps = Object.assign({}, this.displayApps, visibility); this.setDisplayApps(visibility);
}); });
} }
} }
export {
LS_KEY_DISPLAY
};