Skip to content

Commit

Permalink
test: add mocha test infrastructure with core module tests
Browse files Browse the repository at this point in the history
- Add sinon for mocking
- Create test files for NodeFactory, PinningService, PubsubHandler, and HttpServer
- Implement basic test cases with proper assertions
- Set up test infrastructure with before/after hooks

Co-Authored-By: Nico Krause <[email protected]>
  • Loading branch information
devin-ai-integration[bot] and silkroadnomad committed Dec 22, 2024
1 parent c4d9f2e commit d20499b
Show file tree
Hide file tree
Showing 9 changed files with 251 additions and 1 deletion.
3 changes: 2 additions & 1 deletion restructure/relay/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"chai": "^5.1.2",
"eslint": "^9.17.0",
"globals": "^15.14.0",
"mocha": "^10.8.2"
"mocha": "^10.8.2",
"sinon": "^17.0.1"
}
}
Empty file.
80 changes: 80 additions & 0 deletions restructure/relay/tests/unit/testHttpServer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { expect } from 'chai';
import sinon from 'sinon';
import { createHttpServer } from '../../src/httpServer.js';
import express from 'express';

describe('HttpServer', () => {
let sandbox;
let mockExpress;
let mockNode;
let mockPinningService;

beforeEach(() => {
sandbox = sinon.createSandbox();
mockExpress = {
get: sandbox.stub(),
post: sandbox.stub(),
use: sandbox.stub(),
listen: sandbox.stub()
};
mockNode = {
peerId: { toString: () => 'testPeerId' },
getMultiaddrs: sandbox.stub().returns(['testAddr'])
};
mockPinningService = {
pinContent: sandbox.stub().resolves(),
calculatePinningFee: sandbox.stub().returns(1000)
};

sandbox.stub(express, 'Router').returns(mockExpress);
});

afterEach(() => {
sandbox.restore();
});

describe('createHttpServer', () => {
it('should set up routes correctly', () => {
createHttpServer(mockNode, mockPinningService);

expect(mockExpress.get.called).to.be.true;
expect(mockExpress.post.called).to.be.true;
});

it('should handle pin requests correctly', async () => {
const mockReq = {
body: {
cid: 'QmTest',
duration: 30
}
};
const mockRes = {
json: sandbox.stub(),
status: sandbox.stub().returnsThis()
};

createHttpServer(mockNode, mockPinningService);
const pinHandler = mockExpress.post.getCall(0).args[1];
await pinHandler(mockReq, mockRes);

expect(mockPinningService.pinContent.called).to.be.true;
expect(mockRes.json.called).to.be.true;
});

it('should handle errors gracefully', async () => {
const mockReq = {
body: { invalid: 'request' }
};
const mockRes = {
json: sandbox.stub(),
status: sandbox.stub().returnsThis()
};

createHttpServer(mockNode, mockPinningService);
const pinHandler = mockExpress.post.getCall(0).args[1];
await pinHandler(mockReq, mockRes);

expect(mockRes.status.calledWith(400)).to.be.true;
});
});
});
Empty file.
48 changes: 48 additions & 0 deletions restructure/relay/tests/unit/testNodeFactory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { expect } from 'chai';
import sinon from 'sinon';
import { createNode } from '../../src/nodeFactory.js';
import { noise } from '@chainsafe/libp2p-noise';
import { yamux } from '@chainsafe/libp2p-yamux';
import { tcp } from '@libp2p/tcp';
import { webSockets } from '@libp2p/websockets';
import { bootstrap } from '@libp2p/bootstrap';
import { identify } from '@libp2p/identify';
import { gossipsub } from '@chainsafe/libp2p-gossipsub';

