Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions apps/api/src/admin/analytics.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AnalyticsController } from './analytics.controller';
import { AnalyticsService } from './analytics.service';
import { InternalKeyGuard } from './internal-key.guard';

const mockService = {
getOverview: jest.fn().mockResolvedValue({ totalTvl: 0, totalSwapCount: 0 }),
getTvl: jest.fn().mockResolvedValue({ interval: '7d', series: [] }),
getVolume: jest.fn().mockResolvedValue({ interval: '7d', series: [] }),
getFees: jest.fn().mockResolvedValue({ byPool: [] }),
};

describe('AnalyticsController', () => {
let controller: AnalyticsController;
let module: TestingModule;

beforeEach(async () => {
module = await Test.createTestingModule({
controllers: [AnalyticsController],
providers: [
{ provide: AnalyticsService, useValue: mockService },
{ provide: InternalKeyGuard, useValue: { canActivate: () => true } },
],
}).compile();

controller = module.get<AnalyticsController>(AnalyticsController);
jest.clearAllMocks();
});

afterEach(async () => {
await module.close();
});

it('returns the analytics overview', async () => {
mockService.getOverview.mockResolvedValue({ totalTvl: 1000 });

const result = await controller.getOverview();

expect(mockService.getOverview).toHaveBeenCalled();
expect(result).toEqual({ totalTvl: 1000 });
});

it('returns TVL timeseries', async () => {
mockService.getTvl.mockResolvedValue({ interval: '7d', series: [] });

const result = await controller.getTvl({ interval: '7d' } as any);

expect(mockService.getTvl).toHaveBeenCalledWith('7d');
expect(result).toEqual({ interval: '7d', series: [] });
});

it('returns volume timeseries', async () => {
mockService.getVolume.mockResolvedValue({ interval: '1d', series: [] });

const result = await controller.getVolume({ interval: '1d' } as any);

expect(mockService.getVolume).toHaveBeenCalledWith('1d');
expect(result).toEqual({ interval: '1d', series: [] });
});

it('returns fee totals', async () => {
mockService.getFees.mockResolvedValue({ byPool: [{ poolId: 'p1', feesAmount0: '10', feesAmount1: '20' }] });

const result = await controller.getFees();

expect(mockService.getFees).toHaveBeenCalled();
expect(result).toEqual({ byPool: [{ poolId: 'p1', feesAmount0: '10', feesAmount1: '20' }] });
});
});
3 changes: 3 additions & 0 deletions apps/api/src/admin/analytics.controller.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { Controller, Get, Query, UseGuards } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { AnalyticsService } from './analytics.service';
import { InternalKeyGuard } from './internal-key.guard';
import { TimeSeriesQueryDto } from './dto/analytics-query.dto';
import { SWAGGER_TAGS } from '../swagger.constants';

@ApiTags(SWAGGER_TAGS.ADMIN)
@Controller('admin/analytics')
@UseGuards(InternalKeyGuard)
export class AnalyticsController {
Expand Down
3 changes: 3 additions & 0 deletions apps/api/src/swagger.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ export const SWAGGER_TAGS = {
/** Indexer status and queue-health endpoints. */
INDEXER: 'indexer',

/** Internal analytics and monitoring endpoints. */
ADMIN: 'admin',

/** Transaction relay endpoints. */
TRANSACTIONS: 'transactions',
} as const;
Expand Down