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    
017    package edu.samplu.admin.test;
018    
019    
020    
021    import java.net.URL;
022    import java.net.URLEncoder;
023    import java.util.Arrays;
024    import java.util.HashMap;
025    import java.util.Iterator;
026    import java.util.List;
027    import java.util.Map;
028    
029    import com.thoughtworks.selenium.DefaultSelenium;
030    import com.thoughtworks.selenium.Selenium;
031    import org.apache.commons.lang.StringUtils;
032    import org.junit.After;
033    import org.junit.Before;
034    import org.junit.Ignore;
035    import org.junit.Test;
036    import org.kuali.rice.kew.docsearch.DocumentSearchCriteriaProcessorKEWAdapter;
037    import org.kuali.rice.kew.impl.document.search.DocumentSearchCriteriaBoLookupableHelperService;
038    import org.kuali.rice.kew.util.Utilities;
039    
040    import com.gargoylesoftware.htmlunit.ElementNotFoundException;
041    import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
042    import com.gargoylesoftware.htmlunit.html.HtmlInput;
043    import com.gargoylesoftware.htmlunit.html.HtmlPage;
044    import org.kuali.rice.krad.util.KRADConstants;
045    import org.openqa.selenium.By;
046    import org.openqa.selenium.NoSuchElementException;
047    import org.openqa.selenium.WebDriver;
048    import org.openqa.selenium.WebDriverBackedSelenium;
049    import org.openqa.selenium.WebElement;
050    import org.openqa.selenium.firefox.FirefoxDriver;
051    import org.openqa.selenium.remote.DesiredCapabilities;
052    import org.openqa.selenium.remote.RemoteWebDriver;
053    
054    import static org.junit.Assert.*;
055    import static org.junit.Assert.assertEquals;
056    
057    /**
058     * Tests docsearch url parameters
059     */
060    @Ignore
061    public 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((DocumentSearchCriteriaProcessorKEWAdapter.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    }