import { expect } from 'chai'; import Sinon from 'sinon'; import { getHasSeenHF190, getHasSeenHF191, handleHardforkResult, resetHardForkCachedValues, } from '../../../../session/apis/snode_api/hfHandling'; import { TestUtils } from '../../../test-utils'; // tslint:disable-next-line: max-func-body-length describe('hardfork handling', () => { describe('getHasSeenHF190', () => { afterEach(() => { Sinon.restore(); resetHardForkCachedValues(); }); it('fetches from db if undefined, and write to db false if db value is undefined', async () => { const getItemById = TestUtils.stubData('getItemById').resolves(undefined); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); const ret = await getHasSeenHF190(); expect(ret).to.be.eq(false, 'getHasSeenHF190 should return false'); expect(getItemById.calledOnce).to.be.eq(true, 'getItemById should have been called'); expect(createItem.calledOnce).to.be.eq(true, 'createItem should have been called'); expect(createItem.args[0][0]).to.be.deep.eq( { id: 'hasSeenHardfork190', value: false }, 'createItem should have been to set hasSeenHardfork190 to false in the db' ); }); it('fetches from db if undefined, and does not write to db if db value is not undefined', async () => { const getItemById = TestUtils.stubData('getItemById').resolves({ id: 'getHasSeenHF190', value: false, }); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); const ret = await getHasSeenHF190(); expect(ret).to.be.eq(false, 'getHasSeenHF190 should return false'); expect(getItemById.calledOnce).to.be.eq(true, 'getItemById should have been called'); expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called'); }); it('fetches from db if undefined, and does not write to db if db value is not undefined - 2', async () => { const getItemById = TestUtils.stubData('getItemById').resolves({ id: 'getHasSeenHF190', value: true, }); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); const ret = await getHasSeenHF190(); expect(ret).to.be.eq(true, 'getHasSeenHF190 should return false'); expect(getItemById.calledOnce).to.be.eq(true, 'getItemById should have been called'); expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called'); }); it('fetches from db only the value is not cached already', async () => { const getItemById = TestUtils.stubData('getItemById').resolves({ id: 'getHasSeenHF190', value: true, }); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); const ret = await getHasSeenHF190(); const ret2 = await getHasSeenHF190(); expect(ret).to.be.eq(true, 'getHasSeenHF190 should return false'); expect(ret2).to.be.eq(true, 'getHasSeenHF190 should return false - 2'); expect(getItemById.calledOnce).to.be.eq(true, 'getItemById should have been called'); expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called'); }); }); describe('getHasSeenHF191', () => { afterEach(() => { Sinon.restore(); resetHardForkCachedValues(); }); it('fetches from db if undefined, and write to db false if db value is undefined', async () => { const getItemById = TestUtils.stubData('getItemById').resolves(undefined); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); const ret = await getHasSeenHF191(); expect(ret).to.be.eq(false, 'getHasSeenHF191 should return false'); expect(getItemById.calledOnce).to.be.eq(true, 'getItemById should have been called'); expect(createItem.calledOnce).to.be.eq(true, 'createItem should have been called'); expect(createItem.args[0][0]).to.be.deep.eq( { id: 'hasSeenHardfork191', value: false }, 'createItem should have been to set hasSeenHardfork191 to false in the db' ); }); it('fetches from db if undefined, and does not write to db if db value is not undefined', async () => { const getItemById = TestUtils.stubData('getItemById').resolves({ id: 'getHasSeenHF191', value: false, }); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); const ret = await getHasSeenHF191(); expect(ret).to.be.eq(false, 'getHasSeenHF191 should return false'); expect(getItemById.calledOnce).to.be.eq(true, 'getItemById should have been called'); expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called'); }); it('fetches from db if undefined, and does not write to db if db value is not undefined - 2', async () => { const getItemById = TestUtils.stubData('getItemById').resolves({ id: 'getHasSeenHF191', value: true, }); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); const ret = await getHasSeenHF191(); expect(ret).to.be.eq(true, 'getHasSeenHF191 should return false'); expect(getItemById.calledOnce).to.be.eq(true, 'getItemById should have been called'); expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called'); }); it('fetches from db only the value is not cached already', async () => { const getItemById = TestUtils.stubData('getItemById').resolves({ id: 'getHasSeenHF191', value: true, }); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); const ret = await getHasSeenHF191(); const ret2 = await getHasSeenHF191(); expect(ret).to.be.eq(true, 'getHasSeenHF191 should return false'); expect(ret2).to.be.eq(true, 'getHasSeenHF191 should return false - 2'); expect(getItemById.calledOnce).to.be.eq(true, 'getItemById should have been called'); expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called'); }); }); // tslint:disable-next-line: max-func-body-length describe('handleHardforkResult', () => { afterEach(() => { Sinon.restore(); resetHardForkCachedValues(); }); it('does not fail if null is given as json', async () => { const getItemById = TestUtils.stubData('getItemById').resolves(undefined); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); await handleHardforkResult(null as any); expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice'); expect(createItem.calledTwice).to.be.eq(true, 'createItem should have been calledTwice'); expect(createItem.args[0][0]).to.be.deep.eq( { id: 'hasSeenHardfork190', value: false }, 'createItem should have been to set hasSeenHardfork190 to false in the db' ); expect(createItem.args[1][0]).to.be.deep.eq( { id: 'hasSeenHardfork191', value: false }, 'createItem should have been to set hasSeenHardfork191 to false in the db' ); }); it('does not fail on empty json object', async () => { const getItemById = TestUtils.stubData('getItemById').resolves(undefined); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); await handleHardforkResult({}); expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice'); expect(createItem.calledTwice).to.be.eq(true, 'createItem should have been calledTwice'); expect(createItem.args[0][0]).to.be.deep.eq( { id: 'hasSeenHardfork190', value: false }, 'createItem should have been to set hasSeenHardfork190 to false in the db' ); expect(createItem.args[1][0]).to.be.deep.eq( { id: 'hasSeenHardfork191', value: false }, 'createItem should have been to set hasSeenHardfork191 to false in the db' ); }); it('does not fail with invalid array length of 3', async () => { const getItemById = TestUtils.stubData('getItemById').resolves(undefined); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); await handleHardforkResult({ hf: [1, 2, 3] }); expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice'); expect(createItem.calledTwice).to.be.eq(true, 'createItem should have been calledTwice'); expect(createItem.args[0][0]).to.be.deep.eq( { id: 'hasSeenHardfork190', value: false }, 'createItem should have been to set hasSeenHardfork190 to false in the db' ); expect(createItem.args[1][0]).to.be.deep.eq( { id: 'hasSeenHardfork191', value: false }, 'createItem should have been to set hasSeenHardfork191 to false in the db' ); }); it('does not fail with invalid array length of 3', async () => { const getItemById = TestUtils.stubData('getItemById').resolves(undefined); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); await handleHardforkResult({ hf: [1, 2, 3] }); expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice'); expect(createItem.calledTwice).to.be.eq(true, 'createItem should have been calledTwice'); expect(createItem.args[0][0]).to.be.deep.eq( { id: 'hasSeenHardfork190', value: false }, 'createItem should have been to set hasSeenHardfork190 to false in the db' ); expect(createItem.args[1][0]).to.be.deep.eq( { id: 'hasSeenHardfork191', value: false }, 'createItem should have been to set hasSeenHardfork191 to false in the db' ); }); it('does not fail with invalid array length of but not numbers', async () => { const getItemById = TestUtils.stubData('getItemById').resolves(undefined); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); await handleHardforkResult({ hf: ['1', 2] }); expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice'); expect(createItem.calledTwice).to.be.eq(true, 'createItem should have been calledTwice'); expect(createItem.args[0][0]).to.be.deep.eq( { id: 'hasSeenHardfork190', value: false }, 'createItem should have been to set hasSeenHardfork190 to false in the db' ); expect(createItem.args[1][0]).to.be.deep.eq( { id: 'hasSeenHardfork191', value: false }, 'createItem should have been to set hasSeenHardfork191 to false in the db' ); }); it('does not fail with invalid array length of 1 ', async () => { const getItemById = TestUtils.stubData('getItemById').resolves(undefined); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); await handleHardforkResult({ hf: [1] }); expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice'); expect(createItem.calledTwice).to.be.eq(true, 'createItem should have been calledTwice'); expect(createItem.args[0][0]).to.be.deep.eq( { id: 'hasSeenHardfork190', value: false }, 'createItem should have been to set hasSeenHardfork190 to false in the db' ); expect(createItem.args[1][0]).to.be.deep.eq( { id: 'hasSeenHardfork191', value: false }, 'createItem should have been to set hasSeenHardfork191 to false in the db' ); }); it('does not write new data if hf major is <= 18 ', async () => { const getItemById = TestUtils.stubData('getItemById').resolves(undefined); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); await handleHardforkResult({ hf: [18, 9] }); expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice'); expect(createItem.calledTwice).to.be.eq(true, 'createItem should have been calledTwice'); expect(createItem.args[0][0]).to.be.deep.eq( { id: 'hasSeenHardfork190', value: false }, 'createItem should have been to set hasSeenHardfork190 to false in the db' ); expect(createItem.args[1][0]).to.be.deep.eq( { id: 'hasSeenHardfork191', value: false }, 'createItem should have been to set hasSeenHardfork191 to false in the db' ); }); it('does write new data if hf major is === 19 and minor === 0 ', async () => { const getItemById = TestUtils.stubData('getItemById').resolves(undefined); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); await handleHardforkResult({ hf: [19, 0] }); expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice'); expect(createItem.calledThrice).to.be.eq(true, 'createItem should have been calledThrice'); expect(createItem.args[0][0]).to.be.deep.eq( { id: 'hasSeenHardfork190', value: false }, 'createItem should have been to set hasSeenHardfork190 to false in the db' ); expect(createItem.args[1][0]).to.be.deep.eq( { id: 'hasSeenHardfork191', value: false }, 'createItem should have been to set hasSeenHardfork191 to false in the db' ); expect(createItem.args[2][0]).to.be.deep.eq( { id: 'hasSeenHardfork190', value: true }, 'createItem should have been to set hasSeenHardfork191 to true in the db' ); getItemById.resetHistory(); createItem.resetHistory(); expect(await getHasSeenHF190()).to.be.eq(true, 'getHasSeenHF190 should have been true'); expect(getItemById.notCalled).to.be.eq(true, 'getItemById should not have been called more'); expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called more'); }); it('does write new data if hf major is === 19 and minor === 1 ', async () => { const getItemById = TestUtils.stubData('getItemById').resolves(undefined); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); await handleHardforkResult({ hf: [19, 1] }); expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice'); expect(createItem.callCount).to.be.eq(4, 'createItem should have been 4'); expect(createItem.args[0][0]).to.be.deep.eq( { id: 'hasSeenHardfork190', value: false }, 'createItem should have been to set hasSeenHardfork190 to false in the db' ); expect(createItem.args[1][0]).to.be.deep.eq( { id: 'hasSeenHardfork191', value: false }, 'createItem should have been to set hasSeenHardfork191 to false in the db' ); expect(createItem.args[2][0]).to.be.deep.eq( { id: 'hasSeenHardfork190', value: true }, 'createItem should have been to set hasSeenHardfork190 to true in the db' ); expect(createItem.args[3][0]).to.be.deep.eq( { id: 'hasSeenHardfork191', value: true }, 'createItem should have been to set hasSeenHardfork191 to true in the db' ); getItemById.resetHistory(); createItem.resetHistory(); expect(await getHasSeenHF190()).to.be.eq(true, 'getHasSeenHF190 should have been true'); expect(await getHasSeenHF191()).to.be.eq(true, 'getHasSeenHF191 should have been true'); expect(getItemById.notCalled).to.be.eq(true, 'getItemById should not have been called more'); expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called more'); }); it('does not write new data if hf major is === 19 and minor === 1 but it is already known we have seen both forks ', async () => { const getItemById = TestUtils.stubData('getItemById').resolves({ id: '', value: true }); const createItem = TestUtils.stubData('createOrUpdateItem').resolves(); await handleHardforkResult({ hf: [19, 1] }); expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice'); expect(createItem.callCount).to.be.eq(0, 'createItem should have been 0'); getItemById.resetHistory(); createItem.resetHistory(); expect(await getHasSeenHF190()).to.be.eq(true, 'getHasSeenHF190 should have been true'); expect(await getHasSeenHF191()).to.be.eq(true, 'getHasSeenHF191 should have been true'); expect(getItemById.notCalled).to.be.eq(true, 'getItemById should not have been called more'); expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called more'); }); }); });