카테고리 없음
15주차 (3)
jaeoun0238
2025. 2. 6. 00:51
describe('updateCardOrder', () => { it('should update card order', async () => { const userId = 1; const columnId = 1; const cardId = 1; const targetCardId = 2; const column = { id: columnId, board: { id: 99 } }; const cards = [ { id: 1, lexo: LexoRank.middle().toString() }, { id: 2, lexo: LexoRank.middle().genNext().toString() }, ]; const targetCard = { id: targetCardId, lexo: LexoRank.middle().genNext().toString(), }; const updatedCard = { id: cardId, lexo: LexoRank.parse(targetCard.lexo).genNext().toString(), }; mockColumnRepository.findOne.mockResolvedValue(column); mockMemberRepository.findOne.mockResolvedValue({ boardId: column.board.id, userId, }); mockCardRepository.find.mockResolvedValue(cards); mockCardRepository.findOne .mockResolvedValueOnce(cards[0]) .mockResolvedValueOnce(targetCard) .mockResolvedValueOnce(updatedCard); mockCardRepository.update.mockResolvedValue(updatedCard); const result = await service.updateCardOrder( userId, columnId, cardId, targetCardId, ); expect(result).toEqual(updatedCard); }); });
const generateString = () => crypto.randomUUID(); 라는 오류가 발생했습니다.
crypto 객체가 정의되지 않았기 때문에 "crypto is not defined" 인 상태가 된것인데..!
const crypto = require('crypto');
이코드를 사용하면 해결이 가능했습니다.
const crypto = require('crypto'); 를 사용하면 해결되는 이유
NestJS는 기본적으로 CommonJS (CJS) 환경을 사용한다.
require('crypto')는 CommonJS 환경에서 올바르게 동작한다.
import * as crypto from 'crypto';를 사용하려면 TypeScript와 Node.js를 ES 모듈 방식으로 설정해야 하는데,
기본적으로 CommonJS로 설정되어 있기 때문에 오류가 발생할 수 있다.
이번에 맡은 부분을 jest를 사용해보면서 정말 많은 고난이 있었습니다ㅜㅜ 처음사용해보는거라 그런지 익숙하지 않아서 어려움이 많았는데 service.ts파일에서
findOne 의 갯수를 확인하고 이를 service.spec.ts 파일에서도 그대로 적용해야한다.
async updateCardOrder(
userId: number,
columnId: number,
cardId: number,
targetCardId: number,
): Promise<Card> {
const column = await this.columnRepository.findOne({
where: { id: columnId },
relations: ['board'],
});
const checkMember = await this.memberRepository.findOne({
where: { userId: userId, boardId: column.board.id },
});
if (!checkMember) {
throw new NotFoundException(
'카드을 변경할 수 있는 권한이 존재하지 않습니다.',
);
}
const cards = await this.cardRepository.find({
where: { columnId },
order: { lexo: 'DESC' },
});
const card = await this.cardRepository.findOne({ where: { id: cardId } });
const targetCard = await this.cardRepository.findOne({
where: { id: targetCardId },
});
const CardIndex = cards.findIndex((card) => card.id === cardId);
const targetCardIndex = cards.findIndex((card) => card.id === targetCardId);
//-------------------------------------------------------------
if (targetCardIndex < CardIndex) {
const targetNextCardIndex = targetCardIndex - 1;
if (!card || !targetCard) {
throw new BadRequestException('카드가 존재하지 않습니다.');
}
const currentRank = LexoRank.parse(card.lexo);
const targetRank = LexoRank.parse(targetCard.lexo);
const targetNextCard = cards[targetNextCardIndex];
if (targetNextCardIndex < 0) {
let lexoRank: LexoRank;
lexoRank = LexoRank.parse(targetCard.lexo.toString()).genNext(); // 현재 카드 다음 랭크
await this.cardRepository.update(
{ id: cardId, columnId },
{ lexo: lexoRank.toString() },
);
return await this.cardRepository.findOne({ where: { id: cardId } });
}
const newRank = LexoRank.parse(targetNextCard.lexo).between(targetRank); // 현재 카드와 타켓 카드 사이의 랭크
await this.cardRepository.update(
{ id: cardId, columnId },
{ lexo: newRank.toString() },
);
return await this.cardRepository.findOne({ where: { id: cardId } });
} else {
const maxIndex: number = cards.length - 1;
if (targetCardIndex === maxIndex) {
let lexoRank: LexoRank;
lexoRank = LexoRank.parse(targetCard.lexo.toString()).genPrev(); // 현재 카드 다음 랭크
await this.cardRepository.update(
{ id: cardId, columnId },
{ lexo: lexoRank.toString() },
);
return await this.cardRepository.findOne({ where: { id: cardId } }); // 여기서부터 cardRepository를 사용하는 findOne의 갯수 확인
}
const targetNextCardIndex = targetCardIndex + 1;
// const existingCard = await this.cardRepository.findOne({ where: { id: targetCardId }, order: { lexo: "DESC" } })
if (!card || !targetCard) {
throw new BadRequestException('카드가 존재하지 않습니다.');
}
const currentRank = LexoRank.parse(card.lexo);
const targetRank = LexoRank.parse(targetCard.lexo);
const targetNextCard = cards[targetNextCardIndex];
if (targetNextCardIndex === maxIndex) {
let lexoRank: LexoRank;
lexoRank = LexoRank.parse(targetCard.lexo.toString()).genPrev(); // 현재 카드 다음 랭크
await this.cardRepository.update(
{ id: cardId, columnId },
{ lexo: lexoRank.toString() },
);
return await this.cardRepository.findOne({ where: { id: cardId } });
}
const newRank = LexoRank.parse(targetNextCard.lexo).between(targetRank); // 현재 카드와 타켓 카드 사이의 랭크
await this.cardRepository.update(
{ id: cardId, columnId },
{ lexo: newRank.toString() },
);
return await this.cardRepository.findOne({ where: { id: cardId } });
}
}
findOne를 잘살펴보면
mockCardRepository.findOne
.mockResolvedValueOnce(cards[0])
.mockResolvedValueOnce(targetCard)
.mockResolvedValueOnce(updatedCard);
원래의 서비스 파일에서 findOne를 3번 사용했기때문에 CardRepository를 사용하는 3가지를 한번에 묶어서 사용해줘야 오류가 나지 않는다!!!