| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- package com.malk.service.workhours;
- import com.malk.server.dingtalk.DDR_New;
- import org.junit.jupiter.api.Test;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import static org.junit.jupiter.api.Assertions.assertEquals;
- import static org.junit.jupiter.api.Assertions.assertFalse;
- import static org.junit.jupiter.api.Assertions.assertTrue;
- class ApprovalWriteBackServiceTest {
- @Test
- void shouldPreferApprovedStatus() {
- assertEquals("已审批", ApprovalWriteBackService.resolveSummaryApprovalStatus(8, 8));
- assertEquals("已审批", ApprovalWriteBackService.resolveSummaryApprovalStatus(4, 4));
- assertEquals("已审批", ApprovalWriteBackService.resolveSummaryApprovalStatus(0, 4));
- }
- @Test
- void shouldUseInApprovalWhenSubmittedHoursRemain() {
- assertEquals("审批中", ApprovalWriteBackService.resolveSummaryApprovalStatus(8, 0));
- assertEquals("审批中", ApprovalWriteBackService.resolveSummaryApprovalStatus(8, 4));
- }
- @Test
- void shouldFallBackToDraftWhenNoSubmittedOrApprovedHours() {
- assertEquals("暂存", ApprovalWriteBackService.resolveSummaryApprovalStatus(0, 0));
- }
- @Test
- void shouldRestoreSubmittedHoursWhenApprovalCompletes() {
- assertEquals(8.0,
- ApprovalWriteBackService.resolveSubmittedAfterWriteBack(true, 0, 8));
- }
- @Test
- void shouldKeepLargerSubmittedHoursWhenApprovalCompletes() {
- assertEquals(12.0,
- ApprovalWriteBackService.resolveSubmittedAfterWriteBack(true, 12, 8));
- }
- @Test
- void shouldClearSubmittedHoursWhenApprovalIsRejected() {
- assertEquals(0.0,
- ApprovalWriteBackService.resolveSubmittedAfterWriteBack(false, 8, 8));
- }
- @Test
- void shouldFallBackToWholeApprovalWhenHistoricalDetailOpinionIsBlank() {
- assertEquals(true, ApprovalWriteBackService.isDetailApproved(true, ""));
- assertEquals(true, ApprovalWriteBackService.isDetailApproved(true, null));
- assertEquals(true, ApprovalWriteBackService.isDetailApproved(true, "同意"));
- assertEquals(false, ApprovalWriteBackService.isDetailApproved(true, "拒绝"));
- assertEquals(false, ApprovalWriteBackService.isDetailApproved(false, ""));
- }
- @Test
- void shouldExtractFullFormDataFromProcessDetail() {
- DDR_New response = new DDR_New();
- Map<String, Object> formData = new HashMap<>();
- formData.put("tableField_mmae8t99", new ArrayList<>(63));
- response.setData(formData);
- Map extracted = ApprovalWriteBackService.extractProcessFormData(response);
- assertEquals(formData, extracted);
- }
- @Test
- void shouldExtractFullFormDataFromLegacyProcessResult() {
- DDR_New response = new DDR_New();
- Map<String, Object> formData = new HashMap<>();
- formData.put("tableField_mmae8t99", new ArrayList<>(63));
- Map<String, Object> result = new HashMap<>();
- result.put("data", formData);
- response.setResult(result);
- Map extracted = ApprovalWriteBackService.extractProcessFormData(response);
- assertEquals(formData, extracted);
- }
- @Test
- void shouldRecognizeWorkApprovalWithOnlyNonBillableRows() {
- Map<String, Object> row = new HashMap<>();
- row.put("textField_mmd1wu9d", "PROJECT-1");
- Map<String, Object> formData = new HashMap<>();
- formData.put("tableField_mmd1wu9h", Collections.singletonList(row));
- assertEquals(false, ApprovalWriteBackService.isOtherApprovalForm(formData));
- }
- @Test
- void shouldRecognizeOtherApprovalByActivityField() {
- Map<String, Object> row = new HashMap<>();
- row.put("selectField_mmeakgie", "培训");
- Map<String, Object> formData = new HashMap<>();
- formData.put("tableField_mmd1wu9h", Collections.singletonList(row));
- assertEquals(true, ApprovalWriteBackService.isOtherApprovalForm(formData));
- }
- @Test
- void shouldReadOtherApprovalOpinionFromActualField() {
- Map<String, Object> row = new HashMap<>();
- row.put("selectField_mmeakgie", "培训");
- row.put("radioField_mpwhk294", "不同意");
- assertFalse(RepairApprovalWriteBackService.isApprovedRow(row, false, true));
- row.put("radioField_mpwhk294", "同意");
- assertTrue(RepairApprovalWriteBackService.isApprovedRow(row, false, true));
- }
- @Test
- void shouldReadNonBillableApprovalOpinionFromActualField() {
- Map<String, Object> row = new HashMap<>();
- row.put("textField_mmd1wu9d", "PROJECT-1");
- row.put("radioField_mpwhk295", "不同意");
- assertFalse(RepairApprovalWriteBackService.isApprovedRow(row, false, true));
- }
- @Test
- void shouldResumeRepairWriteBackFromPersistedCheckpoint() {
- assertEquals(0, RepairApprovalWriteBackService.resolveCompletedSteps("", 0, 0, 4));
- assertEquals(0, RepairApprovalWriteBackService.resolveCompletedSteps("部分失败", 3, 2, 4));
- assertEquals(1, RepairApprovalWriteBackService.resolveCompletedSteps("部分失败", 4, 3, 4));
- assertEquals(3, RepairApprovalWriteBackService.resolveCompletedSteps("部分失败", 4, 1, 4));
- assertEquals(4, RepairApprovalWriteBackService.resolveCompletedSteps("部分失败", 4, 0, 4));
- assertEquals(0, RepairApprovalWriteBackService.resolveCompletedSteps("全部成功", 4, 0, 4));
- }
- @Test
- void shouldPreserveSavedDraftHoursWhenRepairIsSubmitted() {
- Map<String, Object> existing = new HashMap<>();
- existing.put("projectCode", "P-001");
- existing.put("draftHours", 4d);
- existing.put("submittedHours", 4d);
- existing.put("clientName", "Client A");
- java.util.List<Map> rows = new java.util.ArrayList<>();
- rows.add(existing);
- Map<String, Object> submitted = new HashMap<>();
- submitted.put("projectCode", "P-001");
- submitted.put("submittedHours", 4d);
- TimeCardRepairService.mergeSubmittedRow(
- rows, submitted, "projectCode", "submittedHours", 4d);
- assertEquals(1, rows.size());
- assertEquals(4d, rows.get(0).get("draftHours"));
- assertEquals(4d, rows.get(0).get("submittedHours"));
- assertEquals("Client A", rows.get(0).get("clientName"));
- }
- @Test
- void shouldRecalculateRepairMainTotalsFromAllChildTables() {
- Map<String, Object> billable = new HashMap<>();
- billable.put("numberField_mmczo635", 0d);
- billable.put("numberField_mmczo636", 4d);
- billable.put("numberField_mmczo637", 0d);
- Map<String, Object> nonBillable = new HashMap<>();
- nonBillable.put("numberField_mmczo63b", 1d);
- nonBillable.put("numberField_mmczo63c", 0d);
- Map<String, Object> other = new HashMap<>();
- other.put("numberField_mmeakgik", 0d);
- other.put("numberField_mmeakgij", 2d);
- Map<String, Object> snapshot = new HashMap<>();
- snapshot.put("tableField_mmczo634", Collections.singletonList(billable));
- snapshot.put("tableField_mmczo63h", Collections.singletonList(nonBillable));
- snapshot.put("tableField_mmeakgid", Collections.singletonList(other));
- Map<String, Object> update = new HashMap<>();
- TimeCardRepairService.applySummaryTotals(update, snapshot);
- assertEquals(4d, update.get("numberField_mmacxewa"));
- assertEquals(1d, update.get("numberField_mmad6jbx"));
- assertEquals(2d, update.get("numberField_mmd1smeq"));
- assertEquals(1d, update.get("numberField_mmd1smel"));
- assertEquals(6d, update.get("numberField_mmd1smem"));
- }
- @Test
- void shouldUseDetailIdentityForRepairResubmitCoverage() {
- assertEquals("billable|u1|20260805|P-001",
- TimeCardRepairService.coverageKey("billable", "u1", "20260805", "P-001"));
- }
- @Test
- void shouldRecalculateRepairTotalsFromUpdatedApprovalSnapshot() {
- Map<String, Object> billable = new HashMap<>();
- billable.put("textField_mmacxew3", "P-001");
- billable.put("numberField_mmczo635", 8d);
- billable.put("numberField_mmczo636", 8d);
- billable.put("numberField_mmczo637", 0d);
- billable.put("numberField_mmczo637_value", 0d);
- billable.put("textField_mkov5ozd", "Project D4001");
- Map<String, Object> other = new HashMap<>();
- other.put("selectField_mmeakgie", "Time off in lieu of overtime");
- other.put("numberField_mmeakgik", 8d);
- other.put("numberField_mmeakgij", 8d);
- other.put("numberField_mmeakgii", 8d);
- Map<String, Object> detail = new HashMap<>();
- detail.put("tableField_mmczo634", Collections.singletonList(billable));
- detail.put("tableField_mmeakgid", Collections.singletonList(other));
- Map<String, Object> update = RepairApprovalWriteBackService.buildRepairSummaryUpdate(
- detail, false, true, "P-001", 8d, true);
- assertEquals(8d, update.get("numberField_mmacxewa"));
- assertEquals(8d, update.get("numberField_mmacxewg"));
- assertEquals(16d, update.get("numberField_mmd1smem"));
- assertEquals(16d, update.get("numberField_mmeakgi4"));
- assertEquals(16d, update.get("numberField_mmd1smel"));
- assertEquals("全部成功", RepairApprovalWriteBackService.resolveRepairSummaryStatus(update));
- Map updatedBillable = ((java.util.List<Map>) update.get("tableField_mmczo634")).get(0);
- assertEquals(8d, updatedBillable.get("numberField_mmczo637"));
- assertFalse(updatedBillable.containsKey("numberField_mmczo637_value"));
- assertEquals("Project D4001", updatedBillable.get("textField_mkov5ozd"));
- }
- @Test
- void shouldAggregateBillableAndNonBillableChangesByProjectCode() {
- List<RepairApprovalWriteBackService.Row> rows = new ArrayList<>();
- rows.add(repairRow("P-001", "Project A", 4d, true));
- rows.add(repairRow("P-001", "Project A", 6d, true));
- rows.add(repairRow("P-001", "Project A", 3d, false));
- rows.add(repairRow("P-002", "Project B", 5d, false));
- List<Map> billable = RepairApprovalWriteBackService.childChanges(rows, true);
- List<Map> nonBillable = RepairApprovalWriteBackService.childChanges(rows, false);
- assertEquals(1, billable.size());
- assertEquals("P-001", billable.get(0).get("textField_mmacxew3"));
- assertEquals("Project A", billable.get(0).get("selectField_mmad6jci"));
- assertEquals(10d, billable.get(0).get("numberField_mmd80zae"));
- assertEquals(2, nonBillable.size());
- assertEquals("P-001", nonBillable.get(0).get("textField_mmczo639"));
- assertEquals("Project A", nonBillable.get(0).get("selectField_mmczo638"));
- assertEquals(3d, nonBillable.get(0).get("numberField_mmeakgi9"));
- assertEquals("P-002", nonBillable.get(1).get("textField_mmczo639"));
- assertEquals(5d, nonBillable.get(1).get("numberField_mmeakgi9"));
- }
- private static RepairApprovalWriteBackService.Row repairRow(
- String projectCode, String projectName, double hours, boolean billable) {
- RepairApprovalWriteBackService.Row row = new RepairApprovalWriteBackService.Row();
- row.key = projectCode;
- row.projectName = projectName;
- row.hours = hours;
- row.billable = billable;
- row.approve = true;
- return row;
- }
- @Test
- void shouldKeepRepairSummaryPendingUntilAllCategoriesAreApproved() {
- Map<String, Object> totals = new HashMap<>();
- totals.put("numberField_mmd1smem", 16d);
- totals.put("numberField_mmeakgi4", 8d);
- assertEquals("审批中", RepairApprovalWriteBackService.resolveRepairSummaryStatus(totals));
- }
- @Test
- void shouldInitializeCreatedOriginalSummaryAsDraft() {
- Map<String, Object> update = new HashMap<>();
- RepairApprovalWriteBackService.putDraftSummaryStatus(update, "summaryStatus");
- assertEquals("暂存", update.get("summaryStatus"));
- }
- @Test
- void shouldOnlySkipMissingRequiredHoursForRepairSourceDay() {
- assertTrue(RepairApprovalWriteBackService.shouldSkipMissingRequiredRecord(true, 0));
- assertFalse(RepairApprovalWriteBackService.shouldSkipMissingRequiredRecord(false, 0));
- assertFalse(RepairApprovalWriteBackService.shouldSkipMissingRequiredRecord(true, 2));
- }
- @Test
- void shouldNeverTreatEmptyOrMalformedApprovalDetailsAsSuccess() {
- assertEquals("全部失败", ApprovalWriteBackService.determineSyncStatus(0, 0));
- assertEquals("全部失败", ApprovalWriteBackService.determineSyncStatus(1, 1));
- assertEquals("部分失败", ApprovalWriteBackService.determineSyncStatus(3, 1));
- assertEquals("全部成功", ApprovalWriteBackService.determineSyncStatus(3, 0));
- }
- }
|