package jnpf.base.util; import jnpf.base.model.uploadedit.UploadEditDraft; import jnpf.exception.DataException; import jnpf.util.JsonUtil; import org.junit.Test; import java.util.*; import static org.junit.Assert.*; public class UploadEditStateMachineTest { private Map file(String id) { Map file = new LinkedHashMap<>(); file.put("fileId", id); file.put("name", id + ".docx"); return file; } private UploadEditDraft draft() { UploadEditDraft draft = new UploadEditDraft(); draft.setRevision(0L); draft.setBaselineJson(JsonUtil.getObjectToString(Collections.singletonList(file("A")))); draft.setCurrentJson(draft.getBaselineJson()); return draft; } private String current(UploadEditDraft draft) { return String.valueOf(UploadEditStateMachine.files(draft.getCurrentJson()).get(0).get("fileId")); } @Test public void legacyDocCanAdoptConvertedDocxWithoutChangingItsBaseline() { for (String name : Arrays.asList("legacy.doc", "legacy.DOC")) { UploadEditDraft draft = draft(); Map source = file("A"); source.put("name", name); draft.setBaselineJson(JsonUtil.getObjectToString(Collections.singletonList(source))); draft.setCurrentJson(draft.getBaselineJson()); assertEquals(name, UploadEditStateMachine.begin(draft, 0L, "A").get("name")); assertTrue(UploadEditStateMachine.save(draft, draft.getLeaseId(), "converted", file("B"))); assertEquals(name, UploadEditStateMachine.files(draft.getBaselineJson()).get(0).get("name")); assertEquals("B.docx", UploadEditStateMachine.begin(draft, draft.getRevision(), "B").get("name")); } } @Test public void otherFormatsRemainUnsupported() { for (String name : Arrays.asList("file.pdf", "file.docm", "file.xlsx", "file.doc.exe")) { UploadEditDraft draft = draft(); Map source = file("A"); source.put("name", name); draft.setCurrentJson(JsonUtil.getObjectToString(Collections.singletonList(source))); try { UploadEditStateMachine.begin(draft, 0L, "A"); fail("accepted " + name); } catch (DataException expected) { assertNull(draft.getLeaseId()); } } } @Test public void saveAsPreservesBaselineAndContinuesLatestFile() { UploadEditDraft draft = draft(); UploadEditStateMachine.begin(draft, 0L, "A"); String lease = draft.getLeaseId(); assertTrue(UploadEditStateMachine.save(draft, lease, "save1", file("B"))); assertEquals("B", current(draft)); assertEquals("A", UploadEditStateMachine.files(draft.getBaselineJson()).get(0).get("fileId")); assertTrue(UploadEditStateMachine.save(draft, lease, "save2", file("B2"))); Map source = UploadEditStateMachine.begin(draft, draft.getRevision(), "B2"); assertEquals("B2", source.get("fileId")); } @Test public void duplicateCallbackDoesNotAdvanceOrReplace() { UploadEditDraft draft = draft(); UploadEditStateMachine.begin(draft, 0L, "A"); UploadEditStateMachine.save(draft, draft.getLeaseId(), "once", file("B")); Long revision = draft.getRevision(); assertTrue(UploadEditStateMachine.save(draft, draft.getLeaseId(), "once", file("C"))); assertEquals(revision, draft.getRevision()); assertEquals("B", current(draft)); } @Test public void uploadReplacementInvalidatesOldCallbackAndOpensUploadDirectly() { UploadEditDraft draft = draft(); UploadEditStateMachine.begin(draft, 0L, "A"); String old = draft.getLeaseId(); UploadEditStateMachine.replace(draft, draft.getRevision(), Collections.singletonList(file("C"))); assertFalse(UploadEditStateMachine.save(draft, old, "late", file("B"))); assertEquals("C", UploadEditStateMachine.begin(draft, draft.getRevision(), "C").get("fileId")); } @Test public void discardRestoresLastAdoptedContentAndRejectsLateSave() { UploadEditDraft draft = draft(); UploadEditStateMachine.begin(draft, 0L, "A"); UploadEditStateMachine.save(draft, draft.getLeaseId(), "s1", file("B")); UploadEditStateMachine.adopt(draft, draft.getRevision(), draft.getCurrentJson()); UploadEditStateMachine.begin(draft, draft.getRevision(), "B"); String old = draft.getLeaseId(); UploadEditStateMachine.save(draft, old, "s2", file("C")); UploadEditStateMachine.discard(draft, draft.getRevision()); assertEquals("B", current(draft)); assertFalse(UploadEditStateMachine.save(draft, old, "s3", file("D"))); } @Test public void adoptedLeaseCannotModifyHistory() { UploadEditDraft draft = draft(); UploadEditStateMachine.begin(draft, 0L, "A"); String old = draft.getLeaseId(); UploadEditStateMachine.save(draft, old, "s1", file("B")); UploadEditStateMachine.adopt(draft, draft.getRevision(), draft.getCurrentJson()); assertFalse(UploadEditStateMachine.save(draft, old, "s2", file("C"))); assertEquals("B", current(draft)); } @Test(expected = DataException.class) public void staleFormCannotAdoptNewerEdit() { UploadEditDraft draft = draft(); UploadEditStateMachine.begin(draft, 0L, "A"); UploadEditStateMachine.save(draft, draft.getLeaseId(), "s1", file("B")); UploadEditStateMachine.adopt(draft, 1L, Collections.singletonList(file("A"))); } @Test(expected = DataException.class) public void submittedSourceCannotReplaceWorkingResult() { UploadEditDraft draft = draft(); UploadEditStateMachine.begin(draft, 0L, "A"); UploadEditStateMachine.save(draft, draft.getLeaseId(), "s1", file("B")); UploadEditStateMachine.adopt(draft, draft.getRevision(), Collections.singletonList(file("A"))); } @Test(expected = DataException.class) public void rejectsDuplicateAttachmentIds() { UploadEditStateMachine.files(Arrays.asList(file("A"), file("A"))); } @Test public void repeatedEditingRetainsOriginalSourceAcrossLeases() { UploadEditDraft draft = draft(); UploadEditStateMachine.begin(draft, 0L, "A"); UploadEditStateMachine.save(draft, draft.getLeaseId(), "s1", file("B")); UploadEditStateMachine.begin(draft, draft.getRevision(), "B"); UploadEditStateMachine.save(draft, draft.getLeaseId(), "s2", file("D")); assertEquals(Collections.singletonMap("D", "A"), UploadEditStateMachine.editOrigins(draft)); } @Test public void replacementDropsOldEditOriginAndAdoptionResetsBaseline() { UploadEditDraft draft = draft(); UploadEditStateMachine.begin(draft, 0L, "A"); UploadEditStateMachine.save(draft, draft.getLeaseId(), "s1", file("B")); UploadEditStateMachine.replace(draft, draft.getRevision(), Collections.singletonList(file("C"))); assertTrue(UploadEditStateMachine.editOrigins(draft).isEmpty()); UploadEditStateMachine.begin(draft, draft.getRevision(), "C"); UploadEditStateMachine.save(draft, draft.getLeaseId(), "s2", file("D")); assertEquals(Collections.singletonMap("D", "C"), UploadEditStateMachine.editOrigins(draft)); UploadEditStateMachine.adopt(draft, draft.getRevision(), draft.getCurrentJson()); assertTrue(UploadEditStateMachine.editOrigins(draft).isEmpty()); } @Test public void discardClearsUnadoptedEditOrigins() { UploadEditDraft draft = draft(); UploadEditStateMachine.begin(draft, 0L, "A"); UploadEditStateMachine.save(draft, draft.getLeaseId(), "s1", file("B")); UploadEditStateMachine.discard(draft, draft.getRevision()); assertTrue(UploadEditStateMachine.editOrigins(draft).isEmpty()); } @Test public void eachSuccessfulTransitionBecomesTheNextEditorsBaseline() { UploadEditDraft draft = draft(); UploadEditStateMachine.begin(draft, 0L, "A"); UploadEditStateMachine.save(draft, draft.getLeaseId(), "review-mark", file("B")); UploadEditStateMachine.adopt(draft, draft.getRevision(), draft.getCurrentJson()); assertEquals("B", UploadEditStateMachine.files(draft.getBaselineJson()).get(0).get("fileId")); Map source = UploadEditStateMachine.begin(draft, draft.getRevision(), "B"); assertEquals("B", source.get("fileId")); UploadEditStateMachine.save(draft, draft.getLeaseId(), "author-revision", file("C")); UploadEditStateMachine.adopt(draft, draft.getRevision(), draft.getCurrentJson()); assertEquals("C", UploadEditStateMachine.files(draft.getBaselineJson()).get(0).get("fileId")); assertEquals("C", current(draft)); } }