프로필

프로필 사진
Popomon
Frontend Developer
(2020/12 ~)

    카테고리

    포스트

    [Node/Rest API] SFA - (3) - 컨트롤러와 라우터 - 이메일 확인

    2020. 12. 7. 21:32

    꿈가게: To Do List - iOS

    꿈가게: To Do List - Android

    이메일 확인 컨트롤러 작성하기

    컨트롤러를 작성하기 이전에 성공과 실패의 경우에 대해서 다음과 같이 정의할 필요가 있습니다. 다음과 같이 우선 정리를 해 두면 테스트코드를 작성하기에 훨씬 수월하기 때문입니다.

     

    성공 시

    200 - 이메일 확인 성공

     

    실패 시

    401 - 토큰 값이 존재하지 않는 경우

    409 - 해당하는 이메일 토큰이 없는 경우

    500 - 입력된 데이터가 데이터베이스에 저장되지 않은 경우

    500 - 서버 에러 (여러가지 요인이 존재함)

     

    자! 그러면 위에 정의된 코드를 기준으로 테스트코드를 작성해 보겠습니다. 원래는 테스트코드를 작성하기 위해서는 훨씬 효율적인 방법이 있다고 생각하지만, 저는 아직 실무경험이 부족하기 때문에 투박하게 작성해보겠습니다

     

    저는 총 4개의 단계로 나누어서 작성을 합니다.

    - Data 영역에서는 데이터베이스에 등록하거나 수정하거나 할 객체를 미리 선언해 둡니다.

    - Request 영역에서는 애플리케이션에 해당하는 요청을 보내고 응답 객체를 리턴받습니다.

    - Result 영역에서는 테스트 관련 함수를 통해 응답받은 객체에에 대해서 예상된 결과가 나왔는지를 검증합니다.

    - Reset 영역에서는 테스트에서 사용된 데이터를 지워줍니다.

     

    describe("GET - /confirmation/:token", function () {
      describe("성공 시", function(){
        it("200 - 이메일 인증 완료", async function(){
          // Data
          const data = { email: 'signup1@rollback.com', password: 'Test1234!' };
    
          // Request
          await server.post("/oauth2/signup").withCredentials().send(data);
          const token = await User.findOne({ email: data.email }).then(e => e?.email_verify_token);
          const response = await server.get(`/oauth2/confirmation/${token}`).withCredentials().send(data);
          const isVerified = await User.findOne({ email: data.email }).then(e => e?.email_verified);
          
          // Status
          expect(response.status).to.equal(200);
          expect(isVerified).to.equal(true);
    
          // Reset
          await User.deleteMany({ email: { $in: [ data.email ] } });
        })
      })
      describe("실패 시", function(){
        it("401 - 토큰 값이 존재하지 않음", async function(){
          // Data
          const data = { email: 'signup1@rollback.com', password: 'Test1234!' };
    
          // Request
          await server.post("/oauth2/signup").withCredentials().send(data);
          const response = await server.get(`/oauth2/confirmation/${undefined}`).withCredentials();
    
          // Status
          expect(response.status).to.equal(401);
          await User.deleteMany({ email: { $in: [ data.email ] } });
        })
        it("409 - 이메일 토큰값이 맞지 않음", async function(){
          // Data
          const data = { email: 'signup1@rollback.com', password: 'Test1234!' };
    
          // Request
          await server.post("/oauth2/signup").withCredentials().send(data);
          const token = '1111';
          const response = await server.get(`/oauth2/confirmation/${token}`).withCredentials();
    
          // Status
          expect(response.status).to.equal(409);
          await User.deleteMany({ email: { $in: [ data.email ] } });
        })
      })
    })

     

    테스트코드를 기반으로 원하는 결과가 나올 수 있도록 다음과 같이 로직을 작성해줍니다.

     

    export const confirmation = [
      async (req : Request, res : Response) => {
        const { token } = req.params;
    
        if (token && token !== 'undefined' && token !== 'null') {
          let email_verify_token = token;
          try {
            const user = await User.findOne({ email_verify_token });
            if (!user) {
              console.log('BAD : 해당하는 이메일 토큰이 없습니다.', email_verify_token);
              return res.sendStatus(409);
            };
    
            if (email_verify_token) {
              user.email_verified = true;
              user.email_verify_token = undefined;
              try {
                await user.save();
                return res.sendStatus(200);
              } catch (err) {
                console.error('ERROR : 입력된 데이터가 데이터베이스에 저장되지 않았습니다.', err);
                return res.sendStatus(500);
              }
            }
          } catch (err) {
            console.error('ERROR : 서버의 상태를 체크해주세요', err);
            return res.sendStatus(500);
          }
        } else {
          console.log('BAD : 토큰값이 존재하지 않습니다.', token);
          return res.sendStatus(401);
        }
      }
    ];

     

    'Backend > Node' 카테고리의 다른 글

    [코드조각] server.ts  (0) 2020.11.17
    [코드조각] app.ts  (0) 2020.11.17
    [코드조각] db.ts  (0) 2020.11.17
    [코드조각] .env + config.ts  (0) 2020.11.17
    [Node/Rest API] SFA - (2) - 컨트롤러와 라우터 - 회원가입  (0) 2020.11.14