001 // Copyright 2004, 2005 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.tapestry.engine; 016 017 import org.apache.hivemind.ApplicationRuntimeException; 018 import org.apache.hivemind.Location; 019 import org.apache.tapestry.*; 020 import org.apache.tapestry.event.BrowserEvent; 021 import org.apache.tapestry.services.LinkFactory; 022 import org.apache.tapestry.services.ResponseRenderer; 023 import org.apache.tapestry.services.ServiceConstants; 024 import org.apache.tapestry.web.WebRequest; 025 import org.apache.tapestry.web.WebSession; 026 import static org.easymock.EasyMock.*; 027 import org.testng.annotations.Test; 028 029 import java.util.Collections; 030 import java.util.HashMap; 031 import java.util.Map; 032 033 /** 034 * Tests for {@link org.apache.tapestry.engine.DirectService}. 035 */ 036 @Test 037 public class DirectServiceTest extends ServiceTestCase 038 { 039 protected IDirect newDirect(boolean checkParameters) 040 { 041 IDirect c = newMock(IDirect.class); 042 043 if (checkParameters) { 044 checkOrder(c, false); 045 046 expect(c.getUpdateComponents()).andReturn(Collections.EMPTY_LIST); 047 expect(c.isJson()).andReturn(false); 048 expect(c.isAsync()).andReturn(false); 049 expect(c.isStateful()).andReturn(true); 050 } 051 052 return c; 053 } 054 055 public void test_Get_Link_On_Same_Page() 056 { 057 IPage page = newPage("ThePage"); 058 IDirect c = newDirect(true); 059 IRequestCycle cycle = newCycle(); 060 WebRequest request = newWebRequest(false, null); 061 LinkFactory lf = newLinkFactory(); 062 ILink link = newLink(); 063 064 trainGetPage(cycle, page); 065 trainGetPage(c, page); 066 trainGetIdPath(c, "fred.barney"); 067 068 Object[] serviceParameters = new Object[0]; 069 070 Map parameters = new HashMap(); 071 072 parameters.put(ServiceConstants.PAGE, "ThePage"); 073 parameters.put(ServiceConstants.COMPONENT, "fred.barney"); 074 parameters.put(ServiceConstants.CONTAINER, null); 075 parameters.put(ServiceConstants.SESSION, null); 076 parameters.put(ServiceConstants.PARAMETER, serviceParameters); 077 078 DirectService ds = new DirectService(); 079 080 ds.setLinkFactory(lf); 081 ds.setRequest(request); 082 ds.setRequestCycle(cycle); 083 084 trainConstructLink(lf, ds, false, parameters, true, link); 085 086 replay(); 087 088 assertSame(link, ds.getLink(false, new DirectServiceParameter(c, serviceParameters))); 089 090 verify(); 091 } 092 093 public void test_Get_Link_On_Same_Page_For_Post() 094 { 095 IPage page = newPage("ThePage"); 096 IDirect c = newDirect(true); 097 IRequestCycle cycle = newCycle(); 098 WebRequest request = newWebRequest(false, null); 099 LinkFactory lf = newLinkFactory(); 100 ILink link = newLink(); 101 102 trainGetPage(cycle, page); 103 trainGetPage(c, page); 104 trainGetIdPath(c, "fred.barney"); 105 106 Object[] serviceParameters = new Object[0]; 107 108 Map parameters = new HashMap(); 109 110 parameters.put(ServiceConstants.PAGE, "ThePage"); 111 parameters.put(ServiceConstants.COMPONENT, "fred.barney"); 112 parameters.put(ServiceConstants.CONTAINER, null); 113 parameters.put(ServiceConstants.SESSION, null); 114 parameters.put(ServiceConstants.PARAMETER, serviceParameters); 115 116 DirectService ds = new DirectService(); 117 118 ds.setLinkFactory(lf); 119 ds.setRequest(request); 120 ds.setRequestCycle(cycle); 121 122 trainConstructLink(lf, ds, true, parameters, true, link); 123 124 replay(); 125 126 assertSame(link, ds.getLink(true, new DirectServiceParameter(c, serviceParameters))); 127 128 verify(); 129 } 130 131 public void test_Get_Link_On_Same_Page_Stateful() 132 { 133 IDirect c = newDirect(true); 134 135 IPage page = newPage("ThePage"); 136 IRequestCycle cycle = newCycle(); 137 WebSession session = newWebSession(); 138 WebRequest request = newWebRequest(false, session); 139 LinkFactory lf = newLinkFactory(); 140 ILink link = newLink(); 141 142 trainGetPage(cycle, page); 143 trainGetPage(c, page); 144 trainGetIdPath(c, "fred.barney"); 145 146 Object[] serviceParameters = new Object[0]; 147 148 Map parameters = new HashMap(); 149 150 parameters.put(ServiceConstants.PAGE, "ThePage"); 151 parameters.put(ServiceConstants.COMPONENT, "fred.barney"); 152 parameters.put(ServiceConstants.CONTAINER, null); 153 parameters.put(ServiceConstants.SESSION, "T"); 154 parameters.put(ServiceConstants.PARAMETER, serviceParameters); 155 156 DirectService ds = new DirectService(); 157 ds.setLinkFactory(lf); 158 ds.setRequest(request); 159 ds.setRequestCycle(cycle); 160 161 trainConstructLink(lf, ds, false, parameters, true, link); 162 163 replay(); 164 165 assertSame(link, ds.getLink(false, new DirectServiceParameter(c, serviceParameters))); 166 167 verify(); 168 } 169 170 public void test_Get_Link_On_Different_Page() 171 { 172 IPage page = newPage("ActivePage"); 173 IPage componentPage = newPage("ComponentPage"); 174 IDirect c = newDirect(true); 175 IRequestCycle cycle = newCycle(); 176 WebRequest request = newWebRequest(false, null); 177 LinkFactory lf = newLinkFactory(); 178 ILink link = newLink(); 179 180 trainGetPage(cycle, page); 181 trainGetPage(c, componentPage); 182 trainGetIdPath(c, "fred.barney"); 183 184 Object[] serviceParameters = new Object[0]; 185 186 Map parameters = new HashMap(); 187 188 parameters.put(ServiceConstants.PAGE, "ActivePage"); 189 parameters.put(ServiceConstants.COMPONENT, "fred.barney"); 190 parameters.put(ServiceConstants.CONTAINER, "ComponentPage"); 191 parameters.put(ServiceConstants.SESSION, null); 192 parameters.put(ServiceConstants.PARAMETER, serviceParameters); 193 194 DirectService ds = new DirectService(); 195 ds.setLinkFactory(lf); 196 ds.setRequest(request); 197 ds.setRequestCycle(cycle); 198 199 trainConstructLink(lf, ds, false, parameters, true, link); 200 201 replay(); 202 203 assertSame(link, ds.getLink(false, new DirectServiceParameter(c, serviceParameters))); 204 205 verify(); 206 } 207 208 public void test_Service_Simple() throws Exception 209 { 210 Object[] parameters = new Object[0]; 211 IRequestCycle cycle = newCycle(); 212 IPage page = newPage(); 213 IDirect d = newDirect(false); 214 LinkFactory lf = newLinkFactory(); 215 ResponseRenderer rr = newResponseRenderer(); 216 217 trainGetParameter(cycle, ServiceConstants.COMPONENT, "fred.barney"); 218 trainGetParameter(cycle, ServiceConstants.CONTAINER, null); 219 trainGetParameter(cycle, ServiceConstants.PAGE, "ActivePage"); 220 trainGetParameter(cycle, ServiceConstants.SESSION, null); 221 222 trainGetPage(cycle, "ActivePage", page); 223 cycle.activate(page); 224 225 trainGetNestedComponent(page, "fred.barney", d); 226 227 trainExtractListenerParameters(lf, cycle, parameters); 228 229 expect(cycle.getParameter(BrowserEvent.NAME)).andReturn(null); 230 231 cycle.setListenerParameters(parameters); 232 233 d.trigger(cycle); 234 235 rr.renderResponse(cycle); 236 237 replay(); 238 239 DirectService ds = new DirectService(); 240 ds.setLinkFactory(lf); 241 ds.setResponseRenderer(rr); 242 243 ds.service(cycle); 244 245 verify(); 246 } 247 248 public void test_Service_Simple_Event() throws Exception 249 { 250 Object[] parameters = new Object[0]; 251 IRequestCycle cycle = newCycle(); 252 IPage page = newPage(); 253 IDirect d = newDirect(false); 254 LinkFactory lf = newLinkFactory(); 255 ResponseRenderer rr = newResponseRenderer(); 256 257 trainGetParameter(cycle, ServiceConstants.COMPONENT, "fred.barney"); 258 trainGetParameter(cycle, ServiceConstants.CONTAINER, null); 259 trainGetParameter(cycle, ServiceConstants.PAGE, "ActivePage"); 260 trainGetParameter(cycle, ServiceConstants.SESSION, null); 261 262 trainGetPage(cycle, "ActivePage", page); 263 cycle.activate(page); 264 trainGetNestedComponent(page, "fred.barney", d); 265 266 trainExtractListenerParameters(lf, cycle, parameters); 267 trainExtractBrowserEvent(cycle); 268 269 cycle.setListenerParameters(isA(Object[].class)); 270 271 d.trigger(cycle); 272 273 rr.renderResponse(cycle); 274 275 replay(); 276 277 DirectService ds = new DirectService(); 278 ds.setLinkFactory(lf); 279 ds.setResponseRenderer(rr); 280 281 ds.service(cycle); 282 283 verify(); 284 } 285 286 /** 287 * The complex case is where the component is contained on a different page than the active (at 288 * the time of render) page. 289 */ 290 public void test_Service_Complex() throws Exception 291 { 292 Object[] parameters = new Object[0]; 293 IRequestCycle cycle = newCycle(); 294 IPage page = newPage(); 295 IPage componentPage = newPage(); 296 IDirect d = newDirect(false); 297 LinkFactory lf = newLinkFactory(); 298 ResponseRenderer rr = newResponseRenderer(); 299 300 trainGetParameter(cycle, ServiceConstants.COMPONENT, "fred.barney"); 301 trainGetParameter(cycle, ServiceConstants.CONTAINER, "ComponentPage"); 302 trainGetParameter(cycle, ServiceConstants.PAGE, "ActivePage"); 303 trainGetParameter(cycle, ServiceConstants.SESSION, null); 304 305 trainGetPage(cycle, "ActivePage", page); 306 307 cycle.activate(page); 308 309 trainGetPage(cycle, "ComponentPage", componentPage); 310 311 trainGetNestedComponent(componentPage, "fred.barney", d); 312 313 trainExtractListenerParameters(lf, cycle, parameters); 314 315 expect(cycle.getParameter(BrowserEvent.NAME)).andReturn(null); 316 317 cycle.setListenerParameters(parameters); 318 319 d.trigger(cycle); 320 321 rr.renderResponse(cycle); 322 323 replay(); 324 325 DirectService ds = new DirectService(); 326 ds.setLinkFactory(lf); 327 ds.setResponseRenderer(rr); 328 329 ds.service(cycle); 330 331 verify(); 332 } 333 334 public void test_Service_Not_Direct() throws Exception 335 { 336 IRequestCycle cycle = newCycle(); 337 IPage page = newPage(); 338 IComponent c = newComponent(); 339 Location l = newLocation(); 340 341 trainGetParameter(cycle, ServiceConstants.COMPONENT, "fred.barney"); 342 trainGetParameter(cycle, ServiceConstants.CONTAINER, null); 343 trainGetParameter(cycle, ServiceConstants.PAGE, "ActivePage"); 344 trainGetParameter(cycle, ServiceConstants.SESSION, null); 345 346 trainGetPage(cycle, "ActivePage", page); 347 cycle.activate(page); 348 349 trainGetNestedComponent(page, "fred.barney", c); 350 351 trainGetExtendedId(c, "ActivePage/fred.barney"); 352 trainGetLocation(c, l); 353 354 replay(); 355 356 DirectService ds = new DirectService(); 357 358 try 359 { 360 ds.service(cycle); 361 unreachable(); 362 } 363 catch (ApplicationRuntimeException ex) 364 { 365 assertEquals( 366 "Component ActivePage/fred.barney does not implement the org.apache.tapestry.IDirect interface.", 367 ex.getMessage()); 368 assertSame(c, ex.getComponent()); 369 assertSame(l, ex.getLocation()); 370 } 371 372 verify(); 373 } 374 375 public void test_Session_Active_And_Required() throws Exception 376 { 377 Object[] parameters = new Object[0]; 378 IRequestCycle cycle = newCycle(); 379 IPage page = newPage(); 380 IDirect d = newDirect(false); 381 382 LinkFactory lf = newLinkFactory(); 383 ResponseRenderer rr = newResponseRenderer(); 384 385 trainGetParameter(cycle, ServiceConstants.COMPONENT, "fred.barney"); 386 trainGetParameter(cycle, ServiceConstants.CONTAINER, null); 387 trainGetParameter(cycle, ServiceConstants.PAGE, "ActivePage"); 388 trainGetParameter(cycle, ServiceConstants.SESSION, "T"); 389 390 trainGetPage(cycle, "ActivePage", page); 391 cycle.activate(page); 392 393 trainGetNestedComponent(page, "fred.barney", d); 394 395 trainIsStateful(d, true); 396 397 WebSession session = newMock(WebSession.class); 398 WebRequest request = newWebRequest(session); 399 400 expect(session.isNew()).andReturn(false); 401 402 trainExtractListenerParameters(lf, cycle, parameters); 403 404 expect(cycle.getParameter(BrowserEvent.NAME)).andReturn(null); 405 406 cycle.setListenerParameters(parameters); 407 408 d.trigger(cycle); 409 410 rr.renderResponse(cycle); 411 412 replay(); 413 414 DirectService ds = new DirectService(); 415 ds.setLinkFactory(lf); 416 ds.setResponseRenderer(rr); 417 ds.setRequest(request); 418 419 ds.service(cycle); 420 421 verify(); 422 } 423 424 protected void trainIsStateful(IDirect direct, boolean isStateful) 425 { 426 expect(direct.isStateful()).andReturn(isStateful); 427 } 428 429 public void test_Stale_Session() throws Exception 430 { 431 IRequestCycle cycle = newCycle(); 432 IPage page = newPage(); 433 IDirect d = newDirect(false); 434 435 Location l = newLocation(); 436 437 trainGetParameter(cycle, ServiceConstants.COMPONENT, "fred.barney"); 438 trainGetParameter(cycle, ServiceConstants.CONTAINER, null); 439 trainGetParameter(cycle, ServiceConstants.PAGE, "ActivePage"); 440 trainGetParameter(cycle, ServiceConstants.SESSION, "T"); 441 442 trainGetPage(cycle, "ActivePage", page); 443 cycle.activate(page); 444 445 trainGetNestedComponent(page, "fred.barney", d); 446 447 trainIsStateful(d, true); 448 449 WebRequest request = newWebRequest(null); 450 451 trainGetExtendedId(d, "ActivePage/fred.barney"); 452 trainGetLocation(page, l); 453 trainGetPageName(page, "ActivePage"); 454 455 replay(); 456 457 DirectService ds = new DirectService(); 458 ds.setRequest(request); 459 460 try 461 { 462 ds.service(cycle); 463 unreachable(); 464 } 465 catch (StaleSessionException ex) 466 { 467 assertEquals( 468 "Component ActivePage/fred.barney is stateful, but the HttpSession has expired (or has not yet been created).", 469 ex.getMessage()); 470 assertSame(page, ex.getComponent()); 471 assertSame(l, ex.getLocation()); 472 assertEquals("ActivePage", ex.getPageName()); 473 assertSame(page, ex.getPage()); 474 } 475 476 verify(); 477 } 478 }