diff --git a/karma.conf.js b/karma.conf.js index fdceab411f..0176a32d10 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -17,7 +17,7 @@ module.exports = function (config) { singleRun: true, karmaTypescriptConfig: { bundlerOptions: { - entrypoints: /.*\.browser\.spec\.ts$/, + entrypoints: /^.*[^(node)]\.spec\.ts$/, }, coverageOptions: { instrumentation: false, diff --git a/src/lib/discovery.browser.spec.ts b/src/lib/discovery.spec.ts similarity index 100% rename from src/lib/discovery.browser.spec.ts rename to src/lib/discovery.spec.ts diff --git a/src/lib/waku.spec.ts b/src/lib/waku.node.spec.ts similarity index 99% rename from src/lib/waku.spec.ts rename to src/lib/waku.node.spec.ts index d822c8bae3..ce50591170 100644 --- a/src/lib/waku.spec.ts +++ b/src/lib/waku.node.spec.ts @@ -17,7 +17,7 @@ import { generateSymmetricKey } from './waku_message/version_1'; const TestContentTopic = '/test/1/waku/utf8'; -describe('Waku Dial', function () { +describe('Waku Dial [node only]', function () { let waku: Waku; let waku2: Waku; let nimWaku: NimWaku; diff --git a/src/lib/waku_light_push/index.spec.ts b/src/lib/waku_light_push/index.node.spec.ts similarity index 98% rename from src/lib/waku_light_push/index.spec.ts rename to src/lib/waku_light_push/index.node.spec.ts index 819b48bfb5..5ff779e960 100644 --- a/src/lib/waku_light_push/index.spec.ts +++ b/src/lib/waku_light_push/index.node.spec.ts @@ -10,7 +10,7 @@ import { WakuMessage } from '../waku_message'; const TestContentTopic = '/test/1/waku-light-push/utf8'; -describe('Waku Light Push', () => { +describe('Waku Light Push [node only]', () => { let waku: Waku; let nimWaku: NimWaku; diff --git a/src/lib/waku_message/index.browser.spec.ts b/src/lib/waku_message/index.browser.spec.ts deleted file mode 100644 index 5cc9bd4f40..0000000000 --- a/src/lib/waku_message/index.browser.spec.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { expect } from 'chai'; -import fc from 'fast-check'; - -import { getPublicKey } from './version_1'; - -import { WakuMessage } from './index'; - -const TestContentTopic = '/test/1/waku-message/utf8'; - -describe('Waku Message: Browser & Node', function () { - it('Waku message round trip binary serialization [clear]', async function () { - await fc.assert( - fc.asyncProperty(fc.string(), async (s) => { - const msg = await WakuMessage.fromUtf8String(s, TestContentTopic); - const binary = msg.encode(); - const actual = await WakuMessage.decode(binary); - - expect(actual).to.deep.equal(msg); - }) - ); - }); - - it('Payload to utf-8', async function () { - await fc.assert( - fc.asyncProperty(fc.string(), async (s) => { - const msg = await WakuMessage.fromUtf8String(s, TestContentTopic); - const utf8 = msg.payloadAsUtf8; - - return utf8 === s; - }) - ); - }); - - it('Waku message round trip binary encryption [asymmetric, no signature]', async function () { - await fc.assert( - fc.asyncProperty( - fc.uint8Array({ minLength: 1 }), - fc.uint8Array({ minLength: 32, maxLength: 32 }), - async (payload, privKey) => { - const publicKey = getPublicKey(privKey); - - const msg = await WakuMessage.fromBytes(payload, TestContentTopic, { - encPublicKey: publicKey, - }); - - const wireBytes = msg.encode(); - const actual = await WakuMessage.decode(wireBytes, [privKey]); - - expect(actual?.payload).to.deep.equal(payload); - } - ) - ); - }); - - it('Waku message round trip binary encryption [asymmetric, signature]', async function () { - await fc.assert( - fc.asyncProperty( - fc.uint8Array({ minLength: 1 }), - fc.uint8Array({ minLength: 32, maxLength: 32 }), - fc.uint8Array({ minLength: 32, maxLength: 32 }), - async (payload, sigPrivKey, encPrivKey) => { - const sigPubKey = getPublicKey(sigPrivKey); - const encPubKey = getPublicKey(encPrivKey); - - const msg = await WakuMessage.fromBytes(payload, TestContentTopic, { - encPublicKey: encPubKey, - sigPrivKey: sigPrivKey, - }); - - const wireBytes = msg.encode(); - const actual = await WakuMessage.decode(wireBytes, [encPrivKey]); - - expect(actual?.payload).to.deep.equal(payload); - expect(actual?.signaturePublicKey).to.deep.equal(sigPubKey); - } - ) - ); - }); - - it('Waku message round trip binary encryption [symmetric, no signature]', async function () { - await fc.assert( - fc.asyncProperty( - fc.uint8Array({ minLength: 1 }), - fc.uint8Array({ minLength: 32, maxLength: 32 }), - async (payload, key) => { - const msg = await WakuMessage.fromBytes(payload, TestContentTopic, { - symKey: key, - }); - - const wireBytes = msg.encode(); - const actual = await WakuMessage.decode(wireBytes, [key]); - - expect(actual?.payload).to.deep.equal(payload); - } - ) - ); - }); - - it('Waku message round trip binary encryption [symmetric, signature]', async function () { - await fc.assert( - fc.asyncProperty( - fc.uint8Array({ minLength: 1 }), - fc.uint8Array({ minLength: 32, maxLength: 32 }), - fc.uint8Array({ minLength: 32, maxLength: 32 }), - async (payload, sigPrivKey, symKey) => { - const sigPubKey = getPublicKey(sigPrivKey); - - const msg = await WakuMessage.fromBytes(payload, TestContentTopic, { - symKey: symKey, - sigPrivKey: sigPrivKey, - }); - - const wireBytes = msg.encode(); - const actual = await WakuMessage.decode(wireBytes, [symKey]); - - expect(actual?.payload).to.deep.equal(payload); - expect(actual?.signaturePublicKey).to.deep.equal(sigPubKey); - } - ) - ); - }); - - it('Waku message round trip utf-8 including emojis', async function () { - const messageText = '😁🤣🥧🤦👩‍🎓'; - const wakuMessage = await WakuMessage.fromUtf8String( - messageText, - TestContentTopic - ); - - const decodedText = wakuMessage.payloadAsUtf8; - - expect(decodedText).to.eq(messageText); - }); -}); diff --git a/src/lib/waku_message/index.node.spec.ts b/src/lib/waku_message/index.node.spec.ts new file mode 100644 index 0000000000..96dc506fea --- /dev/null +++ b/src/lib/waku_message/index.node.spec.ts @@ -0,0 +1,177 @@ +import { expect } from 'chai'; +import debug from 'debug'; +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore: No types available +import TCP from 'libp2p-tcp'; + +import { + makeLogFileName, + NimWaku, + NOISE_KEY_1, + WakuRelayMessage, +} from '../../test_utils'; +import { delay } from '../delay'; +import { hexToBuf } from '../utils'; +import { Waku } from '../waku'; + +import { + generatePrivateKey, + generateSymmetricKey, + getPublicKey, +} from './version_1'; + +import { WakuMessage } from './index'; + +const dbg = debug('waku:test:message'); + +const TestContentTopic = '/test/1/waku-message/utf8'; + +describe('Waku Message [node only]', function () { + describe('Interop: Nim', function () { + let waku: Waku; + let nimWaku: NimWaku; + + beforeEach(async function () { + this.timeout(30_000); + + waku = await Waku.create({ + staticNoiseKey: NOISE_KEY_1, + libp2p: { + addresses: { listen: ['/ip4/0.0.0.0/tcp/0'] }, + modules: { transport: [TCP] }, + }, + }); + + const multiAddrWithId = waku.getLocalMultiaddrWithID(); + nimWaku = new NimWaku(makeLogFileName(this)); + await nimWaku.start({ staticnode: multiAddrWithId, rpcPrivate: true }); + + await new Promise((resolve) => + waku.libp2p.pubsub.once('gossipsub:heartbeat', resolve) + ); + }); + + afterEach(async function () { + nimWaku ? nimWaku.stop() : null; + waku ? await waku.stop() : null; + }); + + it('JS decrypts nim message [asymmetric, no signature]', async function () { + this.timeout(10000); + await delay(200); + + const messageText = 'Here is an encrypted message.'; + const message: WakuRelayMessage = { + contentTopic: TestContentTopic, + payload: Buffer.from(messageText, 'utf-8').toString('hex'), + }; + + const privateKey = generatePrivateKey(); + + waku.relay.addDecryptionKey(privateKey); + + const receivedMsgPromise: Promise = new Promise( + (resolve) => { + waku.relay.addObserver(resolve); + } + ); + + const publicKey = getPublicKey(privateKey); + dbg('Post message'); + await nimWaku.postAsymmetricMessage(message, publicKey); + + const receivedMsg = await receivedMsgPromise; + + expect(receivedMsg.contentTopic).to.eq(message.contentTopic); + expect(receivedMsg.version).to.eq(1); + expect(receivedMsg.payloadAsUtf8).to.eq(messageText); + }); + + it('Js encrypts message for nim [asymmetric, no signature]', async function () { + this.timeout(5000); + + const keyPair = await nimWaku.getAsymmetricKeyPair(); + const privateKey = hexToBuf(keyPair.privateKey); + const publicKey = hexToBuf(keyPair.publicKey); + + const messageText = 'This is a message I am going to encrypt'; + const message = await WakuMessage.fromUtf8String( + messageText, + TestContentTopic, + { + encPublicKey: publicKey, + } + ); + + await waku.relay.send(message); + + let msgs: WakuRelayMessage[] = []; + + while (msgs.length === 0) { + await delay(200); + msgs = await nimWaku.getAsymmetricMessages(privateKey); + } + + expect(msgs[0].contentTopic).to.equal(message.contentTopic); + expect(hexToBuf(msgs[0].payload).toString('utf-8')).to.equal(messageText); + }); + + it('JS decrypts nim message [symmetric, no signature]', async function () { + this.timeout(10000); + await delay(200); + + const messageText = 'Here is a message encrypted in a symmetric manner.'; + const message: WakuRelayMessage = { + contentTopic: TestContentTopic, + payload: Buffer.from(messageText, 'utf-8').toString('hex'), + }; + + const symKey = generateSymmetricKey(); + + waku.relay.addDecryptionKey(symKey); + + const receivedMsgPromise: Promise = new Promise( + (resolve) => { + waku.relay.addObserver(resolve); + } + ); + + dbg('Post message'); + await nimWaku.postSymmetricMessage(message, symKey); + + const receivedMsg = await receivedMsgPromise; + + expect(receivedMsg.contentTopic).to.eq(message.contentTopic); + expect(receivedMsg.version).to.eq(1); + expect(receivedMsg.payloadAsUtf8).to.eq(messageText); + }); + + it('Js encrypts message for nim [symmetric, no signature]', async function () { + this.timeout(5000); + + const symKey = await nimWaku.getSymmetricKey(); + + const messageText = + 'This is a message I am going to encrypt with a symmetric key'; + const message = await WakuMessage.fromUtf8String( + messageText, + TestContentTopic, + { + symKey: symKey, + } + ); + + await waku.relay.send(message); + + let msgs: WakuRelayMessage[] = []; + + while (msgs.length === 0) { + await delay(200); + msgs = await nimWaku.getSymmetricMessages(symKey); + } + + expect(msgs[0].contentTopic).to.equal(message.contentTopic); + expect(hexToBuf(msgs[0].payload).toString('utf-8')).to.equal(messageText); + }); + }); +}); diff --git a/src/lib/waku_message/index.spec.ts b/src/lib/waku_message/index.spec.ts index 9795c045e7..5cc9bd4f40 100644 --- a/src/lib/waku_message/index.spec.ts +++ b/src/lib/waku_message/index.spec.ts @@ -1,177 +1,134 @@ import { expect } from 'chai'; -import debug from 'debug'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore: No types available -import TCP from 'libp2p-tcp'; +import fc from 'fast-check'; -import { - makeLogFileName, - NimWaku, - NOISE_KEY_1, - WakuRelayMessage, -} from '../../test_utils'; -import { delay } from '../delay'; -import { hexToBuf } from '../utils'; -import { Waku } from '../waku'; - -import { - generatePrivateKey, - generateSymmetricKey, - getPublicKey, -} from './version_1'; +import { getPublicKey } from './version_1'; import { WakuMessage } from './index'; -const dbg = debug('waku:test:message'); - const TestContentTopic = '/test/1/waku-message/utf8'; -describe('Waku Message: Node only', function () { - describe('Interop: Nim', function () { - let waku: Waku; - let nimWaku: NimWaku; +describe('Waku Message: Browser & Node', function () { + it('Waku message round trip binary serialization [clear]', async function () { + await fc.assert( + fc.asyncProperty(fc.string(), async (s) => { + const msg = await WakuMessage.fromUtf8String(s, TestContentTopic); + const binary = msg.encode(); + const actual = await WakuMessage.decode(binary); - beforeEach(async function () { - this.timeout(30_000); + expect(actual).to.deep.equal(msg); + }) + ); + }); - waku = await Waku.create({ - staticNoiseKey: NOISE_KEY_1, - libp2p: { - addresses: { listen: ['/ip4/0.0.0.0/tcp/0'] }, - modules: { transport: [TCP] }, - }, - }); + it('Payload to utf-8', async function () { + await fc.assert( + fc.asyncProperty(fc.string(), async (s) => { + const msg = await WakuMessage.fromUtf8String(s, TestContentTopic); + const utf8 = msg.payloadAsUtf8; - const multiAddrWithId = waku.getLocalMultiaddrWithID(); - nimWaku = new NimWaku(makeLogFileName(this)); - await nimWaku.start({ staticnode: multiAddrWithId, rpcPrivate: true }); + return utf8 === s; + }) + ); + }); - await new Promise((resolve) => - waku.libp2p.pubsub.once('gossipsub:heartbeat', resolve) - ); - }); + it('Waku message round trip binary encryption [asymmetric, no signature]', async function () { + await fc.assert( + fc.asyncProperty( + fc.uint8Array({ minLength: 1 }), + fc.uint8Array({ minLength: 32, maxLength: 32 }), + async (payload, privKey) => { + const publicKey = getPublicKey(privKey); - afterEach(async function () { - nimWaku ? nimWaku.stop() : null; - waku ? await waku.stop() : null; - }); + const msg = await WakuMessage.fromBytes(payload, TestContentTopic, { + encPublicKey: publicKey, + }); - it('JS decrypts nim message [asymmetric, no signature]', async function () { - this.timeout(10000); - await delay(200); + const wireBytes = msg.encode(); + const actual = await WakuMessage.decode(wireBytes, [privKey]); - const messageText = 'Here is an encrypted message.'; - const message: WakuRelayMessage = { - contentTopic: TestContentTopic, - payload: Buffer.from(messageText, 'utf-8').toString('hex'), - }; - - const privateKey = generatePrivateKey(); - - waku.relay.addDecryptionKey(privateKey); - - const receivedMsgPromise: Promise = new Promise( - (resolve) => { - waku.relay.addObserver(resolve); + expect(actual?.payload).to.deep.equal(payload); } - ); + ) + ); + }); - const publicKey = getPublicKey(privateKey); - dbg('Post message'); - await nimWaku.postAsymmetricMessage(message, publicKey); + it('Waku message round trip binary encryption [asymmetric, signature]', async function () { + await fc.assert( + fc.asyncProperty( + fc.uint8Array({ minLength: 1 }), + fc.uint8Array({ minLength: 32, maxLength: 32 }), + fc.uint8Array({ minLength: 32, maxLength: 32 }), + async (payload, sigPrivKey, encPrivKey) => { + const sigPubKey = getPublicKey(sigPrivKey); + const encPubKey = getPublicKey(encPrivKey); - const receivedMsg = await receivedMsgPromise; + const msg = await WakuMessage.fromBytes(payload, TestContentTopic, { + encPublicKey: encPubKey, + sigPrivKey: sigPrivKey, + }); - expect(receivedMsg.contentTopic).to.eq(message.contentTopic); - expect(receivedMsg.version).to.eq(1); - expect(receivedMsg.payloadAsUtf8).to.eq(messageText); - }); + const wireBytes = msg.encode(); + const actual = await WakuMessage.decode(wireBytes, [encPrivKey]); - it('Js encrypts message for nim [asymmetric, no signature]', async function () { - this.timeout(5000); - - const keyPair = await nimWaku.getAsymmetricKeyPair(); - const privateKey = hexToBuf(keyPair.privateKey); - const publicKey = hexToBuf(keyPair.publicKey); - - const messageText = 'This is a message I am going to encrypt'; - const message = await WakuMessage.fromUtf8String( - messageText, - TestContentTopic, - { - encPublicKey: publicKey, + expect(actual?.payload).to.deep.equal(payload); + expect(actual?.signaturePublicKey).to.deep.equal(sigPubKey); } - ); + ) + ); + }); - await waku.relay.send(message); + it('Waku message round trip binary encryption [symmetric, no signature]', async function () { + await fc.assert( + fc.asyncProperty( + fc.uint8Array({ minLength: 1 }), + fc.uint8Array({ minLength: 32, maxLength: 32 }), + async (payload, key) => { + const msg = await WakuMessage.fromBytes(payload, TestContentTopic, { + symKey: key, + }); - let msgs: WakuRelayMessage[] = []; + const wireBytes = msg.encode(); + const actual = await WakuMessage.decode(wireBytes, [key]); - while (msgs.length === 0) { - await delay(200); - msgs = await nimWaku.getAsymmetricMessages(privateKey); - } - - expect(msgs[0].contentTopic).to.equal(message.contentTopic); - expect(hexToBuf(msgs[0].payload).toString('utf-8')).to.equal(messageText); - }); - - it('JS decrypts nim message [symmetric, no signature]', async function () { - this.timeout(10000); - await delay(200); - - const messageText = 'Here is a message encrypted in a symmetric manner.'; - const message: WakuRelayMessage = { - contentTopic: TestContentTopic, - payload: Buffer.from(messageText, 'utf-8').toString('hex'), - }; - - const symKey = generateSymmetricKey(); - - waku.relay.addDecryptionKey(symKey); - - const receivedMsgPromise: Promise = new Promise( - (resolve) => { - waku.relay.addObserver(resolve); + expect(actual?.payload).to.deep.equal(payload); } - ); + ) + ); + }); - dbg('Post message'); - await nimWaku.postSymmetricMessage(message, symKey); + it('Waku message round trip binary encryption [symmetric, signature]', async function () { + await fc.assert( + fc.asyncProperty( + fc.uint8Array({ minLength: 1 }), + fc.uint8Array({ minLength: 32, maxLength: 32 }), + fc.uint8Array({ minLength: 32, maxLength: 32 }), + async (payload, sigPrivKey, symKey) => { + const sigPubKey = getPublicKey(sigPrivKey); - const receivedMsg = await receivedMsgPromise; + const msg = await WakuMessage.fromBytes(payload, TestContentTopic, { + symKey: symKey, + sigPrivKey: sigPrivKey, + }); - expect(receivedMsg.contentTopic).to.eq(message.contentTopic); - expect(receivedMsg.version).to.eq(1); - expect(receivedMsg.payloadAsUtf8).to.eq(messageText); - }); + const wireBytes = msg.encode(); + const actual = await WakuMessage.decode(wireBytes, [symKey]); - it('Js encrypts message for nim [symmetric, no signature]', async function () { - this.timeout(5000); - - const symKey = await nimWaku.getSymmetricKey(); - - const messageText = - 'This is a message I am going to encrypt with a symmetric key'; - const message = await WakuMessage.fromUtf8String( - messageText, - TestContentTopic, - { - symKey: symKey, + expect(actual?.payload).to.deep.equal(payload); + expect(actual?.signaturePublicKey).to.deep.equal(sigPubKey); } - ); + ) + ); + }); - await waku.relay.send(message); + it('Waku message round trip utf-8 including emojis', async function () { + const messageText = '😁🤣🥧🤦👩‍🎓'; + const wakuMessage = await WakuMessage.fromUtf8String( + messageText, + TestContentTopic + ); - let msgs: WakuRelayMessage[] = []; + const decodedText = wakuMessage.payloadAsUtf8; - while (msgs.length === 0) { - await delay(200); - msgs = await nimWaku.getSymmetricMessages(symKey); - } - - expect(msgs[0].contentTopic).to.equal(message.contentTopic); - expect(hexToBuf(msgs[0].payload).toString('utf-8')).to.equal(messageText); - }); + expect(decodedText).to.eq(messageText); }); }); diff --git a/src/lib/waku_message/version_1.browser.spec.ts b/src/lib/waku_message/version_1.spec.ts similarity index 100% rename from src/lib/waku_message/version_1.browser.spec.ts rename to src/lib/waku_message/version_1.spec.ts diff --git a/src/lib/waku_relay/index.spec.ts b/src/lib/waku_relay/index.node.spec.ts similarity index 98% rename from src/lib/waku_relay/index.spec.ts rename to src/lib/waku_relay/index.node.spec.ts index c03a187540..9689882b3b 100644 --- a/src/lib/waku_relay/index.spec.ts +++ b/src/lib/waku_relay/index.node.spec.ts @@ -18,8 +18,10 @@ const log = debug('waku:test'); const TestContentTopic = '/test/1/waku-relay/utf8'; -describe('Waku Relay', () => { - describe('js only', () => { +describe('Waku Relay [node only]', () => { + // Node needed as we don't have a way to connect 2 js waku + // nodes in the browser yet + describe('2 js nodes', () => { afterEach(function () { if (this.currentTest?.state === 'failed') { console.log(`Test failed, log file name is ${makeLogFileName(this)}`); diff --git a/src/lib/waku_store/index.spec.ts b/src/lib/waku_store/index.node.spec.ts similarity index 100% rename from src/lib/waku_store/index.spec.ts rename to src/lib/waku_store/index.node.spec.ts diff --git a/src/test_utils/log_file.spec.ts b/src/test_utils/log_file.node.spec.ts similarity index 100% rename from src/test_utils/log_file.spec.ts rename to src/test_utils/log_file.node.spec.ts diff --git a/src/test_utils/nim_waku.spec.ts b/src/test_utils/nim_waku.node.spec.ts similarity index 100% rename from src/test_utils/nim_waku.spec.ts rename to src/test_utils/nim_waku.node.spec.ts