package kr.itn.itnhub.seed; import kr.itn.itnhub.AbstractDbTest; import kr.itn.itnhub.contact.Contact; import kr.itn.itnhub.contact.ContactMapper; import kr.itn.itnhub.org.OrgStatus; import kr.itn.itnhub.org.Organization; import kr.itn.itnhub.org.OrganizationMapper; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; class SeedServiceTest extends AbstractDbTest { @Autowired SeedService seedService; @Autowired OrganizationMapper mapper; @Autowired ContactMapper contactMapper; @Autowired JdbcTemplate jdbc; @BeforeEach void clean() { jdbc.update("delete from organization"); jdbc.update("delete from contact"); } private byte[] workbook(String[]... dataRows) throws Exception { try (XSSFWorkbook wb = new XSSFWorkbook(); ByteArrayOutputStream out = new ByteArrayOutputStream()) { Sheet sheet = wb.createSheet(SeedParser.SHEET_NAME); sheet.createRow(0); sheet.createRow(1); int rowNum = 2; for (String[] data : dataRows) { Row row = sheet.createRow(rowNum++); row.createCell(1).setCellValue(data[0]); row.createCell(2).setCellValue(data[1]); row.createCell(5).setCellValue(data[2]); if (data[3] != null) row.createCell(6).setCellValue(data[3]); if (data[4] != null) row.createCell(7).setCellValue(data[4]); if (data[5] != null) row.createCell(8).setCellValue(data[5]); if (data[6] != null) row.createCell(9).setCellValue(data[6]); if (data[7] != null) row.createCell(10).setCellValue(data[7]); } wb.write(out); return out.toByteArray(); } } @Test void 최초_시드는_전부_신규다() throws Exception { byte[] xlsx = workbook( new String[]{"001", "00", "국제방송교류재단", "팀", "송민지", "과장", "02-1", "a@b.kr"}, new String[]{"002", "00", "세종학당재단", "팀", "권유나", "6급", "02-2", "c@d.kr"}); SeedReport report = seedService.seed(new ByteArrayInputStream(xlsx)); assertThat(report.created()).isEqualTo(2); assertThat(report.updated()).isZero(); assertThat(report.total()).isEqualTo(2); assertThat(mapper.findAll()).hasSize(2); } @Test void 같은_파일을_다시_올려도_행이_늘지_않는다() throws Exception { byte[] xlsx = workbook( new String[]{"001", "00", "국제방송교류재단", "팀", "송민지", "과장", "02-1", "a@b.kr"}); seedService.seed(new ByteArrayInputStream(xlsx)); SeedReport second = seedService.seed(new ByteArrayInputStream(xlsx)); assertThat(second.created()).isZero(); assertThat(second.updated()).isEqualTo(1); assertThat(mapper.findAll()).hasSize(1); } @Test void 재시드는_이미_만든_채널ID를_보존한다() throws Exception { byte[] xlsx = workbook( new String[]{"001", "00", "국제방송교류재단", "팀", "송민지", "과장", "02-1", "a@b.kr"}); seedService.seed(new ByteArrayInputStream(xlsx)); Long id = mapper.findAll().get(0).getId(); mapper.updateChannelIdMj(id, "chan-mj"); mapper.updateChannelIdLaw(id, "chan-law"); seedService.seed(new ByteArrayInputStream(xlsx)); assertThat(mapper.findById(id).getStatus()).isEqualTo(OrgStatus.ACTIVE); } @Test void 같은_기관이_한_시트에_두번_들어있으면_한_행만_남고_두번째는_갱신으로_집계된다() throws Exception { byte[] xlsx = workbook( new String[]{"001", "00", "국제방송교류재단", "팀", "송민지", "과장", "02-1", "a@b.kr"}, new String[]{"001", "00", "국제방송교류재단", "팀", "송민지", "과장", "02-1", "a@b.kr"}); SeedReport report = seedService.seed(new ByteArrayInputStream(xlsx)); assertThat(mapper.findAll()).hasSize(1); assertThat(report.total()).isEqualTo(2); assertThat(report.created()).isEqualTo(1); assertThat(report.updated()).isEqualTo(1); } @Test void 담당자정보가_없는_기관은_정보대기로_들어온다() throws Exception { byte[] xlsx = workbook( new String[]{"008", "00", "경찰청", "데이터정책계", "박진우", "경위", "02-3", "e@f.kr"}, new String[]{"008", "01", "경찰청_치안정책연구소", null, null, null, null, null}); seedService.seed(new ByteArrayInputStream(xlsx)); List all = mapper.findAll(); assertThat(all).hasSize(2); assertThat(all).extracting(Organization::getStatus) .containsExactly(OrgStatus.READY, OrgStatus.INFO_PENDING); } @Test void 시트에_담당자명이_있으면_신청기관_담당자_연락처를_만들어_연결한다() throws Exception { byte[] xlsx = workbook( new String[]{"001", "00", "국제방송교류재단", "데이터정보화팀", "송민지", "과장", "02-1", "a@b.kr"}); seedService.seed(new ByteArrayInputStream(xlsx)); Organization org = mapper.findAll().get(0); assertThat(org.getApplicantContactId()).isNotNull(); Contact applicant = org.getApplicant(); assertThat(applicant.getCategory()).isEqualTo("APPLICANT"); assertThat(applicant.getName()).isEqualTo("송민지"); assertThat(applicant.getAffiliation()).isEqualTo("국제방송교류재단"); assertThat(applicant.getDeptName()).isEqualTo("데이터정보화팀"); assertThat(applicant.getTitle()).isEqualTo("과장"); assertThat(applicant.getPhone()).isEqualTo("02-1"); assertThat(applicant.getEmail()).isEqualTo("a@b.kr"); } @Test void 재시드는_이미_연결된_신청기관_담당자를_중복생성하거나_다시_연결하지_않는다() throws Exception { byte[] xlsx = workbook( new String[]{"001", "00", "국제방송교류재단", "팀", "송민지", "과장", "02-1", "a@b.kr"}); seedService.seed(new ByteArrayInputStream(xlsx)); Long firstContactId = mapper.findAll().get(0).getApplicantContactId(); seedService.seed(new ByteArrayInputStream(xlsx)); Organization after = mapper.findAll().get(0); assertThat(after.getApplicantContactId()).isEqualTo(firstContactId); assertThat(jdbc.queryForObject("select count(*) from contact", Integer.class)).isEqualTo(1); } @Test void 같은_담당자를_공유하는_하위기관_여러곳은_담당자를_한_행만_만들어_모두_연결한다() throws Exception { byte[] xlsx = workbook( new String[]{"008", "00", "경찰청", "데이터정책계", "박진우", "경위", "02-3150-3205", "hi@police.go.kr"}, new String[]{"008", "02", "서울청", "데이터정책계", "박진우", "경위", "02-3150-3205", "hi@police.go.kr"}, new String[]{"008", "03", "부산청", "데이터정책계", "박진우", "경위", "02-3150-3205", "hi@police.go.kr"}); SeedReport report = seedService.seed(new ByteArrayInputStream(xlsx)); assertThat(report.created()).isEqualTo(3); assertThat(jdbc.queryForObject("select count(*) from contact", Integer.class)).isEqualTo(1); List all = mapper.findAll(); assertThat(all).hasSize(3); assertThat(all).extracting(Organization::getStatus) .containsOnly(OrgStatus.READY); Long contactId = all.get(0).getApplicantContactId(); assertThat(contactId).isNotNull(); assertThat(all).extracting(Organization::getApplicantContactId) .containsOnly(contactId); } @Test void 이미_다른_담당자로_배정된_기관은_재시드가_배정을_바꾸지_않는다() throws Exception { byte[] xlsx = workbook( new String[]{"001", "00", "국제방송교류재단", "팀", "송민지", "과장", "02-1", "a@b.kr"}); seedService.seed(new ByteArrayInputStream(xlsx)); Long id = mapper.findAll().get(0).getId(); Contact manual = new Contact(); manual.setCategory("APPLICANT"); manual.setName("사람이 직접 배정한 담당자"); contactMapper.insert(manual); mapper.updateAssignments(id, manual.getId(), null, null, null); seedService.seed(new ByteArrayInputStream(xlsx)); Organization after = mapper.findById(id); assertThat(after.getApplicantContactId()).isEqualTo(manual.getId()); assertThat(after.getApplicant().getName()).isEqualTo("사람이 직접 배정한 담당자"); } }