blockchain.test.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. const { eq, ok, notOk } = require('../../helpers/assert');
  2. const { makeNetwork, makePeer } = require('../../helpers/setup');
  3. describe('blockchain (blockexplorer)', (t) => {
  4. t('member sees decrypted tribe content', async () => {
  5. const net = makeNetwork(); const A = makePeer(net); A.setActor();
  6. const r = await A.use('tribes').createTribe('G', '', null, '', [], false, true, 'strict', null, 'OPEN', '');
  7. await A.use('tribesContent').create(r.key, 'feed', { description: 'hi' });
  8. const blocks = await A.use('blockchain').listBlockchain('all', A.keypair.id, {});
  9. ok(Array.isArray(blocks));
  10. const ours = blocks.find(b => b.content && b.content.description === 'hi');
  11. ok(ours);
  12. eq(ours.content._decrypted, true);
  13. });
  14. t('non-member sees no decrypted tribe content', async () => {
  15. const net = makeNetwork(); const A = makePeer(net); const B = makePeer(net); A.setActor();
  16. const r = await A.use('tribes').createTribe('G', '', null, '', [], false, true, 'strict', null, 'OPEN', '');
  17. await A.use('tribesContent').create(r.key, 'feed', { description: 'top secret' });
  18. B.setActor();
  19. const blocks = await B.use('blockchain').listBlockchain('all', B.keypair.id, {});
  20. const leaked = blocks.find(b => b.content && b.content.description === 'top secret');
  21. notOk(leaked);
  22. });
  23. t('hidden envelope types do not appear in blockexplorer', async () => {
  24. const net = makeNetwork(); const A = makePeer(net); A.setActor();
  25. const r = await A.use('tribes').createTribe('T', '', null, '', [], false, true, 'strict', null, 'OPEN', '');
  26. await A.use('tribes').generateInvite(r.key);
  27. const blocks = await A.use('blockchain').listBlockchain('all', A.keypair.id, {});
  28. const inviteMsg = blocks.find(b => b.type === 'tribe-invite-msg');
  29. notOk(inviteMsg);
  30. });
  31. });
  32. describe('blockchain: computeStats (explorer stats panel)', (t) => {
  33. const { computeStats } = require('../../../src/views/blockchain_view');
  34. t('empty input returns zero totals', () => {
  35. const s = computeStats([]);
  36. eq(s.total, 0);
  37. eq(s.typeBreakdown.length, 0);
  38. eq(s.topAuthors.length, 0);
  39. });
  40. t('counts by type and sorts descending', () => {
  41. const blocks = [
  42. { type: 'forum', author: '@a' },
  43. { type: 'forum', author: '@b' },
  44. { type: 'forum', author: '@a' },
  45. { type: 'post', author: '@a' },
  46. { type: 'vote', author: '@c' }
  47. ];
  48. const s = computeStats(blocks);
  49. eq(s.total, 5);
  50. eq(s.typeBreakdown[0].type, 'forum');
  51. eq(s.typeBreakdown[0].count, 3);
  52. eq(s.typeBreakdown[1].count, 1);
  53. });
  54. t('topAuthors caps at 5 and ranks correctly', () => {
  55. const blocks = [];
  56. for (let i = 0; i < 10; i++) blocks.push({ type: 'post', author: '@a' });
  57. for (let i = 0; i < 5; i++) blocks.push({ type: 'post', author: '@b' });
  58. for (let i = 0; i < 3; i++) blocks.push({ type: 'post', author: '@c' });
  59. blocks.push({ type: 'post', author: '@d' });
  60. blocks.push({ type: 'post', author: '@e' });
  61. blocks.push({ type: 'post', author: '@f' });
  62. const s = computeStats(blocks);
  63. eq(s.topAuthors.length, 5);
  64. eq(s.topAuthors[0].author, '@a');
  65. eq(s.topAuthors[0].count, 10);
  66. eq(s.topAuthors[1].author, '@b');
  67. eq(s.topAuthors[2].author, '@c');
  68. notOk(s.topAuthors.find(a => a.author === '@f'), 'overflow author excluded');
  69. });
  70. t('ignores entries with missing type', () => {
  71. const blocks = [
  72. { type: 'post', author: '@a' },
  73. { author: '@a' },
  74. { type: null, author: '@a' }
  75. ];
  76. const s = computeStats(blocks);
  77. eq(s.typeBreakdown.length, 1);
  78. eq(s.typeBreakdown[0].count, 1);
  79. });
  80. t('ignores entries with missing author for topAuthors', () => {
  81. const blocks = [
  82. { type: 'post' },
  83. { type: 'post', author: '@a' }
  84. ];
  85. const s = computeStats(blocks);
  86. eq(s.topAuthors.length, 1);
  87. eq(s.topAuthors[0].author, '@a');
  88. });
  89. });