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.web; import static com.formkiq.core.api.AbstractRestController.ACCEPT_HEADER_V1; import static com.formkiq.core.form.FormFinder.findField; import static com.formkiq.core.form.FormFinder.findValueByKey; import static com.formkiq.core.form.bean.ObjectBuilder.buildArchiveDTO; import static com.formkiq.core.util.Resources.getResourceAsString; import static com.formkiq.core.util.Strings.CHARSET_UTF8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.internet.MimeMessage; import org.apache.commons.lang3.tuple.Pair; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Action; import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.support.ui.ExpectedConditions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.formkiq.core.domain.type.FolderFormsListDTO; import com.formkiq.core.domain.type.FormDTO; import com.formkiq.core.domain.type.QueueDTO; import com.formkiq.core.domain.type.QueueListDTO; import com.formkiq.core.domain.type.UserDTO; import com.formkiq.core.equifax.service.EquifaxServiceLocal; 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.FormJSONFieldType; import com.formkiq.core.form.dto.FormJSONSection; import com.formkiq.core.form.dto.Workflow; import com.formkiq.core.service.ArchiveService; import com.formkiq.core.service.generator.pdfbox.PdfEditorServiceImpl; import com.formkiq.core.service.queue.DocSignQueueMessage; import com.formkiq.core.service.workflow.WorkflowEditorService; import com.formkiq.core.testdata.TestDataBuilder; import com.formkiq.core.util.Resources; import com.formkiq.core.util.Strings; import com.formkiq.core.util.Zips; import com.formkiq.core.webflow.WebFlow; /** * WorkflowController Add Integration Test. * */ @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = Application.class, webEnvironment = DEFINED_PORT) @ActiveProfiles("dev") public class WorkflowAddControllerIntegrationTest extends SeleniumTestBase { /** Sample Form 2 Title. */ private static final String SAMPLE_FORM2 = "Public Service Health Care " + "Plan (PSHCP) Claim Form"; /** Sample Form 2 Title. */ private static final String SAMPLE_FORM_2_HTML_TITLE = "FormKiQ Server - " + SAMPLE_FORM2; /** JSON Default Format. */ private SimpleDateFormat jsonDateFormat = new SimpleDateFormat(JSONService.DEFAULT_DATE_FORMAT); /** ArchiveService. */ @Autowired private ArchiveService archiveService; /** {@link EquifaxServiceLocal}. */ @Autowired private EquifaxServiceLocal equifaxService; /** JSONService. */ @Autowired private JSONService jsonService; /** {@link PdfEditorServiceImpl}.*/ @Autowired private PdfEditorServiceImpl pdfEditorService; /** {@link WorkflowEditorService}. */ @Autowired private WorkflowEditorService workflowEditorService; /** * Assert FormJSONField. * @param field {@link FormJSONField} * @param id int * @param label {@link String} * @param type {@link String} * @param value {@link String} */ private void assertField(final FormJSONField field, final int id, final String label, final FormJSONFieldType type, final String value) { assertEquals(id, field.getId()); assertEquals(label, field.getLabel()); assertEquals(type, field.getType()); assertEquals(value, field.getValue()); } @Override @Before public void before() throws Exception { super.before(); truncateTables("folders", "folder_forms"); } /** * Logs in and click the first workflow. */ private void clickCreateWorkflow() { login(getDefaultEmail()); getDriver().navigate().to(getDefaultHostAndPort() + "/user/dashboard"); waitForJSandJQueryToLoad(); assertEquals("FormKiQ Server - Dashboard", getTitle()); findElementBy(By.id("add_entry_0")).click(); } /** * Fill Docsign Form. */ private void fillDocsign() { findElementBy(By.name("2")).sendKeys("jacksmith@formkiq.com"); findElementBy(By.name("3")).sendKeys("Jack Smith"); findElementBy(By.name("4")).sendKeys("sign this"); findElementBy(By.name("5")).sendKeys("John Smith"); } /** * fill Schedule B. */ private void fillScheduleB() { findElementBy(By.name("2")).sendKeys("10"); findElementBy(By.name("3")).sendKeys("111"); findElementBy(By.name("4")).sendKeys("2222222"); findElementBy(By.name("5")).sendKeys("33333"); findElementBy(By.name("6")).sendKeys("123 Main St."); } /** * Fill Signature. * @param datafieldid {@link String} */ private void fillSignature(final String datafieldid) { WebElement element = findElementBy("canvas", "data-fieldid", datafieldid); final int startXY = 50; Actions builder = new Actions(getDriver()); Action drawAction = builder.moveToElement(element, startXY, startXY).clickAndHold() .moveByOffset(startXY, startXY).release().build(); drawAction.perform(); } /** * Find Href URL in string. * @param s {@link String} * @return {@link String} */ private String findHrefUrl(final String s) { Pattern p = Pattern.compile("href=\"(.*?)\""); Matcher m = p.matcher(s); String url = null; if (m.find()) { url = m.group(1); // this variable should contain the link URL } return url; } /** * Find the index position for {@link FormJSONFieldType}. * @param type {@link FormJSONFieldType} * @return int */ private int findIndex(final FormJSONFieldType type) { return Arrays.asList(FormJSONFieldType.values()).indexOf(type) + 1; } /** * Get Submit Buttons. * @return {@link List} */ private List<WebElement> getSubmitButtons() { List<WebElement> elements = getDriver().findElements(By.xpath("//*[@type='submit']")); return elements; } /** * Click Submit Button by name. * @param name {@link String} * @param text {@link String} */ private void submitByName(final String name, final String text) { submitByName(name, text, TIMEOUT); } /** * Click Submit Button by name. * @param name {@link String} * @param text {@link String} * @param timeout long */ private void submitByName(final String name, final String text, final long timeout) { List<WebElement> elements = getSubmitButtons(); for (WebElement element : elements) { if (name.equals(element.getAttribute("name"))) { assertEquals(text, element.getText()); element.click(); break; } } } /** * testWorkflow01(). * get workflow as ADMIN * @throws Exception Exception */ @Test public void testCreateWorkflow01() throws Exception { // given final long sleep = 250L; FormJSON form = TestDataBuilder.createStoreReceipt(); Workflow workflow = TestDataBuilder.createWorkflow(form); String token = login(); String folder = createFolder(token, getDefaultEmail()); addFileToFolder(token, folder, workflow, form); // when login(getDefaultEmail()); getDriver().navigate().to(getDefaultHostAndPort() + "/user/dashboard"); waitForJSandJQueryToLoad(); assertEquals("FormKiQ Server - Dashboard", getTitle()); findElementBy(By.className("add_0")).click(); // then (verify on correct page) assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e1", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - Store Receipt", getTitle()); // when (enter data) WebElement element = findElementBy(By.name("1")); element.sendKeys("10"); element = findElementBy(By.name("1")); assertEquals("10", element.getAttribute("value")); JavascriptExecutor jsExecutor = (JavascriptExecutor) getDriver(); jsExecutor.executeScript("calculate();", element); Thread.sleep(sleep); getDriver().navigate().refresh(); // then (verify data calculations) element = findElementBy(By.name("2")); assertEquals("$0.70", element.getAttribute("value")); element = findElementBy(By.name("3")); assertEquals("$7.99", element.getAttribute("value")); element = findElementBy(By.name("4")); assertEquals("$18.69", element.getAttribute("value")); List<WebElement> elements = getSubmitButtons(); assertEquals(1, elements.size()); // when (submit) submitByName("_eventId_next", "Next"); // then verify complete assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e2", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - Sample WF Complete", getTitle()); assertTrue(getDriver().getPageSource().contains("end-of-document")); String pageSource = getDriver().getPageSource(); assertTrue(pageSource.contains("The workflow has been saved.")); FolderFormsListDTO formlist = getFolderFileList(token, folder, workflow.getUUID()); assertEquals(1, formlist.getForms().size()); FormDTO fdto = formlist.getForms().get(0); assertNotEquals(workflow.getUUID(), fdto.getUUID()); byte[] data = getFolderFile(token, folder, fdto.getUUID(), MediaType.valueOf(ACCEPT_HEADER_V1 + "+zip"), false).getBody(); ArchiveDTO archive = this.archiveService.extractJSONFromZipFile(data); workflow = archive.getWorkflow(); assertNotNull(workflow); assertEquals(1, archive.getForms().size()); form = archive.getForms().values().iterator().next(); assertTrue(workflow.getSteps().contains(form.getUUID())); assertEquals(workflow.getParentUUID(), form.getParentUUID()); int i = 1; assertEquals("$10.00", findField(form, i++).get().getValue()); assertEquals("$0.70", findField(form, i++).get().getValue()); assertEquals("$7.99", findField(form, i++).get().getValue()); assertEquals("$18.69", findField(form, i++).get().getValue()); } /** * testWorkflow02(). * save form but fails validation * @throws Exception Exception */ @Test public void testCreateWorkflow02() throws Exception { // given FormJSON form = TestDataBuilder.createStoreReceipt(); Workflow workflow = TestDataBuilder.createWorkflow(form); String token = login(); String folder = createFolder(token, getDefaultEmail()); addFileToFolder(token, folder, workflow, form); // when login(getDefaultEmail()); getDriver().navigate().to(getDefaultHostAndPort() + "/user/dashboard"); waitForJSandJQueryToLoad(); assertEquals("FormKiQ Server - Dashboard", getTitle()); findElementBy(By.id("add_entry_0")).click(); // then (verify on correct page) assertEquals("FormKiQ Server - Store Receipt", getTitle()); // when (enter data) submitByName("_eventId_next", "Next"); // then verify summary assertNotEquals("FormKiQ Server - Workflow Sample WF", getTitle()); assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e1", getDriver().getCurrentUrl()); String pageSource = getDriver().getPageSource(); assertFalse(pageSource.contains("end-of-document")); List<WebElement> elements = getDriver().findElements(By.xpath("//*[@class='fa fa-exclamation-circle']")); assertEquals(form.getSections().get(0).getFields().size(), elements.size()); assertEquals("Field required", elements.get(0).getText()); } /** * testWorkflow03(). * Fill Form, Press Next then change URL to previous form * @throws Exception Exception */ @Test public void testCreateWorkflow03() throws Exception { // given FormJSON form0 = TestDataBuilder.createStoreReceipt(); FormJSON form1 = TestDataBuilder.createSimpleForm(); Workflow workflow = TestDataBuilder.createWorkflow(form0, form1); String token = login(); String folder = createFolder(token, getDefaultEmail()); addFileToFolder(token, folder, workflow, form0, form1); // when login(getDefaultEmail()); getDriver().navigate().to(getDefaultHostAndPort() + "/user/dashboard"); waitForJSandJQueryToLoad(); assertEquals("FormKiQ Server - Dashboard", getTitle()); findElementBy(By.className("add_0")).click(); // then (verify on correct page) assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e1", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - Store Receipt", getTitle()); // when (enter data) WebElement element = findElementBy(By.name("1")); element.sendKeys("10"); findElementBy(By.id("nextbutton")).click(); // then verify summary assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e2", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - Simple Form", getTitle()); // when move to previous page findElementBy(By.id("previousbutton")).click(); // then verify summary assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e1", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - Store Receipt", getTitle()); } /** * testCreateWorkflow04(). * test all fields * @throws Exception Exception */ @Test public void testCreateWorkflow04() throws Exception { // given String sigtext = getResourceAsString("/signature.txt"); FormJSON form = TestDataBuilder.createAllFields(); Workflow workflow = TestDataBuilder.createWorkflow(form); String token = login(); String folder = createFolder(token, getDefaultEmail()); addFileToFolder(token, folder, workflow, form); clickCreateWorkflow(); // then (verify on correct page) assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e1", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - All Forms", getTitle()); // given // checkbox findElementByName("" + (findIndex(FormJSONFieldType.SWITCH))).click(); // date findElementByName("" + (findIndex(FormJSONFieldType.DATE))).sendKeys("2017/07/05"); // note findElementByName("" + (findIndex(FormJSONFieldType.NOTE))).sendKeys("This\nis\nthe\nsample\ntext\ndata."); // password findElementByName(FormJSONFieldType.PASSWORD.name()).sendKeys("pass"); // photo JavascriptExecutor js = (JavascriptExecutor) getDriver(); js.executeScript("document.getElementById(\"'All Forms'!" + (findIndex(FormJSONFieldType.PHOTO)) + "\").value = '" + sigtext + "'"); // selectbox selectByIndex("" + (findIndex(FormJSONFieldType.SELECTBOX)), 1); // signature fillSignature("" + (findIndex(FormJSONFieldType.SIGNATURE))); // initials findElementByName("" + (findIndex(FormJSONFieldType.SIGNATURE_INITIALS))).sendKeys("MF"); // input findElementByName(FormJSONFieldType.TEXTBOX.name()).sendKeys("Sample Input field"); // when submitByName("_eventId_next", "Next"); // then verify summary assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e2", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - Sample WF Complete", getTitle()); } /** * testCreateWorkflow05(). * test all fields required, Press Next verify page, * then change URL to event 2 * @throws Exception Exception */ @Test public void testCreateWorkflow05() throws Exception { // given FormJSON form = TestDataBuilder.createAllFields(); Workflow workflow = TestDataBuilder.createWorkflow(form); String token = login(); String folder = createFolder(token, getDefaultEmail()); addFileToFolder(token, folder, workflow, form); clickCreateWorkflow(); // then (verify on correct page) assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e1", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - All Forms", getTitle()); // when submitByName("_eventId_next", "Next"); // then (verify on correct page) assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e1", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - All Forms", getTitle()); // when getDriver().navigate().to(getDefaultHostAndPort() + "/flow/workflow?execution=s1e2"); // then (verify on correct page) assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e1", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - All Forms", getTitle()); } /** * testCreateWorkflow06(). * test idbarcode type , Press Next verify page, * @throws Exception Exception */ @Test public void testCreateWorkflow06() throws Exception { // given FormJSON form = TestDataBuilder.createIdBarcode(); Workflow workflow = TestDataBuilder.createWorkflow(form); String token = login(); String folder = createFolder(token, getDefaultEmail()); addFileToFolder(token, folder, workflow, form); clickCreateWorkflow(); // then (verify on correct page) assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e1", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - Sample WF Complete", getTitle()); } /** * testCreateWorkflow07(). * test invalid built in type, * @throws Exception Exception */ @Test public void testCreateWorkflow07() throws Exception { // given FormJSON form = TestDataBuilder.createIdBarcode(); form.setBuiltintype("FJKSDFDSF"); Workflow workflow = TestDataBuilder.createWorkflow(form); String token = login(); String folder = createFolder(token, getDefaultEmail()); addFileToFolder(token, folder, workflow, form); clickCreateWorkflow(); // then (verify on correct page) assertEquals(getDefaultHostAndPort() + "/flow/notsupported.html", getDriver().getCurrentUrl()); assertEquals("Workflow not Supported", getTitle()); String pageSource = getDriver().getPageSource(); assertTrue(pageSource.contains("Workflow is not supported")); } /** * TODO route testCreateWorkflow11 to email to signature. * testCreateWorkflow08(). * test Docsign workflow * @throws Exception Exception */ @Test @Ignore public void testCreateWorkflow08() throws Exception { //given FormJSON f0 = TestDataBuilder.createScheduleB(); FormJSON f1 = TestDataBuilder.createDocSign(); Workflow workflow = TestDataBuilder.createWorkflow(f0, f1); workflow.setPrintsteps(Arrays.asList(f0.getUUID())); String token = login(); String folder = createFolder(token, getDefaultEmail()); UserDTO user = getUserDTO(token, null); String userid = user.getUUID().toString(); addFileToFolder(token, folder, workflow, f0, f1); // when clickCreateWorkflow(); // then (verify on correct page) assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e1", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - Schedule B", getTitle()); assertEquals(f0.getSections().get(1).getFields().size(), getDriver().findElements(By.className("col-xs-12")).size()); assertEquals(2, getDriver().findElements(By.className("col-xs-6")).size()); // when fillScheduleB(); submitByName("_eventId_next", "Next"); // then assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e2", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - Submit for Signing", getTitle()); // when fillDocsign(); submitByName("_eventId_next", "Next"); // then assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e3", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - Sample WF Complete", getTitle()); // when (goto summary -> complete) submitByName("_eventId_next", " Submit for Signature"); // then String pageSource = getDriver().getPageSource(); assertTrue(pageSource.contains("The workflow has been saved.")); assertNotNull(findElementBy(By.id("pdfbutton"))); // verify email is sent for signing verifyFolderFileList(token, folder, workflow, "ROUTED", "Sample WF"); Pair<QueueDTO, DocSignQueueMessage> pair = verifyQueueMessage(token, userid, folder); String signUrl = verifyDocsignEmail(); assertEquals( "https://www.formkiq.com/flow/sign/" + pair.getRight().getFormid() + "/" + pair.getLeft().getUUID(), signUrl); logout(); // given signUrl = signUrl.replaceAll("https://www.formkiq.com", getDefaultHostAndPort()); // when (sign document) getDriver().navigate().to(signUrl); // then assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e1", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - Sample WF Summary", getTitle()); assertEquals(2, getDriver().findElements(By.className("col-xs-6")).size()); // when (submit missing signtures) submitByName("_eventId_next", " Sign Document"); // then assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e1", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - Sample WF Summary", getTitle()); assertEquals(2, getDriver().findElements(By.className("has-error")).stream().filter(s -> s.isDisplayed()) .collect(Collectors.toList()).size()); // when (add signature to document) fillSignature("7"); fillSignature("8"); JavascriptExecutor js = (JavascriptExecutor) getDriver(); js.executeScript("document.getElementById('latitude').value = '111'"); js.executeScript("document.getElementById('longitude').value = '222'"); submitByName("_eventId_next", " Sign Document"); // then final int stepCount = 3; Pair<Workflow, Map<String, byte[]>> pwf = verifyFolderFileList(token, folder, workflow, "ACTIVE", "Sample WF"); Workflow cworkflow = pwf.getLeft(); Map<String, byte[]> map = pwf.getRight(); verifyDocsignResult(map); assertNotEquals(workflow.getUUID(), cworkflow.getUUID()); int i = 0; assertEquals(stepCount, cworkflow.getSteps().size()); assertTrue(map.containsKey(cworkflow.getSteps().get(i++) + ".form")); assertTrue(map.containsKey(cworkflow.getSteps().get(i++) + ".form")); assertTrue(map.containsKey(cworkflow.getSteps().get(i++) + ".form")); assertEquals(2, map.keySet().stream().filter(s -> s.endsWith(".signature")).count()); assertEquals(cworkflow.getUUID() + ".pdf", map.keySet().stream().filter(s -> s.endsWith(".pdf")).collect(Collectors.joining(", "))); // verify token is deleted once signed. QueueListDTO msgs = getQueueMessages(token, userid); assertEquals(0, msgs.getMessages().size()); verifyCompleteEmail(); } /** * testCreateWorkflow09(). * test invalid signing use. * @throws Exception Exception */ @Test public void testCreateWorkflow09() throws Exception { //given String doc = UUID.randomUUID().toString(); String stoken = UUID.randomUUID().toString(); String signurl = getDefaultHostAndPort() + "/flow/sign/" + doc + "/" + stoken; // when (sign document) getDriver().navigate().to(signurl); // then assertEquals(getDefaultHostAndPort() + "/login", getDriver().getCurrentUrl()); } /** * testCreateWorkflow10(). * test Equifax workflow * @throws Exception Exception */ @Test public void testCreateWorkflow10() throws Exception { //given String resp = Resources.getResourceAsString("/equifax/response.txt"); this.equifaxService.setResponse(resp); MockHttpServletRequest request = new MockHttpServletRequest(); Workflow workflow = TestDataBuilder.createWorkflow(); ArchiveDTO archive = new ArchiveDTO(); archive.setWorkflow(workflow); WebFlow flow = new WebFlow(1, null, Collections.emptyList()); flow.setData(archive); this.workflowEditorService.eventIdaddstep(flow, request, new String[] { "equifaxcc" }); FormJSON equifaxForm = archive.getForms().values().iterator().next(); findValueByKey(equifaxForm, "membernumber").get().setValue("1234567890"); findValueByKey(equifaxForm, "securitycode").get().setValue("99"); findValueByKey(equifaxForm, "customercode").get().setValue("555"); workflow = TestDataBuilder.createWorkflow(equifaxForm); String token = login(); String folder = createFolder(token, getDefaultEmail()); addFileToFolder(token, folder, workflow, equifaxForm); // when clickCreateWorkflow(); // then (verify on correct page) assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e1", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - Equifax Credit Check", getTitle()); assertNoSuchElement(getBy("select", "data-fieldid", "30")); assertNoSuchElement(getBy("input", "data-fieldid", "40")); // when fillEquifaxForm(); submitByName("_eventId_next", "Next"); // then assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e2", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - Sample WF Complete", getTitle()); // TODO remove summary // when (goto summary -> complete) submitByName("_eventId_next", " Submit"); final int count = 3; Pair<Workflow, Map<String, byte[]>> pwf = verifyFolderFileList(token, folder, workflow, "ACTIVE", "Sample WF"); Map<String, byte[]> map = pwf.getRight(); assertEquals(count, map.size()); String key = map.keySet().stream().filter(s -> s.endsWith(".form")).findFirst().get(); FormJSON form = this.jsonService.readValue(map.get(key), FormJSON.class); assertNotNull(findValueByKey(form, "equifax_credit_check_id").get().getValue()); assertEquals("https://uat.equifax.ca/sts/processinquiry.asp", findValueByKey(form, "url").get().getValue()); assertNotNull(findValueByKey(form, "request").get().getValue()); assertNotNull(findValueByKey(form, "response").get().getValue()); assertNotNull(findValueByKey(form, "requesttype").get().getValue()); assertNotNull(findValueByKey(form, "inserteddate").get().getValue()); assertEquals(getDefaultEmail(), findValueByKey(form, "requester").get().getValue()); assertEquals("25,000", findValueByKey(form, "approvedamount").get().getValue()); } /** * testCreateWorkflow11(). * fillout and generate and sign fillable PDF * @throws Exception Exception */ @Test public void testCreateWorkflow11() throws Exception { // given String pdfname = "sample-form2.pdf"; byte[] data = Resources.getResourceAsBytes("/" + pdfname); ArchiveDTO archive = buildArchiveDTO(pdfname); this.pdfEditorService.generate(archive, pdfname, data); String token = login(); String folder = createFolder(token, getDefaultEmail()); addFileToFolder(token, folder, archive); // when login(getDefaultEmail()); getDriver().navigate().to(getDefaultHostAndPort() + "/user/dashboard"); waitForJSandJQueryToLoad(); assertEquals("FormKiQ Server - Dashboard", getTitle()); findElementBy(By.className("add_0")).click(); // then (verify on correct page) assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e1", getDriver().getCurrentUrl()); assertEquals(SAMPLE_FORM_2_HTML_TITLE, getTitle()); fillSampleForm2(); // when (submit) submitByName("_eventId_next", "Next"); // then verify summary assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e2", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - Signature", getTitle()); assertEquals(1, findElements(getBy("button", "data-fieldid", "55")).size()); assertEquals(0, getDriver().findElements(getBy("img", "data-fieldid", "55")).size()); // when (go back submitByName("_eventId_prev", "Previous"); // then assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e1", getDriver().getCurrentUrl()); assertEquals(SAMPLE_FORM_2_HTML_TITLE, getTitle()); // when findElementBy(By.name("1")).sendKeys("Smith123"); submitByName("_eventId_next", "Next"); // then assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e2", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - Signature", getTitle()); // when (signature) click(By.className("button-sig")); JavascriptExecutor jsExecutor = (JavascriptExecutor) getDriver(); jsExecutor.executeScript("signaturemetadata('555','999');"); // then getWait().until(ExpectedConditions.visibilityOfElementLocated(By.id("form-modal"))); // when click(By.className("form-modal-close-button")); // then getWait().until(ExpectedConditions.invisibilityOfElementLocated(By.id("form-modal"))); // when (signature) click(By.className("button-sig")); // then fillSignature("55"); // when click(By.className("form-modal-update-button")); // then getWait().until(ExpectedConditions.invisibilityOfElementLocated(By.id("form-modal"))); assertEquals(0, getDriver().findElements(getBy("button", "data-fieldid", "55")).size()); assertEquals(1, findElements(getBy("img", "data-fieldid", "55")).size()); // when submitByName("_eventId_next", " Submit", TIMEOUT * 2); // then complete page assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e3", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - sample-form2.pdf Complete", getTitle()); Workflow workflow = archive.getWorkflow(); Pair<Workflow, Map<String, byte[]>> pwf = verifyFolderFileList(token, folder, workflow, "ACTIVE", "sample-form2.pdf"); workflow = pwf.getLeft(); Map<String, byte[]> map = pwf.getRight(); assertEquals(getDefaultHostAndPort() + "/api/folders/files/" + folder + "/" + workflow.getUUID() + ".pdf", findElementBy(By.id("pdflink")).getAttribute("href")); assertEquals(SAMPLE_FORM2 + ".pdf", map.keySet().stream().filter(s -> s.endsWith(".pdf")).collect(Collectors.joining(", "))); assertEquals(1, map.keySet().stream().filter(s -> s.endsWith(".pdf")).count()); assertEquals(1, map.keySet().stream().filter(s -> s.endsWith(".signature")).count()); FormJSON f1 = this.jsonService.readValue(map.get(workflow.getSteps().get(1) + ".form"), FormJSON.class); assertTrue(f1.getAssetData().containsKey(f1.getSections().get(0).getFields().get(0).getValue())); assertEquals("555", findValueByKey(f1, "latitude").get().getValue()); assertEquals("999", findValueByKey(f1, "longitude").get().getValue()); assertEquals("0:0:0:0:0:0:0:1", findValueByKey(f1, "ipaddress").get().getValue()); assertEquals("", findValueByKey(f1, "xforwardedfor").get().getValue()); assertNotNull(this.jsonService.stringToDate(findValueByKey(f1, "inserteddate").get().getValue())); byte[] pdf = map.get(SAMPLE_FORM2 + ".pdf"); PDDocument document = PDDocument.load(pdf); try { PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm(); assertEquals("SmithSmith123", acroForm.getField("lastName").getValueAsString()); assertEquals("John", acroForm.getField("firstName").getValueAsString()); assertEquals(1, document.getSignatureDictionaries().size()); } finally { document.close(); } // TODO verify audit } /** * fill sample-form2.pdf. */ private void fillSampleForm2() { int i = 1; // when - fill out Member information i = fillMemberInformation(i); // Coordination of benefits i = fillCorrdinationOfBenefits(i); // Spouse / Dependent Children Expenses i = fillSpouseDependentExpenses(i); // Information about your claim i = fillClaimInformation(i); // Authorization and signature i = fillAuthorizationAndSignatures(i); } /** * testCreateWorkflow11. * @param j int * @return int */ private int fillAuthorizationAndSignatures(final int j) { int i = j; i++; findElementBy(By.name("" + i++)).sendKeys("2018"); findElementBy(By.name("" + i++)).sendKeys("01"); findElementBy(By.name("" + i++)).sendKeys("30"); return i; } /** * testCreateWorkflow11. * @param j int * @return int */ private int fillClaimInformation(final int j) { int i = j; findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Yes'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i++ + "!'No'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Yes'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i++ + "!'No'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Yes'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i++ + "!'No'")).click(); findElementBy(By.name("" + i++)).sendKeys("2018"); findElementBy(By.name("" + i++)).sendKeys("12"); findElementBy(By.name("" + i++)).sendKeys("28"); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Yes'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i++ + "!'No'")).click(); findElementBy(By.name("" + i++)).sendKeys("1015"); // submitted return i; } /** * testCreateWorkflow11. * @param j int * @return int */ private int fillSpouseDependentExpenses(final int j) { int i = j; findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Spouse'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Son'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Daughter'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i++ + "!'Other'")).click(); findElementBy(By.name("" + i++)).sendKeys("Jack"); findElementBy(By.name("" + i++)).sendKeys("Smith"); findElementBy(By.name("" + i++)).sendKeys("2010"); // birthdate 1 findElementBy(By.name("" + i++)).sendKeys("03"); // birthdate 2 findElementBy(By.name("" + i++)).sendKeys("22"); // birthdate 3 findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Spouse'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Son'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Daughter'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i++ + "!'Other'")).click(); findElementBy(By.name("" + i++)).sendKeys("Jane"); // Spouse first findElementBy(By.name("" + i++)).sendKeys("Smith"); // Spouse last findElementBy(By.name("" + i++)).sendKeys("1969"); // birthdate 1 findElementBy(By.name("" + i++)).sendKeys("05"); // birthdate 2 findElementBy(By.name("" + i++)).sendKeys("27"); // birthdate 3 findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Spouse'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Son'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Daughter'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i++ + "!'Other'")).click(); findElementBy(By.name("" + i++)).sendKeys("Suze"); // Spouse first findElementBy(By.name("" + i++)).sendKeys("Smith"); // Spouse last findElementBy(By.name("" + i++)).sendKeys("2012"); // birthdate 1 findElementBy(By.name("" + i++)).sendKeys("06"); // birthdate 2 findElementBy(By.name("" + i++)).sendKeys("28"); // birthdate 3 findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Spouse'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Son'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Daughter'")).click(); findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i++ + "!'Other'")).click(); findElementBy(By.name("" + i++)).sendKeys("Frank"); // Spouse first findElementBy(By.name("" + i++)).sendKeys("Smith"); // Spouse last findElementBy(By.name("" + i++)).sendKeys("2014"); // birthdate 1 findElementBy(By.name("" + i++)).sendKeys("07"); // birthdate 2 findElementBy(By.name("" + i++)).sendKeys("30"); // birthdate 3 return i; } /** * testCreateWorkflow11. * @param j int * @return int */ private int fillCorrdinationOfBenefits(final int j) { int i = j; findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'No'")).click(); // Spouse Another plan findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i++ + "!'Yes'")).click(); // Spouse Another plan findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'No'")).click(); // Spouse Another plan findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i++ + "!'Yes'")).click(); // Spouse Another plan findElementBy(By.name("" + i++)).sendKeys("Smith"); // Spouse diff plan findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Male'")).click(); // Gender findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i++ + "!'female'")).click(); // Gender findElementBy(By.name("" + i++)).sendKeys("5551234"); // Spouse Contract findElementBy(By.name("" + i++)).sendKeys("55554321"); // Spouse Cert No return i; } /** * testCreateWorkflow11. * @param j int * @return int */ private int fillMemberInformation(final int j) { int i = j; findElementBy(By.name("" + i++)).sendKeys("Smith"); // last name findElementBy(By.name("" + i++)).sendKeys("John"); // first name findElementBy(By.name("" + i++)).sendKeys("John"); // certificate findElementBy(By.name("" + i++)).sendKeys("555"); // phone number 1 findElementBy(By.name("" + i++)).sendKeys("555"); // phone number 2 findElementBy(By.name("" + i++)).sendKeys("1212"); // phone number 3 findElementBy(By.name("" + i++)).sendKeys("2000"); // birthdate 1 findElementBy(By.name("" + i++)).sendKeys("01"); // birthdate 2 findElementBy(By.name("" + i++)).sendKeys("19"); // birthdate 3 findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Eng'")).click(); // Language Required findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i++ + "!'Fr'")).click(); // Language Required findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i + "!'Male'")).click(); // Gender findElementBy(By.id("'Public Service Health Care Plan (PSHCP) Claim Form'!" + i++ + "!'Female'")).click(); // Gender findElementBy(By.name("" + i++)).sendKeys("123 Main"); // Street findElementBy(By.name("" + i++)).sendKeys("708"); // Apartment findElementBy(By.name("" + i++)).sendKeys("New York"); // City findElementBy(By.name("" + i++)).sendKeys("NY"); // Province findElementBy(By.name("" + i++)).sendKeys("90210"); // Postal Code return i; } /** * testCreateWorkflow12(). * test selecting checkbox and refreshing page to make sure it * is still selected * @throws Exception Exception */ @Test public void testCreateWorkflow12() throws Exception { // given FormJSON form = TestDataBuilder.createAllFields(); Workflow workflow = TestDataBuilder.createWorkflow(form); String token = login(); String folder = createFolder(token, getDefaultEmail()); addFileToFolder(token, folder, workflow, form); clickCreateWorkflow(); // then (verify on correct page) assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e1", getDriver().getCurrentUrl()); assertEquals("FormKiQ Server - All Forms", getTitle()); // given // checkbox findElementByName("" + (findIndex(FormJSONFieldType.SWITCH))).click(); // when submitByName("_eventId_next", "Next"); // then verify summary assertEquals(getDefaultHostAndPort() + "/flow/workflow?execution=s1e1", getDriver().getCurrentUrl()); assertTrue(findElementByName("" + (findIndex(FormJSONFieldType.SWITCH))).isSelected()); } /** * fill equifax form. */ private void fillEquifaxForm() { findElementBy("input", "data-valuekey", "suffix").sendKeys("mr"); findElementBy("input", "data-valuekey", "firstname").sendKeys("mr"); findElementBy("input", "data-valuekey", "familyname").sendKeys("mr"); findElementBy("input", "data-valuekey", "birthdate").sendKeys("2017-01-01T12:12:12-0600"); findElementBy("input", "data-valuekey", "homephonenumber").sendKeys("555-555-5555"); findElementBy("input", "data-valuekey", "streetno0").sendKeys("123"); findElementBy("input", "data-valuekey", "streetname0").sendKeys("main"); findElementBy("input", "data-valuekey", "city0").sendKeys("test"); findElementBy("input", "data-valuekey", "province0").sendKeys("mb"); findElementBy("input", "data-valuekey", "postalcode0").sendKeys("90210"); } /** * Verify Completion Email. * @throws IOException IOException * @throws MessagingException MessagingException */ private void verifyCompleteEmail() throws IOException, MessagingException { assertEquals(0, getMailSender().getMessages().size()); assertEquals(1, getMailSender().getMimeMessages().size()); MimeMessage msg = getMailSender().getMimeMessages().get(0); assertEquals("Completed signing Sample WF", msg.getSubject()); assertEquals("test@formkiq.com", msg.getAllRecipients()[0].toString()); Multipart multipart = (Multipart) msg.getContent(); assertEquals(1, multipart.getCount()); ByteArrayOutputStream out = new ByteArrayOutputStream(); msg.writeTo(out); String s = out.toString(CHARSET_UTF8.name()); assertFalse(s.contains("${sendername}")); assertFalse(s.contains("${signername}")); assertFalse(s.contains("${doc}")); assertFalse(s.contains("${stoken}")); assertTrue(s.contains("has reviewed and signed the document")); out.close(); } /** * verify email is sent for signing. * @return {@link String} The signing URL. * @throws IOException IOException * @throws MessagingException MessagingException */ private String verifyDocsignEmail() throws IOException, MessagingException { assertEquals(0, getMailSender().getMessages().size()); assertEquals(1, getMailSender().getMimeMessages().size()); MimeMessage msg = getMailSender().getMimeMessages().get(0); assertTrue(msg.getSubject().endsWith("sign this")); assertTrue(msg.getAllRecipients()[0].toString().endsWith("jacksmith@formkiq.com")); Multipart multipart = (Multipart) msg.getContent(); assertEquals(1, multipart.getCount()); ByteArrayOutputStream out = new ByteArrayOutputStream(); msg.writeTo(out); String s = out.toString(CHARSET_UTF8.name()); assertTrue(s.contains("John Smith")); assertTrue(s.contains("Jack Smith")); assertFalse(s.contains("${sendername}")); assertFalse(s.contains("${signername}")); assertFalse(s.contains("${doc}")); assertFalse(s.contains("${stoken}")); assertTrue(s.contains("Please review the document and sign at the link above")); out.close(); getMailSender().reset(); return findHrefUrl(s); } /** * Verify the Docsign Result. * @param map {@link Map} * @throws IOException IOException * @throws ParseException ParseException */ private void verifyDocsignResult(final Map<String, byte[]> map) throws IOException, ParseException { final int numberOfSteps = 3; final int numberOfFields = 5; String workflowname = map.entrySet().stream().filter(e -> e.getKey().endsWith(".workflow")).findFirst() .get().getKey(); String s = Strings.toString(map.get(workflowname)); Workflow w = this.jsonService.readValue(s, Workflow.class); assertEquals(numberOfSteps, w.getSteps().size()); String step = w.getSteps().get(w.getSteps().size() - 1); byte[] formdata = map.get(step + ".form"); FormJSON r = this.jsonService.readValue(Strings.toString(formdata), FormJSON.class); assertEquals(w.getParentUUID(), r.getParentUUID()); assertEquals("docsignresult", r.getBuiltintype()); assertEquals(1, r.getSections().size()); FormJSONSection section = r.getSections().get(0); assertEquals(numberOfFields, section.getFields().size()); FormJSONField f0 = section.getFields().get(0); assertEquals(1, f0.getId()); assertEquals("Inserted Date", f0.getLabel()); assertEquals(FormJSONFieldType.TEXTBOX, f0.getType()); assertNotNull(this.jsonDateFormat.parse(f0.getValue())); int i = 1; assertField(section.getFields().get(i), ++i, "IP Address", FormJSONFieldType.TEXTBOX, "0:0:0:0:0:0:0:1"); assertField(section.getFields().get(i), ++i, "X-FORWARDED-FOR", FormJSONFieldType.TEXTBOX, ""); assertField(section.getFields().get(i), ++i, "Latitude", FormJSONFieldType.TEXTBOX, "111"); assertField(section.getFields().get(i), ++i, "Longitude", FormJSONFieldType.TEXTBOX, "222"); } /** * Verify Folder File List for testSign01(). * @param token {@link String} * @param folder {@link String} * @param workflow {@link Workflow} * @param status {@link String} * @param name {@link String} * * @throws IOException IOException * @return {@link Pair} */ private Pair<Workflow, Map<String, byte[]>> verifyFolderFileList(final String token, final String folder, final Workflow workflow, final String status, final String name) throws IOException { FolderFormsListDTO dto = getFolderFileList(token, folder, workflow.getUUID()); assertEquals(1, dto.getForms().size()); assertEquals(name, dto.getForms().get(0).getName()); assertEquals("WORKFLOW", dto.getForms().get(0).getType()); assertEquals(status, dto.getForms().get(0).getStatus()); String workflowUUID = dto.getForms().get(0).getUUID(); byte[] body = getFolderFile(token, folder, workflowUUID, MediaType.valueOf(ACCEPT_HEADER_V1 + "+zip"), false).getBody(); Map<String, byte[]> map = Zips.extractZipToMap(body); String workflowKey = workflowUUID + ".workflow"; Workflow wf = this.jsonService.readValue(map.get(workflowKey), Workflow.class); return Pair.of(wf, map); } /** * Verify Queue Messages for testSign01(). * @param token {@link String} * @param userid {@link String} * @param folder {@link String} * @return {@link Pair} * @throws Exception Exception */ private Pair<QueueDTO, DocSignQueueMessage> verifyQueueMessage(final String token, final String userid, final String folder) throws Exception { QueueListDTO msgs = getQueueMessages(token, userid); assertEquals(1, msgs.getMessages().size()); QueueDTO queueDTO = msgs.getMessages().get(0); assertNotNull(queueDTO.getUUID()); DocSignQueueMessage dmsg = this.jsonService.readValue(queueDTO.getMessage(), DocSignQueueMessage.class); assertEquals(folder, dmsg.getFolderid()); assertNotNull(dmsg.getAssetid()); assertNotNull(dmsg.getFormid()); assertNotNull(dmsg.getUserid()); assertTrue(dmsg.getSigner1email().endsWith("jacksmith@formkiq.com")); assertTrue(dmsg.getSigner1name().endsWith("Jack Smith")); assertEquals(userid, dmsg.getUserid()); return Pair.of(queueDTO, dmsg); } // TODO backbutton... }