describe('NodeFactory', () => {
let sandbox;

beforeEach(() => {
sandbox = sinon.createSandbox();
});

afterEach(() => {
sandbox.restore();
});

describe('createNode', () => {
it('should create a node with correct configuration', async () => {
// Test implementation
const node = await createNode();

expect(node).to.exist;
expect(node.services).to.have.property('pubsub');
expect(node.services).to.have.property('identify');
expect(node.connectionManager).to.exist;
});

it('should configure transport protocols correctly', async () => {
const node = await createNode();

expect(node.transportManager.getTransports()).to.have.lengthOf.at.least(2);
expect(node.services.identify).to.exist;
});

it('should initialize with correct connection encryption', async () => {
const node = await createNode();

expect(node.connectionEncrypter).to.exist;
expect(node.services.identify.multicodecs).to.include('/noise');
});
});
});
57 changes: 57 additions & 0 deletions restructure/relay/tests/unit/testPinningService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { expect } from 'chai';
import sinon from 'sinon';
import { PinningService } from '../../src/pinner/pinningService.js';

describe('PinningService', () => {
let sandbox;
let pinningService;
let mockHelia;
let mockOrbitdb;
let mockElectrumClient;

beforeEach(() => {
sandbox = sinon.createSandbox();
mockHelia = {
blockstore: {
put: sandbox.stub().resolves(),
get: sandbox.stub().resolves()
}
};
mockOrbitdb = {
id: 'test-id',
identity: { id: 'test-identity' }
};
mockElectrumClient = {
request: sandbox.stub().resolves()
};

pinningService = new PinningService(mockHelia, mockOrbitdb, mockElectrumClient);
});

afterEach(() => {
sandbox.restore();
});

describe('calculatePinningFee', () => {
it('should calculate fee based on size and duration', () => {
const size = 1024 * 1024; // 1MB
const duration = 30; // 30 days

const fee = pinningService.calculatePinningFee(size, duration);

expect(fee).to.be.a('number');
expect(fee).to.be.greaterThan(0);
});
});

describe('pinContent', () => {
it('should pin content successfully', async () => {
const cid = 'QmTest';
const duration = 30;

await pinningService.pinContent(cid, duration);

expect(mockHelia.blockstore.put.called).to.be.true;
});
});
});
64 changes: 64 additions & 0 deletions restructure/relay/tests/unit/testPubsubHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { expect } from 'chai';
import sinon from 'sinon';
import { setupPubsub } from '../../src/pubsubHandler.js';

describe('PubsubHandler', () => {
let sandbox;
let mockNode;
let mockPinningService;

beforeEach(() => {
sandbox = sinon.createSandbox();
mockNode = {
services: {
pubsub: {
subscribe: sandbox.stub().resolves(),
publish: sandbox.stub().resolves(),
addEventListener: sandbox.stub()
}
}
};
mockPinningService = {
pinContent: sandbox.stub().resolves(),
calculatePinningFee: sandbox.stub().returns(1000)
};
});

afterEach(() => {
sandbox.restore();
});

describe('setupPubsub', () => {
it('should subscribe to the correct topics', async () => {
await setupPubsub(mockNode, mockPinningService);
expect(mockNode.services.pubsub.subscribe.called).to.be.true;
});

it('should handle incoming messages correctly', async () => {
const message = {
data: new TextEncoder().encode(JSON.stringify({
action: 'pin',
cid: 'QmTest',
duration: 30
}))
};

await setupPubsub(mockNode, mockPinningService);
const messageHandler = mockNode.services.pubsub.addEventListener.getCall(0).args[1];
await messageHandler(message);

expect(mockPinningService.pinContent.called).to.be.true;
});

it('should handle invalid messages gracefully', async () => {
const invalidMessage = {
data: new TextEncoder().encode('invalid json')
};

await setupPubsub(mockNode, mockPinningService);
const messageHandler = mockNode.services.pubsub.addEventListener.getCall(0).args[1];

expect(() => messageHandler(invalidMessage)).to.not.throw();
});
});
});
Empty file.
Empty file.

0 comments on commit d20499b

Please sign in to comment.