Java tutorial
/* * Copyright (C) 2017 FormKiQ Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.formkiq.core.service.workflow; import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.isA; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.commons.lang3.tuple.Pair; import org.bouncycastle.util.Strings; import org.easymock.EasyMockRunner; import org.easymock.EasyMockSupport; import org.easymock.Mock; import org.easymock.TestSubject; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.context.ApplicationContext; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockMultipartFile; import org.springframework.mock.web.MockMultipartHttpServletRequest; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.web.servlet.ModelAndView; import com.formkiq.core.form.JSONService; import com.formkiq.core.form.dto.ArchiveDTO; import com.formkiq.core.form.dto.FormJSON; import com.formkiq.core.form.dto.FormJSONField; import com.formkiq.core.form.dto.Workflow; import com.formkiq.core.form.dto.WorkflowOutputPdfForm; import com.formkiq.core.form.service.FormCalculatorService; import com.formkiq.core.form.service.FormCalculatorServiceImpl; import com.formkiq.core.form.service.FormValidatorService; import com.formkiq.core.form.service.FormValidatorServiceImpl; import com.formkiq.core.service.ArchiveService; import com.formkiq.core.service.FolderService; import com.formkiq.core.service.dto.FormSaveResult; import com.formkiq.core.service.generator.WorkflowOutputGenerator; import com.formkiq.core.testdata.TestDataBuilder; import com.formkiq.core.webflow.FlowState; import com.formkiq.core.webflow.FlowStateType; import com.formkiq.core.webflow.WebFlow; import com.google.common.collect.ImmutableMap; /** * Unit Tests for {@link WorkflowEditorServiceImpl}. * */ @RunWith(EasyMockRunner.class) public class WorkflowEditorServiceImplTest extends EasyMockSupport { /** WorkflowEditorService. */ @TestSubject private WorkflowEditorServiceImpl ws = new WorkflowEditorServiceImpl(); /** ArchiveDTO. */ private ArchiveDTO archive = new ArchiveDTO(); /** {@link ApplicationContext}. */ @Mock private ApplicationContext context; /** ArchiveDTO. */ @Mock private ArchiveDTO mockarchive; /** ArchiveService. */ @Mock private ArchiveService archiveService; /** Mock. */ @Mock private WebFlow flow; /** Mock. */ @Mock private FolderService folderService; /** {@link FormCalculatorService}. */ private FormCalculatorService formCalculatorService = new FormCalculatorServiceImpl(); /** JSONService. */ private JSONService jsonService = new JSONService(); /** Mock. */ @Mock private List<WorkflowOutputGenerator> outputGenerators; /** Mock. */ @Mock private HttpServletRequest request; /** Mock. */ @Mock private HttpSession session; /** Mock. */ @Mock private WorkflowOutputGenerator pdfEditor; /** WorkflowService. */ private WorkflowService workflowService = new WorkflowServiceImpl(); /** Workflow. */ private Workflow workflow = new Workflow(); /** Workflow. */ @Mock private Workflow mockworkflow; /** {@link FormValidatorService}. */ private FormValidatorService validator = new FormValidatorServiceImpl(); /** Folder UUID. */ private String folder = UUID.randomUUID().toString(); /** UUID. */ private String uuid = UUID.randomUUID().toString(); /** * before. */ @Before public void before() { ReflectionTestUtils.setField(this.ws, "workflowService", this.workflowService); ReflectionTestUtils.setField(this.ws, "jsonService", this.jsonService); ReflectionTestUtils.setField(this.ws, "formCalculatorService", this.formCalculatorService); ReflectionTestUtils.setField(this.ws, "validatorService", this.validator); } /** * Expect Action. * @return {@link Workflow} */ private Workflow expectAction() { Workflow wf = new Workflow(); wf.setSteps(Arrays.asList("1", "2", "3")); wf.setPrintsteps(Arrays.asList("1", "2", "3")); this.archive.setWorkflow(wf); FlowState state = new FlowState(FlowStateType.DEFAULT, wf); // when expect(this.flow.getCurrentState()).andReturn(state); return wf; } /** * testEventAddStep01(). * Add step * @throws IOException IOException */ @SuppressWarnings("unchecked") @Test public void testEventAddStep01() throws IOException { // given this.archive.setWorkflow(this.workflow); // when expect(this.flow.getData()).andReturn(this.archive); this.flow.setStates(isA(List.class)); this.flow.setEventId(2); replayAll(); this.ws.eventIdaddstep(this.flow, this.request, null); // then verifyAll(); assertEquals(1, this.archive.getForms().size()); FormJSON form = this.archive.getForms().values().iterator().next(); assertEquals("New Form", form.getName()); assertNotNull(form.getUUID()); assertEquals(1, this.workflow.getSteps().size()); assertEquals(1, this.workflow.getPrintsteps().size()); assertTrue(this.workflow.getSteps().contains(form.getUUID())); assertTrue(this.workflow.getPrintsteps().contains(form.getUUID())); } /** * testEventAddStep02(). * Add step - MultipartHttpServletRequest * @throws IOException IOException */ @SuppressWarnings("unchecked") @Test public void testEventAddStep02() throws IOException { // given this.archive.setWorkflow(this.workflow); MockMultipartHttpServletRequest req = new MockMultipartHttpServletRequest(); req.setRequestURI("/home"); byte[] content = Strings.toByteArray("test"); req.addFile(new MockMultipartFile("sample.pdf", "sample.pdf", "", content)); // when expect(this.flow.getData()).andReturn(this.archive); this.flow.setStates(isA(List.class)); this.flow.setEventId(1); Map<String, WorkflowOutputGenerator> map = ImmutableMap.of("test", this.pdfEditor); expect(this.context.getBeansOfType(WorkflowOutputGenerator.class)).andReturn(map); expect(this.pdfEditor.getNewWorkflowOutputDocument()).andReturn(new WorkflowOutputPdfForm()); this.pdfEditor.generate(this.archive, "sample.pdf", content); replayAll(); this.ws.eventIdaddstep(this.flow, req, null); // then verifyAll(); } /** * testEventForms01(). * _eventId_forms. * @throws IOException IOException */ @Test public void testEventForms01() throws IOException { // given ArchiveDTO arch = new ArchiveDTO(); Workflow wf = new Workflow(); FormJSON form0 = TestDataBuilder.createSimpleForm(); FormJSON form1 = TestDataBuilder.createStoreReceipt(); wf.setSteps(Arrays.asList(form0.getUUID(), form1.getUUID())); arch.setWorkflow(wf); arch.addForm(form0); arch.addForm(form1); // when expect(this.flow.getData()).andReturn(arch); replayAll(); FormJSONField result = this.ws.eventIdforms(this.flow, new String[] { "81" }); // then verifyAll(); assertEquals("Simple Form[" + form0.getUUID() + "],Store Receipt[" + form1.getUUID() + "]", String.join(",", result.getOptions())); } /** * testEventIdformfields01(). * @throws Exception Exception */ @Test public void testEventIdformfields01() throws Exception { // given String formUUID = UUID.randomUUID().toString(); String param81 = "Test[" + formUUID + "]"; FormJSON testform = TestDataBuilder.createSimpleForm(); // when expect(this.flow.getData()).andReturn(this.mockarchive); expect(this.request.getParameter("81")).andReturn(param81); expect(this.mockarchive.getForm(formUUID)).andReturn(testform); replayAll(); FormJSONField field = this.ws.eventIdformfields(this.flow, this.request, null); // verify verifyAll(); assertEquals("Total ($)[1]", String.join(",", field.getOptions())); } /** * testEventIdformulaformfields01(). * no variables * @throws Exception Exception */ @Test public void testEventIdformulaformfields01() throws Exception { // given String formUUID = UUID.randomUUID().toString(); String param81 = "Test[" + formUUID + "]"; FormJSON testform = TestDataBuilder.createSimpleForm(); // when expect(this.flow.getData()).andReturn(this.mockarchive); expect(this.request.getParameter("83")).andReturn(param81); expect(this.mockarchive.getForm(formUUID)).andReturn(testform); replayAll(); FormJSONField field = this.ws.eventIdformulaformfields(this.flow, this.request); // verify verifyAll(); assertEquals("", String.join(",", field.getOptions())); } /** * testEventIdformulaformfields02(). * with variables * @throws Exception Exception */ @Test public void testEventIdformulaformfields02() throws Exception { // given String formUUID = UUID.randomUUID().toString(); String param81 = "Test[" + formUUID + "]"; FormJSON testform = TestDataBuilder.createStoreReceipt(); // when expect(this.flow.getData()).andReturn(this.mockarchive); expect(this.request.getParameter("83")).andReturn(param81); expect(this.mockarchive.getForm(formUUID)).andReturn(testform); replayAll(); FormJSONField field = this.ws.eventIdformulaformfields(this.flow, this.request); // verify verifyAll(); assertEquals("$subtotal,$tax,$delivery,$total", String.join(",", field.getOptions())); } /** * testEventIdformulaformfieldvar01(). * adding variable from current form * @throws IOException IOException */ @Test public void testEventIdformulaformfieldvar01() throws IOException { // given FormJSON testform = TestDataBuilder.createStoreReceipt(); FlowState state = new FlowState(FlowStateType.DEFAULT, testform); String[] param78 = new String[] {}; String[] param83 = new String[] { "Test[" + testform.getUUID() + "]" }; String[] param84 = new String[] { "$subtotal" }; // when expect(this.flow.getCurrentState()).andReturn(state); expect(this.request.getParameterValues("78")).andReturn(param78); expect(this.request.getParameterValues("83")).andReturn(param83); expect(this.request.getParameterValues("84")).andReturn(param84); replayAll(); FormJSONField result = this.ws.eventIdformulaformfieldvar(this.flow, this.request); // then verifyAll(); assertEquals("$subtotal", result.getValue()); } /** * testEventIdformulaformfieldvar02(). * adding variable from different form * @throws IOException IOException */ @Test public void testEventIdformulaformfieldvar02() throws IOException { // given FormJSON testform = TestDataBuilder.createStoreReceipt(); FormJSON currentform = TestDataBuilder.createSimpleForm(); FlowState state = new FlowState(FlowStateType.DEFAULT, currentform); String[] param78 = new String[] { "7*" }; String[] param83 = new String[] { testform.getName() + "[" + testform.getUUID() + "]" }; String[] param84 = new String[] { "$subtotal" }; // when expect(this.flow.getCurrentState()).andReturn(state); expect(this.request.getParameterValues("78")).andReturn(param78); expect(this.request.getParameterValues("83")).andReturn(param83); expect(this.request.getParameterValues("84")).andReturn(param84); replayAll(); FormJSONField result = this.ws.eventIdformulaformfieldvar(this.flow, this.request); // then verifyAll(); assertEquals("7*'Store Receipt'!$subtotal", result.getValue()); } /** * testEventIdremoveform01(). */ @SuppressWarnings("boxing") @Test public void testEventIdremoveform01() { // given FormJSON testform = TestDataBuilder.createSimpleForm(); List<String> steps = Arrays.asList(testform.getUUID()); this.workflow.setSteps(new ArrayList<>(steps)); this.workflow.setPrintsteps(new ArrayList<>(steps)); FlowState state = new FlowState(FlowStateType.DEFAULT, testform); // when expect(this.flow.getData()).andReturn(this.mockarchive); expect(this.mockarchive.getWorkflow()).andReturn(this.workflow); expect(this.flow.getCurrentState()).andReturn(state).times(2); this.mockarchive.removeForm(testform); expect(this.flow.removeState(state)).andReturn(true); replayAll(); this.ws.eventIdremoveform(this.flow, this.request); // then verifyAll(); assertEquals(0, this.workflow.getSteps().size()); assertEquals(0, this.workflow.getPrintsteps().size()); } /** * testEventIdremoveformfield01(). * remove field. */ @Test public void testEventIdremoveformfield01() { // given FormJSON form = TestDataBuilder.createAllFields(); int fieldcount = form.getSections().get(0).getFields().size(); assertTrue(fieldcount > 0); String[] fieldids = new String[] { "2" }; FlowState state = new FlowState(FlowStateType.DEFAULT, form); // when expect(this.flow.getCurrentState()).andReturn(state); replayAll(); this.ws.eventIdremoveformfield(this.flow, this.request, fieldids); // then verifyAll(); int fieldcount2 = form.getSections().get(0).getFields().size(); assertEquals(fieldcount2, fieldcount - 1); } /** * testEventIdremoveprintstep01() * remove print step. */ @Test public void testEventIdremoveprintstep01() { // given String[] fieldids = new String[] { "1" }; this.workflow.setPrintsteps(new ArrayList<>(Arrays.asList("1", "2", "3"))); // when expect(this.flow.getData()).andReturn(this.mockarchive); expect(this.mockarchive.getWorkflow()).andReturn(this.workflow); replayAll(); this.ws.eventIdremoveprintstep(this.flow, fieldids); // then verifyAll(); assertEquals("1,3", String.join(",", this.workflow.getPrintsteps())); } /** * testEventIdremoveprintstep02() * remove -1 print step. */ @Test public void testEventIdremoveprintstep02() { // given String[] fieldids = new String[] { "" }; this.workflow.setPrintsteps(new ArrayList<>(Arrays.asList("1", "2", "3"))); // when expect(this.flow.getData()).andReturn(this.mockarchive); expect(this.mockarchive.getWorkflow()).andReturn(this.workflow); replayAll(); this.ws.eventIdremoveprintstep(this.flow, fieldids); // then verifyAll(); assertEquals("1,2,3", String.join(",", this.workflow.getPrintsteps())); } /** * testEventIdremoveprintstep03() * remove 10th print step. */ @Test public void testEventIdremoveprintstep03() { // given String[] fieldids = new String[] { "10" }; this.workflow.setPrintsteps(new ArrayList<>(Arrays.asList("1", "2", "3"))); // when expect(this.flow.getData()).andReturn(this.mockarchive); expect(this.mockarchive.getWorkflow()).andReturn(this.workflow); replayAll(); this.ws.eventIdremoveprintstep(this.flow, fieldids); // then verifyAll(); assertEquals("1,2,3", String.join(",", this.workflow.getPrintsteps())); } /** * testEventStepdown01(). * _eventId_stepdown up. * @throws IOException IOException */ @Test public void testEventStepdown01() throws IOException { // given Workflow wf = expectAction(); replayAll(); this.ws.eventIdstepdown(this.flow, this.request, new String[] { "0" }); // then verifyAll(); assertEquals("2,1,3", String.join(",", wf.getSteps())); assertEquals("1,2,3", String.join(",", wf.getPrintsteps())); } /** * testEventStepdown02(). * _eventId_stepdown up at max size. * @throws IOException IOException */ @Test public void testEventStepdown02() throws IOException { // given // when Workflow wf = expectAction(); replayAll(); this.ws.eventIdstepdown(this.flow, this.request, new String[] { "2" }); // then verifyAll(); assertEquals("1,2,3", String.join(",", wf.getSteps())); assertEquals("1,2,3", String.join(",", wf.getPrintsteps())); } /** * testEventStepdown03(). * _eventId_stepdown up at max size. * @throws IOException IOException */ @Test public void testEventStepdown03() throws IOException { // given // when Workflow wf = expectAction(); replayAll(); this.ws.eventIdstepdown(this.flow, this.request, new String[] { "-1" }); // then verifyAll(); assertEquals("1,2,3", String.join(",", wf.getSteps())); assertEquals("1,2,3", String.join(",", wf.getPrintsteps())); } /** * testEventStepup01(). * _eventId_stepup. No Change. * @throws IOException IOException */ @Test public void testEventStepup01() throws IOException { // given Workflow wf = expectAction(); replayAll(); this.ws.eventIdstepup(this.flow, this.request, new String[] { "0" }); // then verifyAll(); assertEquals("1,2,3", String.join(",", wf.getSteps())); assertEquals("1,2,3", String.join(",", wf.getPrintsteps())); } /** * testEventStepup02(). * _eventId_stepup up at max size. * @throws IOException IOException */ @Test public void testEventStepup02() throws IOException { // given Workflow wf = expectAction(); // when replayAll(); this.ws.eventIdstepup(this.flow, this.request, new String[] { "3" }); // then verifyAll(); assertEquals("1,2,3", String.join(",", wf.getSteps())); assertEquals("1,2,3", String.join(",", wf.getPrintsteps())); } /** * testEventStepup03(). * _eventId_stepup up at max size. * @throws IOException IOException */ @Test public void testEventStepup03() throws IOException { // given Workflow wf = expectAction(); // when replayAll(); this.ws.eventIdstepup(this.flow, this.request, new String[] { "-1" }); // then verifyAll(); assertEquals("1,2,3", String.join(",", wf.getSteps())); assertEquals("1,2,3", String.join(",", wf.getPrintsteps())); } /** * testEventStepup04(). * _eventId_stepup last item of list. * @throws IOException IOException */ @Test public void testEventStepup04() throws IOException { // given Workflow wf = expectAction(); // when replayAll(); this.ws.eventIdstepup(this.flow, this.request, new String[] { "2" }); // then verifyAll(); assertEquals("1,3,2", String.join(",", wf.getSteps())); assertEquals("1,2,3", String.join(",", wf.getPrintsteps())); } /** * testEventStepup05(). * _eventId_stepup item 1. * @throws IOException IOException */ @Test public void testEventStepup05() throws IOException { // given Workflow wf = expectAction(); // when replayAll(); this.ws.eventIdstepup(this.flow, this.request, new String[] { "1" }); // then verifyAll(); assertEquals("2,1,3", String.join(",", wf.getSteps())); assertEquals("1,2,3", String.join(",", wf.getPrintsteps())); } /** * testPrintStepdown01(). * _eventId_printstepup up. * @throws IOException IOException */ @Test public void testPrintStepdown01() throws IOException { // given Workflow wf = expectAction(); // when replayAll(); this.ws.eventIdprintstepdown(this.flow, this.request, new String[] { "0" }); // then verifyAll(); assertEquals("1,2,3", String.join(",", wf.getSteps())); assertEquals("2,1,3", String.join(",", wf.getPrintsteps())); } /** * testPrintStepup01(). * _eventId_printstepup last item of list. * @throws IOException IOException */ @Test public void testPrintStepup01() throws IOException { // given Workflow wf = expectAction(); // when replayAll(); this.ws.eventIdprintstepup(this.flow, this.request, new String[] { "2" }); // then verifyAll(); assertEquals("1,2,3", String.join(",", wf.getSteps())); assertEquals("1,3,2", String.join(",", wf.getPrintsteps())); } /** * testSave01(). * has errors * @throws IOException IOException */ @Test public void testSave01() throws IOException { // given String execution = "s1e1"; String sha1hash = UUID.randomUUID().toString(); Map<String, String> errors = ImmutableMap.of("errors", "1"); FormSaveResult saveResult = new FormSaveResult(null, "", errors); // when expect(this.request.getParameter("execution")).andReturn(execution); expect(this.request.getSession()).andReturn(this.session); expect(this.session.getAttribute("s1")).andReturn(this.flow); expect(this.flow.getData()).andReturn(this.archive); expect(this.flow.getParameter("folder")).andReturn(this.folder); expect(this.flow.getParameter("sha1hash")).andReturn(sha1hash); expect(this.folderService.saveForm(this.folder, this.archive, sha1hash, false)).andReturn(saveResult); this.flow.setParameter("errors", errors); replayAll(); Map<String, String> result = this.ws.save(this.request); // then verifyAll(); assertFalse(result.isEmpty()); } /** * testSave02(). * no errors * @throws IOException IOException */ @Test public void testSave02() throws IOException { // given String execution = "s1e1"; String sha1hash = UUID.randomUUID().toString(); Map<String, String> errors = new HashMap<>(); FormSaveResult saveResult = new FormSaveResult(null, "", errors); // when expect(this.request.getParameter("execution")).andReturn(execution).times(2); expect(this.request.getSession()).andReturn(this.session).anyTimes(); expect(this.session.getAttribute("s1")).andReturn(this.flow).times(2); expect(this.flow.getData()).andReturn(this.archive); expect(this.flow.getParameter("folder")).andReturn(this.folder); expect(this.flow.getParameter("sha1hash")).andReturn(sha1hash); expect(this.folderService.saveForm(this.folder, this.archive, sha1hash, false)).andReturn(saveResult); expect(this.flow.getSessionKey()).andReturn(execution); this.session.removeAttribute("s1"); replayAll(); Map<String, String> result = this.ws.save(this.request); // then verifyAll(); assertTrue(result.isEmpty()); } /** * testSave03(). * saving throws exception * @throws IOException IOException */ @Test public void testSave03() throws IOException { // given String execution = "s1e1"; String sha1hash = UUID.randomUUID().toString(); RuntimeException exception = new RuntimeException("dummy error"); // when expect(this.request.getParameter("execution")).andReturn(execution); expect(this.request.getSession()).andReturn(this.session).anyTimes(); expect(this.session.getAttribute("s1")).andReturn(this.flow); expect(this.flow.getData()).andReturn(this.archive); expect(this.flow.getParameter("folder")).andReturn(this.folder); expect(this.flow.getParameter("sha1hash")).andReturn(sha1hash); expect(this.folderService.saveForm(this.folder, this.archive, sha1hash, false)).andThrow(exception); this.flow.setParameter(eq("errors"), isA(Map.class)); replayAll(); Map<String, String> result = this.ws.save(this.request); // then verifyAll(); assertEquals(1, result.size()); assertEquals("dummy error", result.get("error")); } /** * testStartEdit01(). * @throws IOException IOException * */ @Test public void testStartEdit01() throws IOException { // given MockHttpServletRequest req = new MockHttpServletRequest(); FormJSON form = TestDataBuilder.createAllFields(); String sha1hash = UUID.randomUUID().toString(); String step = UUID.randomUUID().toString(); List<String> steps = Arrays.asList(step); // when expect(this.archiveService.get(this.folder, this.uuid, false)) .andReturn(Pair.of(this.mockarchive, sha1hash)); expect(this.mockarchive.getWorkflow()).andReturn(this.mockworkflow).times(2); expect(this.mockworkflow.getSteps()).andReturn(steps); expect(this.mockarchive.getForm(step)).andReturn(form); replayAll(); Pair<ModelAndView, WebFlow> result = this.ws.startEdit(req, this.folder, this.uuid); // then verifyAll(); final int states = 5; ModelAndView mav = result.getLeft(); assertEquals("redirect:/user/designer/edit?execution=s1e1", mav.getViewName()); WebFlow wf = result.getRight(); assertEquals(states, wf.getStates().size()); } /** * testStartEdit02(). * start on new entry, IE: UUID is null * @throws IOException IOException * */ @Test public void testStartEdit02() throws IOException { // given String uuidNull = null; MockHttpServletRequest req = new MockHttpServletRequest(); // when replayAll(); Pair<ModelAndView, WebFlow> result = this.ws.startEdit(req, this.folder, uuidNull); // then verifyAll(); final int states = 4; ModelAndView mav = result.getLeft(); assertEquals("redirect:/user/designer/edit?execution=s1e1", mav.getViewName()); WebFlow wf = result.getRight(); assertEquals(states, wf.getStates().size()); } }