코딩하는 털보

11 to 9, Day 11 본문

Diary/Eleven to Nine

11 to 9, Day 11

이정인 2021. 3. 12. 17:14

Today, ToDoList

  • Toy Project - NGMA
    • 신청 받은 내역 확인/거절 프로세스 만들기
    • 내가 신청한 이력을 취소할 수 있는 기능 만들기

신청 받은 내역 확인/거절 프로세스 만들기

대기자 테이블의 확인/취소 버튼에 ajax로 대기자 속성 변경하기

컨트롤러 테스트

    @Test
    @WithUserDetails(value = "jilee@example.com", setupBefore = TestExecutionEvent.TEST_EXECUTION)
    public void confirmWaiter() throws Exception {
        Account lover = accountService.getUserByEmail("sjlee@example.com");
        Account account = accountService.getUserByEmail("jilee@example.com");
        accountService.pickLover(lover, account);

        assertThat(lover.getLoverState()).isEqualTo(LoverState.WAITING);
        assertThat(account.getLoverState().getHasWaiters()).isEqualTo(true);
        assertThat(account.getWaiter()).isNotEmpty();

        mvc.perform(post("/account/waiter/"+lover.getId())
                .param("param", "confirm"))
                .andDo(print())
                .andExpect(status().isOk());

        assertThat(lover.getLoverState()).isEqualTo(LoverState.COUPLED);
        assertThat(account.getLoverState().getHasWaiters()).isEqualTo(false);
        assertThat(account.getWaiter()).isEmpty();
    }

    @Test
    @WithUserDetails(value = "jilee@example.com", setupBefore = TestExecutionEvent.TEST_EXECUTION)
    public void rejectWaiter() throws Exception {
        Account lover = accountService.getUserByEmail("sjlee@example.com");
        Account account = accountService.getUserByEmail("jilee@example.com");
        accountService.pickLover(lover, account);

        assertThat(lover.getLoverState()).isEqualTo(LoverState.WAITING);
        assertThat(account.getLoverState().getHasWaiters()).isEqualTo(true);
        assertThat(account.getWaiter().contains(lover)).isTrue();
        assertThat(account.getWaiter()).isNotEmpty();

        mvc.perform(post("/account/waiter/"+lover.getId())
                .param("param", "reject"))
                .andDo(print())
                .andExpect(status().isOk());

        assertThat(lover.getLoverState()).isEqualTo(LoverState.NOTHING);
        assertThat(account.getWaiter().contains(lover)).isFalse();
    }

핸들러

    @PostMapping("/waiter/{id}")
    @ResponseBody
    public ResponseEntity<?> modifyWaiter(@AuthenticationPrincipal UserAccount userAccount,
                                    @PathVariable("id") Long id,@RequestParam String param) {
        if (param.equals("confirm")) {
            accountService.confirmWaiter(userAccount, id);
        } else if (param.equals("reject")) {
            accountService.rejectWaiter(userAccount, id);
        } else {
            throw new InvalidParameterException(param);
        }
        return ResponseEntity.ok().body("{}");
    }

서비스

    public void rejectWaiter(UserAccount userAccount, Long waiterId) {
        Account account = getUserById(userAccount.getAccountId());
        Account waiter = getUserById(waiterId);
        account.getWaiters().remove(waiter);
        waiter.setLover(null);
        waiter.setLoverState(LoverState.NOTHING);
    }

    public void confirmWaiter(UserAccount userAccount, Long waiterId) {
        Account account = getUserById(userAccount.getAccountId());
        Account waiter = getUserById(waiterId);
        account.setLover(waiter);
        account.setLoverState(LoverState.COUPLED);
        waiter.setLoverState(LoverState.COUPLED);
        account.getWaiters().remove(waiter);
        clearWaiter(account);
        clearWaiter(waiter);
    }

    public void clearWaiter(Account account) {
        List<Account> waiterList = account.getWaiters();
        for (Account waiter : waiterList) {
            waiter.setLover(null);
            waiter.setLoverState(LoverState.NOTHING);
        }
        waiterList.clear();
        account.setLoverStateHasWaiters(false);
    }

ajax

function confirmWaiter(accountId) {
    $.ajax({
        url: "http://localhost:8080/account/waiter/"+accountId,
        type: "POST",
        data: {param: "confirm"},
        dataType: "json",
        success: function(data) {
            alert("확인되었습니다.");
            loadCoupleState();
        },
        error: function(request) {
            alert(request.responseText);
        }
    });
}

function rejectWaiter() {
    $.ajax({
        url: "http://localhost:8080/account/waiter/"+accountId,
        type: "POST",
        data: {param: "reject"},
        dataType: "json",
        success: function(data) {
            alert("거절되었습니다.");
            loadCoupleState();
        },
        error: function(request) {
            alert(request.responseText);
        }
    });
}

트러블 슈팅

두 Account 객체의 lover 속성이 서로 일 경우 무한 루프 발생.

    @OneToOne
    @JsonIgnore
    @JoinColumn(name = "lover_id")
    private Account lover;

@JsonIgnore 애노테이션으로 Json response에서 제외


내가 신청한 이력을 취소할 수 있는 기능 만들기

컨트롤러 테스트

    @Test
    @WithUserDetails(value = "jilee@example.com", setupBefore = TestExecutionEvent.TEST_EXECUTION)
    public void cancelpick() throws Exception {
        Account account = accountService.getUserByEmail("jilee@example.com");
        Account lover = accountService.getUserByEmail("sjlee@example.com");
        lover.setLover(account);
        lover.setLoverState(LoverState.WAITING);
        account.getWaiters().add(lover);
        account.setLoverStateHasWaiters(true);

        mvc.perform(post("/account/pick/cancel"))
                .andDo(print())
                .andExpect(status().isOk());

        assertThat(account.getLover()).isNull();
        assertThat(account.getLoverState()).isEqualTo(LoverState.NOTHING);
    }

핸들러

    @PostMapping("/pick/cancel")
    @ResponseBody
    public ResponseEntity<?> cancelPick(@AuthenticationPrincipal UserAccount userAccount) {
        accountService.cancelPick(userAccount);
        return ResponseEntity.ok().body("{}");
    }

서비스

    public void cancelPick(UserAccount userAccount) {
        Account account = getUserById(userAccount.getAccountId());
        account.setLover(null);
        account.setLoverState(LoverState.NOTHING);
    }

취소 버튼 및 ajax 함수 추가

function waitingComment(data) {
    $("div#loverStateResult")
        .append("<p class=\"text-sm-start\">아직 "+data.name.toString()+"("+data.email.toString()+")" +
            "님으로부터 승인을 대기중입니다. 상대방의 확인이 끝날 때 까지 기다려주세요.</p>" +
            "\<a class=\"btn btn-outline-primary btn-sm\" type=\"button\" id=\"cancelPick\" onclick=\"cancelPick();\">취소하기</a>");
}

function cancelPick() {
    $.ajax({
        url: "http://localhost:8080/account/pick/cancel",
        type: "POST",
        dataType: "json",
        success: function(data) {
            alert("취소되었습니다.");
            loadCoupleState();
        },
        error: function(request) {
            alert(request.responseText);
        }
    });
}
Comments