File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
package kr.itn.itnhub.system;
import kr.itn.itnhub.AbstractDbTest;
import kr.itn.itnhub.mattermost.MattermostClient;
import kr.itn.itnhub.mattermost.MattermostException;
import kr.itn.itnhub.org.Organization;
import kr.itn.itnhub.org.OrganizationMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@AutoConfigureMockMvc
@WithMockUser(roles = "ADMIN")
class SystemResetControllerTest extends AbstractDbTest {
@Autowired
MockMvc mvc;
@Autowired
OrganizationMapper orgMapper;
@Autowired
JdbcTemplate jdbc;
@MockBean
MattermostClient mattermost;
private Long bothChannelsId;
private Long noChannelId;
@BeforeEach
void setUp() {
jdbc.update("delete from organization");
bothChannelsId = seed("001", "채널있는기관");
orgMapper.updateChannelIdMj(bothChannelsId, "ch-mj");
orgMapper.updateChannelIdLaw(bothChannelsId, "ch-law");
orgMapper.updateStage(bothChannelsId, 3);
jdbc.update("insert into stage_history (org_id, stage) values (?, 3)", bothChannelsId);
noChannelId = seed("002", "채널없는기관");
}
private Long seed(String orgNo, String orgName) {
Organization org = new Organization();
org.setOrgNo(orgNo);
org.setOrgName(orgName);
org.setChannelSlug(orgNo);
orgMapper.upsertBySeed(org);
return orgMapper.findByOrgNoAndOrgName(orgNo, orgName).getId();
}
@Test
void 미리보기는_DB가_아는_채널만_보여준다() throws Exception {
mvc.perform(get("/api/system/reset/preview"))
.andExpect(status().isOk())
// 채널 없는 기관은 아예 목록에 없다
.andExpect(jsonPath("$.length()").value(1))
.andExpect(jsonPath("$[0].orgNo").value("001"))
.andExpect(jsonPath("$[0].stage").value(3))
.andExpect(jsonPath("$[0].channels.length()").value(2))
.andExpect(jsonPath("$[0].channels[0].kind").value("문정원"))
.andExpect(jsonPath("$[0].channels[1].kind").value("법률검토"));
}
@Test
void 미리보기는_아무것도_바꾸지_않는다() throws Exception {
mvc.perform(get("/api/system/reset/preview")).andExpect(status().isOk());
assertThat(orgMapper.findById(bothChannelsId).getChannelIdMj()).isEqualTo("ch-mj");
verify(mattermost, never()).archiveChannel(anyString());
}
@Test
void 확인문구가_틀리면_400이고_아무것도_지우지_않는다() throws Exception {
mvc.perform(post("/api/system/reset/channels").with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content("{\"confirm\": \"초기화\"}"))
.andExpect(status().isBadRequest());
verify(mattermost, never()).archiveChannel(anyString());
assertThat(orgMapper.findById(bothChannelsId).getChannelIdMj()).isEqualTo("ch-mj");
}
@Test
void 초기화하면_채널을_보관하고_DB의_채널과_단계를_비운다() throws Exception {
mvc.perform(post("/api/system/reset/channels").with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content("{\"confirm\": \"채널 초기화\"}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.archivedChannels").value(2))
.andExpect(jsonPath("$.clearedOrgs").value(1))
.andExpect(jsonPath("$.failures.length()").value(0));
verify(mattermost).archiveChannel("ch-mj");
verify(mattermost).archiveChannel("ch-law");
Organization after = orgMapper.findById(bothChannelsId);
assertThat(after.getChannelIdMj()).isNull();
assertThat(after.getChannelIdLaw()).isNull();
assertThat(after.getStage()).isNull();
assertThat(jdbc.queryForObject("select count(*) from stage_history where org_id = ?",
Integer.class, bothChannelsId)).isZero();
}
@Test
void 담당자_배정과_권리확인_데이터는_건드리지_않는다() throws Exception {
jdbc.update("insert into review_item (org_id, seq, review_result) values (?, 1, '이용가능')",
bothChannelsId);
jdbc.update("insert into work_memo (org_id, contact_name, body) values (?, '시스템', '메모')",
bothChannelsId);
mvc.perform(post("/api/system/reset/channels").with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content("{\"confirm\": \"채널 초기화\"}"))
.andExpect(status().isOk());
assertThat(jdbc.queryForObject("select count(*) from review_item where org_id = ?",
Integer.class, bothChannelsId)).isEqualTo(1);
assertThat(jdbc.queryForObject("select count(*) from work_memo where org_id = ?",
Integer.class, bothChannelsId)).isEqualTo(1);
// 기관 자체도 남는다
assertThat(orgMapper.findById(bothChannelsId)).isNotNull();
}
@Test
void 한쪽_채널이_실패하면_그_기관의_DB는_그대로_두고_실패를_보고한다() throws Exception {
doThrow(new MattermostException("권한 없음")).when(mattermost).archiveChannel("ch-law");
mvc.perform(post("/api/system/reset/channels").with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content("{\"confirm\": \"채널 초기화\"}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.archivedChannels").value(1))
.andExpect(jsonPath("$.clearedOrgs").value(0))
.andExpect(jsonPath("$.failures.length()").value(1));
// 남은 채널을 다시 찾을 수 있어야 하므로 ID를 지우지 않는다
assertThat(orgMapper.findById(bothChannelsId).getChannelIdLaw()).isEqualTo("ch-law");
}
}