소스코드가 길어지니 점점 코드 읽기가 불편해지고 복잡해진다.
아직 레이어드 아키텍처가 적용되어 있지 않기에 리팩터링도 필요하다.
우선 동작되도록 만들고 조금씩 보안이나 성능, 유지보수 용이성을 기준으로 리팩터링을 할 예정이기에 여러 차례 이미 테스트했던 부분들을 다시 테스트해야 한다.
더 이상 postman으로 했던 테스트를 또다시 하고 싶지 않아 졌다.
우선 매 번 클릭해서 하기가 번거롭고 시간이 꽤나 소요된다.
또한 사람이니까 테스트를 놓치는 부분도 생길 수 있기에
작성한 코드에 대한 신뢰성이 더 떨어진다.
결국 테스트 코드를 추가할 수밖에 없다는 결론에 이르렀다.
jest를 이용해서 단위테스트부터 넣기로 하였다.
유저 파트 회원가입, 로그인, 비밀번호 변경 때 사용자가 입력한 값들이 정상적인지 확인하는 테스트를 넣었다.
- describe
- test
- it
- 관점의 차이
- mock데이터 이용
- req, res테스트
- faker 테스트
- 테스트에 대한 테스트
- 메타 테스트
- super test
express-validator의 검증 로직에서 withMessage()는 직전 검사 항목이 에러 나오면 나오게 될 문구이다. 만약 설정하지 않았다면 express-validator에 있는 기본 항목이 반영된다.
최소 영문 소문자 하나, 숫자 하나, 특수문자 하나
이 두 개의. matches() 메서드는 정규 표현식을 사용하여 문자열의 유효성을 검사하는 것입니다. 각각의 정규 표현식은 다음과 같은 차이점을 가집니다:
- 첫 번째 정규 표현식:
javascript코드 복사
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[?!@#$%])[A-Za-z\\d?!@#$%]{8,20}$/
- 설명: 이 정규 표현식은 다음 조건을 모두 충족해야 유효한 문자열로 간주합니다.
- 최소 8자에서 최대 20자까지의 길이여야 합니다.
- 적어도 하나의 소문자 ([a-z]), 하나의 대문자 ([A-Z]), 하나의 숫자 (\\d), 하나의 특수 문자 ([?!@#$%])를 포함해야 합니다.
- 문자열은 [A-Za-z\\d?!@#$%] 이 문자들만으로 구성되어야 합니다.
- 사용 예시: 이 정규 표현식은 비밀번호와 같은 강력한 보안 요구사항을 충족시키기 위해 사용됩니다. 대소문자, 숫자, 특수 문자가 모두 포함되어야 하며, 지정된 길이 범위 내에 있어야 합니다.
- 두 번째 정규 표현식:
javascript코드 복사
/^[A-Za-z\\d?!@#$%]{8,20}$/
- 설명: 이 정규 표현식은 다음 조건을 만족해야 유효한 문자열로 간주합니다.
- 최소 8자에서 최대 20자까지의 길이여야 합니다.
- 문자열은 [A-Za-z\\d?!@#$%] 이 문자들만으로 구성되어야 합니다.
- 사용 예시: 이 정규 표현식은 문자열의 구성 요소에 대한 강제 요구사항이 있지만, 특정 문자 클래스 (예: 소문자, 대문자, 숫자, 특수 문자)를 반드시 포함할 필요는 없을 때 사용될 수 있습니다. 예를 들어, 특정 API 또는 서비스에서는 특정 특수 문자를 허용하지 않는 경우가 있을 수 있습니다.
따라서 두 정규 표현식은 각각의 사용 사례와 요구사항에 맞게 선택되어야 합니다. 보안이 중요한 정보를 처리하는 경우 첫 번째 정규 표현식을 사용하여 강력한 비밀번호를 보장할 수 있으며, 다른 경우에는 두 번째 정규 표현식을 사용하여 간단한 문자열 유효성 검사를 수행할 수 있습니다.
퀴즈 결과 api
숫자 값 validation
- JS의 경우 “10”도 숫자로 인지 됨
- 문제는 validator에서 확인할 때는 강제 형 변환 되어서 숫자이지만
- req.body를 처리할 때는 문자열 “10”인 상태이다
- controller에서 강제 형 변환 할 수 있지만 미들웨어에서 변환 하 는 게 자연스럽다 생각했다
- 그런데, validator middleware에서 형 변환까지 하는 게 맞는가?
const { body } = require("express-validator");
// 강제 형변환 미들웨어
const forceTypeConversion = (req, res, next) => {
Object.keys(req.body).forEach((key) => {
const value = req.body[key];
const numberValue = parseFloat(value);
if (!isNaN(numberValue) && Number.isInteger(numberValue)) {
req.body[key] = numberValue;
}
});
next();
};
// 숫자인지 확인하고, 정수인지 확인
const ensureInt = (value) => {
if (!isNaN(value) && Number.isInteger(parseFloat(value))) {
return true;
}
return false;
};
const quizValidators = {
saveQuizResult: [
forceTypeConversion,
body("totalQuizCount")
.exists()
.withMessage("응시한 문제 수가 존재해야 합니다.")
.notEmpty()
.withMessage("응시한 문제 수가 비어 있을 수 없습니다.")
.isInt({ min: 0 })
.withMessage("응시한 문제 수가 0 이상의 정수여야 합니다.")
.bail()
.custom(ensureInt)
.withMessage("응시한 문제 수는 문자열이 아닌 정수여야 합니다."),
body("solvedQuizCount")
.exists()
.withMessage("맞춘 문제 수가 존재해야 합니다.")
.notEmpty()
.withMessage("맞춘 문제 수는 비어 있을 수 없습니다.")
.custom(ensureInt)
.withMessage("맞춘 문제 수는 문자열이 아닌 정수여야 합니다.")
.isInt({ min: 0 })
.withMessage("맞춘 문제 수는 0 이상의 정수여야 합니다."),
body("totalQuizScore")
.exists()
.withMessage("맞춘 총 점수가 존재해야 합니다.")
.notEmpty()
.withMessage("맞춘 총 점수는 비어 있을 수 없습니다.")
.custom(ensureInt)
.withMessage("맞춘 총 점수는 문자열이 아닌 정수여야 합니다.")
.isInt({ min: 0 })
.withMessage("맞춘 총 점수는 0 이상의 정수여야 합니다."),
],
};
module.exports = quizValidators;
테스트 실패…
validatoin에만 유닛테스트 적용하였다.
'Project' 카테고리의 다른 글
[간단한 퀴즈 서비스] Day19 인증 로직 미들웨어 수정 (0) | 2024.11.13 |
---|---|
[간단한 퀴즈 서비스] Day17~18 마이페이지 API, 랭킹 API (1) | 2024.11.12 |
[간단한 퀴즈 서비스] Day09~11 DB설계 및 구현 (0) | 2024.11.10 |
[간단한 퀴즈 서비스] Day05-08 DB 없이 동작 구현 (1) | 2024.11.09 |
[간단한 퀴즈 서비스] Day04 백로그 작성, 기능명세, API명세 (1) | 2024.11.08 |