001/*
002 * Copyright 2006-2012 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package edu.samplu.admin.test;
018
019
020
021import java.net.URL;
022import java.net.URLEncoder;
023import java.util.Arrays;
024import java.util.HashMap;
025import java.util.Iterator;
026import java.util.List;
027import java.util.Map;
028
029import com.thoughtworks.selenium.DefaultSelenium;
030import com.thoughtworks.selenium.Selenium;
031import org.apache.commons.lang.StringUtils;
032import org.junit.After;
033import org.junit.Before;
034import org.junit.Ignore;
035import org.junit.Test;
036import org.kuali.rice.kew.docsearch.DocumentSearchCriteriaProcessorKEWAdapter;
037import org.kuali.rice.kew.impl.document.search.DocumentSearchCriteriaBoLookupableHelperService;
038import org.kuali.rice.kew.util.Utilities;
039
040import com.gargoylesoftware.htmlunit.ElementNotFoundException;
041import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
042import com.gargoylesoftware.htmlunit.html.HtmlInput;
043import com.gargoylesoftware.htmlunit.html.HtmlPage;
044import org.kuali.rice.krad.util.KRADConstants;
045import org.openqa.selenium.By;
046import org.openqa.selenium.NoSuchElementException;
047import org.openqa.selenium.WebDriver;
048import org.openqa.selenium.WebDriverBackedSelenium;
049import org.openqa.selenium.WebElement;
050import org.openqa.selenium.firefox.FirefoxDriver;
051import org.openqa.selenium.remote.DesiredCapabilities;
052import org.openqa.selenium.remote.RemoteWebDriver;
053
054import static org.junit.Assert.*;
055import static org.junit.Assert.assertEquals;
056
057/**
058 * Tests docsearch url parameters
059 */
060@Ignore
061public class DocumentSearchURLParametersIT {
062    private static final String ADMIN_USER_NETWORK_ID = "admin";
063
064    private WebDriver driver;
065    private String base;
066
067    private static final String DOCUMENT_TYPE_NAME = "KualiNotification";
068    private static final String ADVANCED_SEARCH_ONLY_FIELD = "applicationDocumentId";
069
070    private static final Map<String, String> CORE_FIELDS = new HashMap<String, String>();
071    static {
072        // basic
073        CORE_FIELDS.put("documentTypeName", DOCUMENT_TYPE_NAME);
074        CORE_FIELDS.put("documentId", "1234");
075        CORE_FIELDS.put("initiatorPrincipalName", "CURRENT_USER");
076        CORE_FIELDS.put("dateCreated", "11/11/11");
077
078    }
079    private static final Map<String, String> BASIC_FIELDS = new HashMap<String, String>();
080    static {
081        BASIC_FIELDS.putAll(CORE_FIELDS);
082        // searchable attrs
083        BASIC_FIELDS.put("documentAttribute.notificationContentType", "testType");
084        BASIC_FIELDS.put("documentAttribute.notificationChannel", "testChannel");
085        BASIC_FIELDS.put("documentAttribute.notificationProducer", "testProducer");
086        BASIC_FIELDS.put("documentAttribute.notificationPriority", "testPriority");
087        BASIC_FIELDS.put("documentAttribute.notificationRecipients", "testRecipients");
088        BASIC_FIELDS.put("documentAttribute.notificationSenders", "testSenders");
089        BASIC_FIELDS.put("saveName", "testBasicSearchFields_saved_search");
090        BASIC_FIELDS.put("isAdvancedSearch", "NO");
091    }
092
093    private static final Map<String, String> ADVANCED_FIELDS = new HashMap<String, String>();
094    static {
095        ADVANCED_FIELDS.put("approverPrincipalName", "testApproverName");
096        ADVANCED_FIELDS.put("viewerPrincipalName", "testViewerName");
097        ADVANCED_FIELDS.put("applicationDocumentId", "testApplicationDocumentId");
098        // ADVANCED_FIELDS.put("routeNodeName", "Adhoc Routing");
099        ADVANCED_FIELDS.put("dateApproved", "01/01/01");
100        ADVANCED_FIELDS.put("dateLastModified", "02/02/02");
101        ADVANCED_FIELDS.put("dateFinalized", "03/03/03");
102        ADVANCED_FIELDS.put("title", "test title");
103        ADVANCED_FIELDS.put("isAdvancedSearch", "YES");
104    }
105
106    @Before
107    public void setUp() throws Exception {
108        driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), DesiredCapabilities.firefox());
109        // default to locally running dev sampleapp
110        base = StringUtils.defaultIfEmpty(System.getProperty("remote.public.url"), "http://localhost:8080/kr-dev");
111    }
112
113    @After
114    public void tearDown() throws Exception {
115        driver.quit();
116    }
117
118    private void performLogin() {
119        driver.get(base);
120        assertEquals("Login", driver.getTitle());
121        driver.findElement(By.name("__login_user")).sendKeys(ADMIN_USER_NETWORK_ID);
122        driver.findElement(By.xpath("//input[@value='Login']")).click();
123    }
124
125    private String getDocSearchURL(Map<String, String> params) {
126        StringBuilder sb = new StringBuilder();
127        for (Map.Entry<String, String> entry: params.entrySet()) {
128            sb.append(URLEncoder.encode(entry.getKey()) + "=" + URLEncoder.encode(entry.getValue()) + "&");
129        }
130        return getDocSearchURL(sb.toString());
131        
132    }
133    private String getDocSearchURL(String params) {
134        return base + "/kew/DocumentSearch.do?" + params;
135    }
136    
137    private WebElement findElementByTagAndName(String tag, String name) {
138        return driver.findElement(By.xpath("//" + tag + "[@name='" + name + "']"));
139    }
140    
141    private WebElement findInput(String name) {
142        return findElementByTagAndName("input", name);
143    }
144    
145    private WebElement findModeToggleButton() {
146        WebElement toggleAdvancedSearch = null;
147        try {
148            return driver.findElement(By.id("toggleAdvancedSearch"));
149        } catch (NoSuchElementException e) {
150            fail("toggleAdvancedSearch button not found");
151            return null;
152        }
153    }
154
155    private void assertSearchDetailMode(WebElement e, boolean advanced) {
156        assertEquals((advanced ? "basic" : "detailed") + " search", e.getAttribute("title"));
157
158        try {
159            findInput(ADVANCED_SEARCH_ONLY_FIELD);
160            if (!advanced) fail("Advanced search field found in basic search");
161        } catch (NoSuchElementException nsee) {
162            if (advanced) fail("Advanced search field not found in advancedsearch");
163        }
164    }
165
166    @Test
167    public void testBasicSearchMode() throws InterruptedException{
168        performLogin();
169        driver.get(getDocSearchURL(""));
170        WebElement toggle = findModeToggleButton();
171        assertSearchDetailMode(toggle, false);
172        toggle.click();
173        assertSearchDetailMode(findModeToggleButton(), true);
174    }
175
176    @Test
177    public void testAdvancedSearchMode() {
178        performLogin();
179        driver.get(getDocSearchURL((KRADConstants.ADVANCED_SEARCH_FIELD + "=YES")));
180        WebElement toggle = findModeToggleButton();
181        assertSearchDetailMode(toggle, true);
182        toggle.click();
183        assertSearchDetailMode(findModeToggleButton(), false);
184    }
185
186    @Test
187    public void testHeaderBarDisabled() throws InterruptedException{
188        performLogin();
189
190        driver.get(getDocSearchURL("headerBarEnabled=false"));
191        assertTrue(driver.findElements(By.id("headerarea-small")).isEmpty());
192        assertInputPresence(CORE_FIELDS, true);
193        driver.get(getDocSearchURL("headerBarEnabled=true"));
194        assertFalse(driver.findElements(By.id("headerarea-small")).isEmpty());
195        assertInputPresence(CORE_FIELDS, true);
196    }
197
198    @Test
199    public void testCriteriaDisabled() throws InterruptedException{
200        performLogin();
201        driver.get(getDocSearchURL("searchCriteriaEnabled=NO"));
202        assertInputPresence(CORE_FIELDS, false);
203        driver.get(getDocSearchURL("searchCriteriaEnabled=true"));
204        assertInputPresence(CORE_FIELDS, true);
205    }
206
207    @Test
208    public void testBasicSearchFields() throws InterruptedException{
209        performLogin();
210
211        // criteria.initiator=delyea&criteria.docTypeFullName=" + documentTypeName +
212        driver.get(getDocSearchURL(BASIC_FIELDS));
213
214        assertInputValues(BASIC_FIELDS);
215
216        driver.findElement(By.id("toggleAdvancedSearch")).click();
217
218        Map<String, String> expected = new HashMap<String, String>(BASIC_FIELDS);
219        for (Map.Entry<String, String> entry: ADVANCED_FIELDS.entrySet()) {
220            if (!"isAdvancedSearch".equals(entry.getKey())) {
221                expected.put(entry.getKey(), "");
222            } else {
223                expected.put(entry.getKey(), entry.getValue());
224            }
225        }
226        assertInputValues(expected);
227    }
228
229    @Test
230    public void testBasicSearchFieldsAndExecuteSearch() throws InterruptedException {
231        performLogin();
232
233        // criteria.initiator=delyea&criteria.docTypeFullName=" + documentTypeName +
234        Map<String, String> fields = new HashMap<String, String>();
235        fields.putAll(BASIC_FIELDS);
236        fields.put("methodToCall", "search");
237        driver.get(getDocSearchURL(fields));
238
239        assertInputValues(BASIC_FIELDS);
240
241        // verify that it attempted the search
242        assertTrue(driver.getPageSource().contains("No values match this search"));
243
244        driver.findElement(By.id("toggleAdvancedSearch")).click();
245
246        Map<String, String> expected = new HashMap<String, String>(BASIC_FIELDS);
247        for (Map.Entry<String, String> entry: ADVANCED_FIELDS.entrySet()) {
248            if (!"isAdvancedSearch".equals(entry.getKey())) {
249                expected.put(entry.getKey(), "");
250            } else {
251                expected.put(entry.getKey(), entry.getValue());
252            }
253        }
254        assertInputValues(expected);
255
256        // I guess switching modes doesn't re-execute the search
257        // assertTrue(driver.getPageSource().contains("No values match this search"));
258    }
259
260    @Test
261    public void testBasicSearchFieldsAndExecuteSearchWithHiddenCriteria() throws InterruptedException {
262        performLogin();
263
264        // criteria.initiator=delyea&criteria.docTypeFullName=" + documentTypeName +
265        Map<String, String> fields = new HashMap<String, String>();
266        fields.putAll(BASIC_FIELDS);
267        fields.put("methodToCall", "search");
268        fields.put("searchCriteriaEnabled", "NO");
269        driver.get(getDocSearchURL(fields));
270
271        assertInputPresence(BASIC_FIELDS, false);
272
273        // verify that it attempted the search
274        assertTrue(driver.getPageSource().contains("No values match this search"));
275
276        // NOTE: toggling modes re-enables the search criteria
277    }
278
279    @Test
280    public void testAdvancedSearchFields() throws InterruptedException{
281        performLogin();
282
283        // criteria.initiator=delyea&criteria.docTypeFullName=" + documentTypeName +
284        Map<String, String> values = new HashMap<String, String>(BASIC_FIELDS);
285        values.putAll(ADVANCED_FIELDS);
286        driver.get(getDocSearchURL(values));
287
288        assertInputValues(values);
289
290        driver.findElement(By.id("toggleAdvancedSearch")).click();
291
292        assertInputValues(BASIC_FIELDS);
293    }
294
295    @Test
296    public void testAdvancedSearchFieldsAndExecuteSearch() throws InterruptedException{
297        performLogin();
298
299        // criteria.initiator=delyea&criteria.docTypeFullName=" + documentTypeName +
300        Map<String, String> expected = new HashMap<String, String>(BASIC_FIELDS);
301        expected.putAll(ADVANCED_FIELDS);
302        
303        Map<String, String> values = new HashMap<String, String>(expected);
304        values.put("methodToCall", "search");
305        driver.get(getDocSearchURL(values));
306
307        assertInputValues(expected);
308
309        // verify that it attempted the search
310        assertTrue(driver.getPageSource().contains("No values match this search"));
311
312        driver.findElement(By.id("toggleAdvancedSearch")).click();
313
314        assertInputValues(BASIC_FIELDS);
315    }
316
317    @Test
318    public void testAdvancedSearchFieldsAndExecuteSearchWithHiddenCriteria() throws InterruptedException {
319        performLogin();
320
321        // criteria.initiator=delyea&criteria.docTypeFullName=" + documentTypeName +
322        Map<String, String> expected = new HashMap<String, String>(BASIC_FIELDS);
323        expected.putAll(ADVANCED_FIELDS);
324
325        Map<String, String> values = new HashMap<String, String>(expected);
326        values.put("methodToCall", "search");
327        values.put("searchCriteriaEnabled", "NO");
328        driver.get(getDocSearchURL(values));
329
330        assertInputPresence(expected, false);
331
332        // verify that it attempted the search
333        assertTrue(driver.getPageSource().contains("No values match this search"));
334
335        // NOTE: toggling modes re-enables the search criteria
336    }
337
338    /**
339     * Supplying a saveName does not result in the saved search getting loaded.
340     * @throws InterruptedException
341     */
342    @Test
343    public void testSupplyingSavedSearchNameDoesNothing() throws InterruptedException {
344        performLogin();
345
346        // get the search saved
347        driver.get(getDocSearchURL(BASIC_FIELDS));
348
349        driver.get(getDocSearchURL("saveName=testBasicSearchFields_saved_search"));
350        
351        Map<String, String> emptyForm = new HashMap<String, String>();
352        for (String key: CORE_FIELDS.keySet()) {
353            emptyForm.put(key, "");
354        }
355
356        assertInputValues(emptyForm);
357    }
358    
359    private void assertInputValues(Map<String, String> fields) {
360        for (Map.Entry<String, String> entry: fields.entrySet()) {
361            String value = findInput(entry.getKey()).getAttribute("value");
362            assertEquals("Field '" + entry.getKey() + "' expected '" + entry.getValue() + "' got '" + value + "'", entry.getValue(), value);
363        }
364    }
365
366    private void assertInputPresence(Map<String, String> fields, boolean present) {
367        for (String name: fields.keySet()) {
368            if (present) {
369                assertTrue("Expected field '" + name + "' to be present", driver.findElements(By.name(name)).size() != 0);
370            } else {
371                assertEquals("Expected field '" + name + "' not to be present", 0, driver.findElements(By.name(name)).size());
372            }
373        }
374    }
375}