factom
Version:
Library to build applications on the Factom blockchain
303 lines (241 loc) • 11.9 kB
JavaScript
const { FactomCli, FactomEventEmitter, FACTOM_EVENT } = require('../src/factom'),
{
DirectoryBlock,
FactoidBlock,
AdminBlock,
EntryCreditBlock,
EntryBlock
} = require('../src/blocks'),
mockDirectoryBlock = require('./data/directory-block.json'),
assert = require('chai').assert;
describe('Test FactomEventEmitter', () => {
const cli = new FactomCli({
factomd: {
host: process.env.FACTOMD_HOST,
port: process.env.FACTOMD_PORT
}
});
it('should add then remove a directory block listener', done => {
const emitter = new FactomEventEmitter(cli);
const listener = dBlock => {
assert.instanceOf(dBlock, DirectoryBlock);
assert.isTrue(emitter.isPolling);
assert.lengthOf(emitter.listeners('newDirectoryBlock'), 1);
emitter.removeListener(FACTOM_EVENT.newDirectoryBlock, listener);
assert.isFalse(emitter.isPolling);
assert.lengthOf(emitter.listeners('newDirectoryBlock'), 0);
done();
};
emitter.on('error', err => done(err));
emitter.on(FACTOM_EVENT.newDirectoryBlock, listener);
});
it('should add then remove a factoid block listener', done => {
const emitter = new FactomEventEmitter(cli);
const listener = fBlock => {
assert.instanceOf(fBlock, FactoidBlock);
assert.isTrue(emitter.isPolling);
assert.lengthOf(emitter.listeners('newFactoidBlock'), 1);
emitter.removeListener('newFactoidBlock', listener);
assert.isFalse(emitter.isPolling);
assert.lengthOf(emitter.listeners('newFactoidBlock'), 0);
done();
};
emitter.on('error', err => done(err));
emitter.on(FACTOM_EVENT.newFactoidBlock, listener);
});
it('should add then remove an admin block listener', done => {
const emitter = new FactomEventEmitter(cli);
const listener = aBlock => {
assert.instanceOf(aBlock, AdminBlock);
assert.isTrue(emitter.isPolling);
assert.lengthOf(emitter.listeners('newAdminBlock'), 1);
emitter.removeListener('newAdminBlock', listener);
assert.isFalse(emitter.isPolling);
assert.lengthOf(emitter.listeners('newAdminBlock'), 0);
done();
};
emitter.on('error', err => done(err));
emitter.on(FACTOM_EVENT.newAdminBlock, listener);
});
it('should add then remove an entry credit block listener', done => {
const emitter = new FactomEventEmitter(cli);
const listener = ecBlock => {
assert.instanceOf(ecBlock, EntryCreditBlock);
assert.isTrue(emitter.isPolling);
assert.lengthOf(emitter.listeners('newEntryCreditBlock'), 1);
emitter.removeListener('newEntryCreditBlock', listener);
assert.isFalse(emitter.isPolling);
assert.lengthOf(emitter.listeners('newEntryCreditBlock'), 0);
done();
};
emitter.on('error', err => done(err));
emitter.on(FACTOM_EVENT.newEntryCreditBlock, listener);
});
it('should add then remove entry chain listener', done => {
const emitter = new FactomEventEmitter(cli);
const chain = '3392f9df84cae30d97962641600546d7aafd3a29667d1dd356280a54c9070bcb';
const listener = eBlock => {
assert.instanceOf(eBlock, EntryBlock);
assert.isTrue(emitter.isPolling);
assert.lengthOf(emitter.listeners(chain), 1);
emitter.removeListener(chain, listener);
assert.isFalse(emitter.isPolling);
assert.lengthOf(emitter.listeners(chain), 0);
done();
};
emitter.on('error', err => done(err));
emitter.on(chain, listener);
emitter._handleDirectoryBlock(mockDirectoryBlock);
});
it('should add then remove factoid address listener', done => {
const emitter = new FactomEventEmitter(cli);
const address = 'FA29eyMVJaZ2tbGqJ3M49gANaXMXCjgfKcJGe5mx8p4iQFCvFDAC';
const factoidBlockRef = 'cad832bab1d83c74bff8e1092fcf70e298cd7cdf35dee1956ae8879e749195ac';
const listener = tx => {
assert.strictEqual(
tx.id,
'c538ffb37d5dab837f3ea781b01bae481d8d6e77ceb0471442c1d85576a00e01'
);
assert.isTrue(emitter.isPolling);
assert.lengthOf(emitter.listeners(address), 1);
emitter.removeListener(address, listener);
assert.isFalse(emitter.isPolling);
assert.lengthOf(emitter.listeners(address), 0);
done();
};
emitter.on('error', err => done(err));
emitter.on(address, listener);
emitter._handleDirectoryBlock({ factoidBlockRef, entryBlockRefs: [] });
});
it('should add then remove new chain listener', done => {
const emitter = new FactomEventEmitter(cli);
const newChain = {
chainId: '626ae1be1e36c6fd589e50c55638c7a18b551dfc6b63da30842722d448fc6db2',
keyMR: 'a4883d0e53ce79d70401a839b087c91f1611bd332e3d988a412230fddd27c22d'
};
mockDirectoryBlock.entryBlockRefs.push(newChain);
const listener = eBlock => {
assert.instanceOf(eBlock, EntryBlock);
assert.strictEqual(eBlock.sequenceNumber, 0);
assert.isTrue(emitter.isPolling);
assert.strictEqual(eBlock.keyMR, newChain.keyMR);
assert.lengthOf(emitter.listeners('newChain'), 1);
emitter.removeListener('newChain', listener);
assert.isFalse(emitter.isPolling);
assert.lengthOf(emitter.listeners('newChain'), 0);
done();
};
emitter.on('error', err => done(err));
emitter.on(FACTOM_EVENT.newChain, listener);
emitter._handleDirectoryBlock(mockDirectoryBlock);
});
it('should stop polling after emitting once', done => {
const emitter = new FactomEventEmitter(cli);
const listener = dBlock => {
assert.instanceOf(dBlock, DirectoryBlock);
assert.isFalse(emitter.isPolling);
assert.lengthOf(emitter.listeners('newDirectoryBlock'), 0);
done();
};
emitter.on('error', err => done(err));
emitter.once(FACTOM_EVENT.newDirectoryBlock, listener);
});
it('should not stop polling if there are listeners of a different type still active', done => {
const emitter = new FactomEventEmitter(cli);
const nullListener = () => {};
const listener = aBlock => {
// assert that adding multiple listeners results in healthy state
assert.instanceOf(aBlock, AdminBlock);
assert.isTrue(emitter.isPolling);
assert.lengthOf(emitter.listeners('newEntryCreditBlock'), 1);
assert.lengthOf(emitter.listeners('newAdminBlock'), 1);
// assert that the removal of a listener does not stop polling if newDirectoryBlock still has dependent listeners
emitter.removeListener('newAdminBlock', listener);
assert.isTrue(emitter.isPolling);
assert.lengthOf(emitter.listeners('newEntryCreditBlock'), 1);
assert.lengthOf(emitter.listeners('newAdminBlock'), 0);
// assert that the removal of the final dependent listeners stops polling and removes all listeners
emitter.removeListener('newEntryCreditBlock', nullListener);
assert.isFalse(emitter.isPolling);
assert.lengthOf(emitter.listeners('newEntryCreditBlock'), 0);
done();
};
emitter.on('error', err => done(err));
emitter.on(FACTOM_EVENT.newEntryCreditBlock, nullListener);
emitter.on(FACTOM_EVENT.newAdminBlock, listener);
});
it('should not stop polling if there are listeners of the same type still active', done => {
const emitter = new FactomEventEmitter(cli);
const nullListener = () => {};
const listener = fBlock => {
// assert that adding multiple listeners results in healthy state
assert.instanceOf(fBlock, FactoidBlock);
assert.isTrue(emitter.isPolling);
assert.lengthOf(emitter.listeners('newFactoidBlock'), 2);
// assert that the removal of a listener does not stop polling if newDirectoryBlock still has dependent listeners
emitter.removeListener('newFactoidBlock', listener);
assert.isTrue(emitter.isPolling);
assert.lengthOf(emitter.listeners('newFactoidBlock'), 1);
// assert that the removal of the final dependent listeners stops polling and removes all listeners
emitter.removeListener('newFactoidBlock', nullListener);
assert.isFalse(emitter.isPolling);
assert.lengthOf(emitter.listeners('newFactoidBlock'), 0);
done();
};
emitter.on('error', err => done(err));
emitter.on(FACTOM_EVENT.newFactoidBlock, nullListener);
emitter.on(FACTOM_EVENT.newFactoidBlock, listener);
});
it('should add two chain ID listeners for the same chain ID then remove one without affecting the other', done => {
const emitter = new FactomEventEmitter(cli);
const chainId = '4060c0192a421ca121ffff935889ef55a64574a6ef0e69b2b4f8a0ab919b2ca4';
const nullListener = () => {};
const listener = eBlock => {
assert.instanceOf(eBlock, EntryBlock);
assert.isTrue(emitter.isPolling);
assert.lengthOf(emitter.listeners(chainId), 2);
assert.lengthOf(emitter.chainSubscriptions, 1);
emitter.removeListener(chainId, nullListener);
assert.isTrue(emitter.isPolling);
assert.lengthOf(emitter.listeners(chainId), 1);
assert.lengthOf(emitter.chainSubscriptions, 1);
emitter.removeListener(chainId, listener);
assert.isFalse(emitter.isPolling);
assert.lengthOf(emitter.listeners(chainId), 0);
assert.lengthOf(emitter.chainSubscriptions, 0);
done();
};
emitter.on('error', err => done(err));
emitter.on(chainId, nullListener);
emitter.on(chainId, listener);
emitter._handleDirectoryBlock(mockDirectoryBlock);
});
it('should add two factoid address listeners for the same address then remove one without affecting the other', done => {
const emitter = new FactomEventEmitter(cli);
const address = 'FA29eyMVJaZ2tbGqJ3M49gANaXMXCjgfKcJGe5mx8p4iQFCvFDAC';
const factoidBlockRef = 'cad832bab1d83c74bff8e1092fcf70e298cd7cdf35dee1956ae8879e749195ac';
const nullListener = () => {};
const listener = tx => {
assert.strictEqual(
tx.id,
'c538ffb37d5dab837f3ea781b01bae481d8d6e77ceb0471442c1d85576a00e01'
);
assert.isTrue(emitter.isPolling);
assert.lengthOf(emitter.listeners(address), 2);
assert.lengthOf(emitter.factoidAddressSubscriptions, 1);
emitter.removeListener(address, nullListener);
assert.isTrue(emitter.isPolling);
assert.lengthOf(emitter.listeners(address), 1);
assert.lengthOf(emitter.factoidAddressSubscriptions, 1);
emitter.removeListener(address, listener);
assert.isFalse(emitter.isPolling);
assert.lengthOf(emitter.listeners(address), 0);
assert.lengthOf(emitter.factoidAddressSubscriptions, 0);
done();
};
emitter.on('error', err => done(err));
emitter.on(address, nullListener);
emitter.on(address, listener);
emitter._handleDirectoryBlock({ factoidBlockRef, entryBlockRefs: [] });
});
});