Skip to content

Commit

Permalink
Feature/#37 가격 상승률 기반 주식 리스트 조회 API 기능 구현 (#176)
Browse files Browse the repository at this point in the history
  • Loading branch information
xjfcnfw3 authored Nov 18, 2024
2 parents d2b56d4 + 88e3b5d commit bcc9a09
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 0 deletions.
6 changes: 6 additions & 0 deletions packages/backend/src/stock/stock.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,4 +228,10 @@ export class StockController {
async getTopStocksByViews(@LimitQuery(5) limit: number) {
return await this.stockService.getTopStocksByViews(limit);
}

@Get('topGainers')
@ApiGetStocks('가격 상승률 기반 주식 리스트 조회 API')
async getTopStocksByGainers(@LimitQuery(20) limit: number) {
return await this.stockService.getTopStocksByGainers(limit);
}
}
135 changes: 135 additions & 0 deletions packages/backend/src/stock/stock.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable max-lines-per-function */
import { instanceToPlain } from 'class-transformer';
import { DataSource } from 'typeorm';
import { Logger } from 'winston';
Expand Down Expand Up @@ -121,6 +122,140 @@ describe('StockService 테스트', () => {
).rejects.toThrow('you are not owner of user stock');
});

test('주식 조회수 기준 상위 데이터를 반환한다.', async () => {
const limit = 5;
// QueryBuilder Mock
const queryBuilderMock = {
leftJoin: jest.fn().mockReturnThis(),
select: jest.fn().mockReturnThis(),
orderBy: jest.fn().mockReturnThis(),
limit: jest.fn().mockReturnThis(),
getRawMany: jest.fn().mockResolvedValue([
{
id: 'A005930',
name: '삼성전자',
currentPrice: '100000.0',
changeRate: '2.5',
volume: '500000',
marketCap: '500000000000.00',
},
{
id: 'A051910',
name: 'LG화학',
currentPrice: '75000.0',
changeRate: '-1.2',
volume: '300000',
marketCap: '20000000000.00',
},
]),
};

// Manager Mock
const managerMock = {
getRepository: jest.fn().mockReturnValue({
createQueryBuilder: jest.fn().mockReturnValue(queryBuilderMock),
}),
};
const dataSource = createDataSourceMock(managerMock);
const stockService = new StockService(dataSource as DataSource, logger);

const result = await stockService.getTopStocksByViews(limit);

expect(managerMock.getRepository).toHaveBeenCalledWith(Stock);
expect(queryBuilderMock.orderBy).toHaveBeenCalledWith(
'stock.views',
'DESC',
);
expect(queryBuilderMock.limit).toHaveBeenCalledWith(limit);
expect(queryBuilderMock.getRawMany).toHaveBeenCalled();

expect(instanceToPlain(result)).toEqual([
{
id: 'A005930',
name: '삼성전자',
currentPrice: 100000.0,
changeRate: 2.5,
volume: 500000,
marketCap: '500000000000.00',
},
{
id: 'A051910',
name: 'LG화학',
currentPrice: 75000.0,
changeRate: -1.2,
volume: 300000,
marketCap: '20000000000.00',
},
]);
});

test('주식 상승률 기준 상위 데이터를 반환한다.', async () => {
const limit = 20;
// QueryBuilder Mock
const queryBuilderMock = {
leftJoin: jest.fn().mockReturnThis(),
select: jest.fn().mockReturnThis(),
orderBy: jest.fn().mockReturnThis(),
limit: jest.fn().mockReturnThis(),
getRawMany: jest.fn().mockResolvedValue([
{
id: 'A005930',
name: '삼성전자',
currentPrice: '100000.0',
changeRate: '2.5',
volume: '500000',
marketCap: '500000000000.00',
},
{
id: 'A051910',
name: 'LG화학',
currentPrice: '75000.0',
changeRate: '-1.2',
volume: '300000',
marketCap: '20000000000.00',
},
]),
};

// Manager Mock
const managerMock = {
getRepository: jest.fn().mockReturnValue({
createQueryBuilder: jest.fn().mockReturnValue(queryBuilderMock),
}),
};
const dataSource = createDataSourceMock(managerMock);
const stockService = new StockService(dataSource as DataSource, logger);

const result = await stockService.getTopStocksByGainers(limit);

expect(managerMock.getRepository).toHaveBeenCalledWith(Stock);
expect(queryBuilderMock.orderBy).toHaveBeenCalledWith(
'stockLiveData.changeRate',
'DESC',
);
expect(queryBuilderMock.limit).toHaveBeenCalledWith(limit);
expect(queryBuilderMock.getRawMany).toHaveBeenCalled();

expect(instanceToPlain(result)).toEqual([
{
id: 'A005930',
name: '삼성전자',
currentPrice: 100000.0,
changeRate: 2.5,
volume: 500000,
marketCap: '500000000000.00',
},
{
id: 'A051910',
name: 'LG화학',
currentPrice: 75000.0,
changeRate: -1.2,
volume: 300000,
marketCap: '20000000000.00',
},
]);
});

test('소유 주식인지 확인한다.', async () => {
const managerMock = {
exists: jest.fn().mockResolvedValue(true),
Expand Down
9 changes: 9 additions & 0 deletions packages/backend/src/stock/stock.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,13 @@ export class StockService {

return plainToInstance(StocksResponse, rawData);
}

async getTopStocksByGainers(limit: number) {
const rawData = await this.StocksQuery()
.orderBy('stockLiveData.changeRate', 'DESC')
.limit(limit)
.getRawMany();

return plainToInstance(StocksResponse, rawData);
}
}

0 comments on commit bcc9a09

Please sign in to comment.