刘光辉
8 小时以前 06f314545ac3514d7ce28939920866ae8188d31c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package jnpf.base.util;
import jnpf.base.model.uploadedit.UploadEditDraft;
import jnpf.exception.DataException;
import jnpf.util.JsonUtil;
import jnpf.util.TicketUtil;
import org.junit.Test;
import java.util.*;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
public class UploadTemplateSourceTest {
    Map<String,Object> file(String id, String template) {
        Map<String,Object> file = new LinkedHashMap<>(); file.put("fileId", id); file.put("name", "same.docx");
        if (template != null) file.put(UploadTemplateSource.FIELD, template); return file;
    }
    @Test public void editingKeepsSourceDeletingReuploadingClearsAndDiscardRestores() {
        UploadEditDraft draft = new UploadEditDraft(); draft.setRevision(0L);
        draft.setBaselineJson(JsonUtil.getObjectToString(List.of(file("A", "templateA")))); draft.setCurrentJson(draft.getBaselineJson());
        UploadEditStateMachine.begin(draft, 0L, "A"); String lease = draft.getLeaseId();
        assertTrue(UploadEditStateMachine.save(draft, lease, "save1", file("edited", "forged")));
        assertEquals("templateA", UploadEditStateMachine.files(draft.getCurrentJson()).get(0).get(UploadTemplateSource.FIELD));
        UploadEditStateMachine.replace(draft, draft.getRevision(), List.of());
        assertFalse(UploadEditStateMachine.save(draft, lease, "late", file("late", "templateA")));
        var upload = file("new", "forged");
        UploadTemplateSource.normalize(List.of(upload), List.of(file("A", "templateA")), "tenant", "owner");
        assertFalse(upload.containsKey(UploadTemplateSource.FIELD));
        UploadEditStateMachine.replace(draft, draft.getRevision(), List.of(upload));
        UploadEditStateMachine.discard(draft, draft.getRevision());
        assertEquals("templateA", UploadEditStateMachine.files(draft.getCurrentJson()).get(0).get(UploadTemplateSource.FIELD));
    }
    @Test public void newVerifiedReceiptOverridesSameFileIdAndRejectsForgedReceipt() {
        var submitted = file("A", "forged"); submitted.put("uploadReceipt", "new");
        Map<String,Object> proof = file("A", "templateB"); proof.put("purpose", "upload-edit-source");
        proof.put("tenantId", "tenant"); proof.put("ownerId", "owner");
        try (var tickets = mockStatic(TicketUtil.class)) {
            tickets.when(() -> TicketUtil.parseTicket("new")).thenReturn(JsonUtil.getObjectToString(proof));
            UploadTemplateSource.normalize(List.of(submitted), List.of(file("A", "templateA")), "tenant", "owner");
            assertEquals("templateB", submitted.get(UploadTemplateSource.FIELD));
            try { UploadTemplateSource.normalize(List.of(submitted), List.of(), "other", "owner"); fail("tenant mismatch must fail"); } catch (DataException expected) { }
        }
    }
    @Test public void serverTimeIsPreservedButClientTimeIsNotTrusted() {
        var trusted = file("A", "templateA"); trusted.put("contentSavedAt", 100L);
        var submitted = file("A", "forged"); submitted.put("contentSavedAt", 999L);
        UploadTemplateSource.normalize(List.of(submitted), List.of(trusted), "tenant", "owner");
        assertEquals(100L, submitted.get("contentSavedAt"));
        var ordinary = file("B", "forged"); ordinary.put("contentSavedAt", 999L);
        UploadTemplateSource.normalize(List.of(ordinary), List.of(trusted), "tenant", "owner");
        assertFalse(ordinary.containsKey("contentSavedAt"));
        assertFalse(ordinary.containsKey(UploadTemplateSource.FIELD));
    }
    @Test public void savedCopyKeepsTemplateButUsesNewServerTimeAndMetadataToken() {
        var original = file("A", "templateA"); original.put("contentSavedAt", 100L);
        UploadEditDraft draft = new UploadEditDraft(); draft.setRevision(0L);
        draft.setBaselineJson(JsonUtil.getObjectToString(List.of(original))); draft.setCurrentJson(draft.getBaselineJson());
        UploadEditStateMachine.begin(draft, 0L, "A");
        var saved = file("B", "forged"); saved.put("contentSavedAt", 200L);
        assertTrue(UploadEditStateMachine.save(draft, draft.getLeaseId(), "saved", saved));
        var actual = UploadEditStateMachine.files(draft.getCurrentJson()).get(0);
        assertEquals("templateA", actual.get(UploadTemplateSource.FIELD));
        assertEquals(200L, ((Number) actual.get("contentSavedAt")).longValue());
        var otherTemplate = file("A", "templateB"); otherTemplate.put("contentSavedAt", 100L);
        assertEquals(UploadEditStateMachine.contentToken(List.of(original)), UploadEditStateMachine.contentToken(List.of(otherTemplate)));
        assertNotEquals(UploadEditStateMachine.metadataToken(List.of(original)), UploadEditStateMachine.metadataToken(List.of(otherTemplate)));
    }
}