-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Admin
committed
Dec 5, 2024
1 parent
70426ac
commit e414625
Showing
6 changed files
with
308 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
module.exports = { | ||
preset: 'ts-jest', | ||
testEnvironment: 'node', | ||
roots: ['<rootDir>/src'], | ||
testMatch: ['**/__tests__/**/*.test.ts'], | ||
moduleFileExtensions: ['ts', 'js', 'json', 'node'], | ||
collectCoverageFrom: [ | ||
'src/**/*.ts', | ||
'!src/**/*.d.ts', | ||
'!src/**/__tests__/**' | ||
], | ||
coverageDirectory: 'coverage', | ||
setupFilesAfterEnv: ['<rootDir>/src/__tests__/setup.ts'] | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import { MongoDBAdapter } from '../../db/mongodb'; | ||
import { BlockData, ContractConfig, EventData } from '../../db/adapter'; | ||
import { describe, it, expect, beforeAll, afterAll, beforeEach } from '@jest/globals'; | ||
|
||
describe('MongoDBAdapter', () => { | ||
let adapter: MongoDBAdapter; | ||
|
||
beforeAll(async () => { | ||
adapter = new MongoDBAdapter(process.env.MONGODB_URI!); | ||
await adapter.connect(); | ||
}); | ||
|
||
afterAll(async () => { | ||
await adapter.disconnect(); | ||
}); | ||
|
||
beforeEach(async () => { | ||
// Clear collections before each test | ||
const db = (adapter as any).client.db(); | ||
await db.collection('blocks').deleteMany({}); | ||
await db.collection('contracts').deleteMany({}); | ||
await db.collection('events').deleteMany({}); | ||
}); | ||
|
||
describe('Blocks', () => { | ||
const mockBlock: BlockData = { | ||
number: 1, | ||
hash: '0x123', | ||
timestamp: 1000, | ||
transactions: ['0xabc'] | ||
}; | ||
|
||
it('should save and retrieve a block', async () => { | ||
await adapter.saveBlock(mockBlock); | ||
const retrieved = await adapter.getBlock(mockBlock.number); | ||
expect(retrieved).toEqual(mockBlock); | ||
}); | ||
|
||
it('should get latest block', async () => { | ||
await adapter.saveBlock({ ...mockBlock, number: 1 }); | ||
await adapter.saveBlock({ ...mockBlock, number: 2 }); | ||
const latest = await adapter.getLatestBlock(); | ||
expect(latest?.number).toBe(2); | ||
}); | ||
}); | ||
|
||
describe('Contracts', () => { | ||
const mockContract: ContractConfig = { | ||
address: '0x123', | ||
name: 'Test Contract', | ||
abi: '[]', | ||
events: [], | ||
isActive: true, | ||
createdAt: new Date(), | ||
updatedAt: new Date() | ||
}; | ||
|
||
it('should add and retrieve a contract', async () => { | ||
await adapter.addContract(mockContract); | ||
const retrieved = await adapter.getContract(mockContract.address); | ||
expect(retrieved?.address).toBe(mockContract.address); | ||
}); | ||
|
||
it('should list active contracts', async () => { | ||
await adapter.addContract(mockContract); | ||
await adapter.addContract({ ...mockContract, address: '0x456', isActive: false }); | ||
const activeContracts = await adapter.listContracts(true); | ||
expect(activeContracts.length).toBe(1); | ||
expect(activeContracts[0].address).toBe('0x123'); | ||
}); | ||
}); | ||
|
||
describe('Events', () => { | ||
const mockEvent: EventData = { | ||
id: '1', | ||
contractAddress: '0x123', | ||
eventName: 'Transfer', | ||
blockNumber: 1, | ||
transactionHash: '0xabc', | ||
timestamp: 1000, | ||
returnValues: { from: '0x123', to: '0x456', value: '1000' }, | ||
raw: { data: '0x', topics: [] } | ||
}; | ||
|
||
it('should save and retrieve events', async () => { | ||
await adapter.saveEvent(mockEvent); | ||
const events = await adapter.getEvents(mockEvent.contractAddress); | ||
expect(events.length).toBe(1); | ||
expect(events[0].id).toBe(mockEvent.id); | ||
}); | ||
|
||
it('should query events with filters', async () => { | ||
await adapter.saveEvent(mockEvent); | ||
await adapter.saveEvent({ ...mockEvent, id: '2', blockNumber: 2 }); | ||
|
||
const result = await adapter.queryEvents({ | ||
contractAddress: '0x123', | ||
fromBlock: 1, | ||
toBlock: 1 | ||
}); | ||
|
||
expect(result.events.length).toBe(1); | ||
expect(result.total).toBe(1); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
import { describe, it, expect, beforeAll, afterAll, beforeEach } from '@jest/globals'; | ||
import express from 'express'; | ||
import request from 'supertest'; | ||
import { MongoDBAdapter } from '../../db/mongodb'; | ||
import { createContractRoutes } from '../../routes/contracts'; | ||
import { createEventRoutes } from '../../routes/events'; | ||
import { createBlockRoutes } from '../../routes/blocks'; | ||
|
||
describe('API Routes', () => { | ||
let app: express.Application; | ||
let db: MongoDBAdapter; | ||
|
||
beforeAll(async () => { | ||
db = new MongoDBAdapter(process.env.MONGODB_URI!); | ||
await db.connect(); | ||
|
||
app = express(); | ||
app.use(express.json()); | ||
app.use('/contracts', createContractRoutes(db, '../out', '../deployments')); | ||
app.use('/events', createEventRoutes(db)); | ||
app.use('/blocks', createBlockRoutes(db)); | ||
}); | ||
|
||
afterAll(async () => { | ||
await db.disconnect(); | ||
}); | ||
|
||
beforeEach(async () => { | ||
const dbClient = (db as any).client.db(); | ||
await dbClient.collection('blocks').deleteMany({}); | ||
await dbClient.collection('contracts').deleteMany({}); | ||
await dbClient.collection('events').deleteMany({}); | ||
}); | ||
|
||
describe('Contract Routes', () => { | ||
const mockContract = { | ||
address: '0x123', | ||
name: 'Test Contract', | ||
abi: '[]' | ||
}; | ||
|
||
it('should add a new contract', async () => { | ||
const response = await request(app) | ||
.post('/contracts') | ||
.send(mockContract); | ||
|
||
expect(response.status).toBe(200); | ||
expect(response.body.message).toBe('Contract added successfully'); | ||
}); | ||
|
||
it('should list contracts', async () => { | ||
await db.addContract({ | ||
...mockContract, | ||
events: [], | ||
isActive: true | ||
}); | ||
|
||
const response = await request(app) | ||
.get('/contracts'); | ||
|
||
expect(response.status).toBe(200); | ||
expect(response.body.length).toBe(1); | ||
expect(response.body[0].address).toBe(mockContract.address); | ||
}); | ||
}); | ||
|
||
describe('Event Routes', () => { | ||
const mockEvent = { | ||
name: 'Transfer', | ||
signature: 'Transfer(address,address,uint256)', | ||
abi: 'event Transfer(address indexed from, address indexed to, uint256 value)' | ||
}; | ||
|
||
beforeEach(async () => { | ||
await db.addContract({ | ||
address: '0x123', | ||
name: 'Test Contract', | ||
abi: '[]', | ||
events: [], | ||
isActive: true | ||
}); | ||
}); | ||
|
||
it('should add an event to a contract', async () => { | ||
const response = await request(app) | ||
.post('/events/contracts/0x123/events') | ||
.send(mockEvent); | ||
|
||
expect(response.status).toBe(200); | ||
expect(response.body.message).toBe('Event added successfully'); | ||
}); | ||
|
||
it('should query events', async () => { | ||
const response = await request(app) | ||
.post('/events/query') | ||
.send({ | ||
contractAddress: '0x123', | ||
fromBlock: 1, | ||
toBlock: 100 | ||
}); | ||
|
||
expect(response.status).toBe(200); | ||
expect(response.body).toHaveProperty('events'); | ||
expect(response.body).toHaveProperty('total'); | ||
}); | ||
}); | ||
|
||
describe('Block Routes', () => { | ||
const mockBlock = { | ||
number: 1, | ||
hash: '0x123', | ||
timestamp: 1000, | ||
transactions: [] | ||
}; | ||
|
||
beforeEach(async () => { | ||
await db.saveBlock(mockBlock); | ||
}); | ||
|
||
it('should get block by number', async () => { | ||
const response = await request(app) | ||
.get('/blocks/1'); | ||
|
||
expect(response.status).toBe(200); | ||
expect(response.body.number).toBe(1); | ||
expect(response.body.hash).toBe('0x123'); | ||
}); | ||
|
||
it('should get indexing status', async () => { | ||
const response = await request(app) | ||
.get('/blocks/status'); | ||
|
||
expect(response.status).toBe(200); | ||
expect(response.body).toHaveProperty('latestIndexedBlock'); | ||
expect(response.body).toHaveProperty('totalIndexedBlocks'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { MongoMemoryServer } from 'mongodb-memory-server'; | ||
import { MongoClient } from 'mongodb'; | ||
import '@jest/globals'; | ||
|
||
let mongoServer: MongoMemoryServer; | ||
let mongoClient: MongoClient; | ||
|
||
beforeAll(async () => { | ||
mongoServer = await MongoMemoryServer.create(); | ||
const mongoUri = mongoServer.getUri(); | ||
mongoClient = new MongoClient(mongoUri); | ||
await mongoClient.connect(); | ||
|
||
// Set environment variables for testing | ||
process.env.MONGODB_URI = mongoUri; | ||
process.env.ETHEREUM_RPC_URL = 'http://localhost:8545'; // For local testing | ||
}); | ||
|
||
afterAll(async () => { | ||
if (mongoClient) { | ||
await mongoClient.close(); | ||
} | ||
if (mongoServer) { | ||
await mongoServer.stop(); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters