001 // Copyright 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.record; 016 017 import static org.easymock.EasyMock.checkOrder; 018 import static org.easymock.EasyMock.expect; 019 020 import java.util.ArrayList; 021 import java.util.Collection; 022 import java.util.Collections; 023 024 import org.apache.hivemind.ApplicationRuntimeException; 025 import org.apache.hivemind.ErrorLog; 026 import org.apache.hivemind.Location; 027 import org.apache.hivemind.Resource; 028 import org.apache.tapestry.BaseComponentTestCase; 029 import org.apache.tapestry.IComponent; 030 import org.apache.tapestry.IPage; 031 import org.apache.tapestry.event.ObservedChangeEvent; 032 import org.apache.tapestry.spec.IComponentSpecification; 033 import org.apache.tapestry.spec.IPropertySpecification; 034 import org.apache.tapestry.test.Creator; 035 import org.testng.annotations.Test; 036 037 /** 038 * Tests for {@link org.apache.tapestry.record.PageRecorderImpl}. 039 * 040 * @author Howard M. Lewis Ship 041 * @since 4.0 042 */ 043 @Test 044 public class TestPageRecorder extends BaseComponentTestCase 045 { 046 private ErrorLog newErrorLog() 047 { 048 return newMock(ErrorLog.class); 049 } 050 051 public void testGetChanges() 052 { 053 ErrorLog log = newErrorLog(); 054 055 PropertyPersistenceStrategySource source = newMock(PropertyPersistenceStrategySource.class); 056 057 Collection expected = new ArrayList(); 058 059 expect(source.getAllStoredChanges("Foo")).andReturn(expected); 060 061 replay(); 062 063 PageRecorderImpl pr = new PageRecorderImpl("Foo", source, log); 064 065 Collection actual = pr.getChanges(); 066 067 assertSame(expected, actual); 068 069 verify(); 070 } 071 072 private IComponentSpecification newSpec(String propertyName, String persistence) 073 { 074 IComponentSpecification spec = newSpec(); 075 076 IPropertySpecification ps = newMock(IPropertySpecification.class); 077 checkOrder(ps, false); 078 079 expect(spec.getPropertySpecification(propertyName)).andReturn(ps); 080 081 expect(ps.getPersistence()).andReturn(persistence); 082 083 return spec; 084 } 085 086 public void testObserveChange() 087 { 088 ErrorLog log = newErrorLog(); 089 090 IPage page = newPage(); 091 092 IComponentSpecification spec = newSpec("foobar", "session"); 093 094 expect(page.getSpecification()).andReturn(spec); 095 096 expect(page.getIdPath()).andReturn(null); 097 098 PropertyPersistenceStrategySource source = newMock(PropertyPersistenceStrategySource.class); 099 100 PropertyPersistenceStrategy strategy = newMock(PropertyPersistenceStrategy.class); 101 102 expect(source.getStrategy("session")).andReturn(strategy); 103 104 Object newValue = new Object(); 105 106 strategy.store("Foo", null, "foobar", newValue); 107 108 replay(); 109 110 PageRecorderImpl pr = new PageRecorderImpl("Foo", source, log); 111 112 ObservedChangeEvent event = new ObservedChangeEvent(page, "foobar", newValue); 113 114 pr.observeChange(event); 115 116 verify(); 117 } 118 119 public void testUnknownStategy() 120 { 121 Location l = fabricateLocation(12); 122 Throwable inner = new ApplicationRuntimeException("Simulated error."); 123 ErrorLog log = newErrorLog(); 124 125 PropertyPersistenceStrategySource source = newMock(PropertyPersistenceStrategySource.class); 126 127 IComponent component = newComponent(); 128 129 IComponentSpecification spec = newSpec(); 130 131 IPropertySpecification ps = newMock(IPropertySpecification.class); 132 133 expect(component.getSpecification()).andReturn(spec); 134 135 expect(spec.getPropertySpecification("zip")).andReturn(ps); 136 137 expect(ps.getPersistence()).andReturn("unknown"); 138 139 expect(source.getStrategy("unknown")).andThrow(inner); 140 141 expect(ps.getLocation()).andReturn(l); 142 143 log.error("Simulated error.", l, inner); 144 145 replay(); 146 147 PageRecorderImpl pr = new PageRecorderImpl("SomePage", source, log); 148 149 assertNull(pr.findStrategy(component, "zip")); 150 151 verify(); 152 } 153 154 public void testRollbackPageProperty() 155 { 156 ErrorLog log = newErrorLog(); 157 158 Creator creator = new Creator(); 159 160 PageFixture page = (PageFixture) creator.newInstance(PageFixture.class); 161 162 PropertyPersistenceStrategySource source = newMock(PropertyPersistenceStrategySource.class); 163 164 PropertyChange pc = new PropertyChangeImpl(null, "cartoonName", "Dexter's Laboratory"); 165 166 expect(source.getAllStoredChanges("MyPage")).andReturn(Collections.singletonList(pc)); 167 168 replay(); 169 170 PageRecorderImpl pr = new PageRecorderImpl("MyPage", source, log); 171 172 pr.rollback(page); 173 174 assertEquals("Dexter's Laboratory", page.getCartoonName()); 175 176 verify(); 177 } 178 179 public void testRollbackComponentProperty() 180 { 181 ErrorLog log = newErrorLog(); 182 183 IPage page = newPage(); 184 185 IComponent component = newMock(IComponent.class); 186 187 PropertyPersistenceStrategySource source = newMock(PropertyPersistenceStrategySource.class); 188 189 PropertyChange pc = new PropertyChangeImpl("fred.barney", "id", "ziff"); 190 191 expect(source.getAllStoredChanges("MyPage")).andReturn(Collections.singletonList(pc)); 192 193 expect(page.getNestedComponent("fred.barney")).andReturn(component); 194 195 component.setId("ziff"); 196 197 replay(); 198 199 PageRecorderImpl pr = new PageRecorderImpl("MyPage", source, log); 200 201 pr.rollback(page); 202 203 verify(); 204 } 205 206 public void testChangeWhileLocked() 207 { 208 ErrorLog log = newErrorLog(); 209 210 IPage page = newPage(); 211 212 PropertyPersistenceStrategySource source = newMock(PropertyPersistenceStrategySource.class); 213 214 expect(page.getExtendedId()).andReturn("MyPage"); 215 216 log 217 .error( 218 "Change to persistent property foobar of MyPage has been ignored." 219 + " Persistent properties may only be changed prior to the rendering of the response page.", 220 null, 221 null); 222 223 replay(); 224 225 PageRecorderImpl pr = new PageRecorderImpl("MyPage", source, log); 226 227 pr.commit(); 228 229 ObservedChangeEvent event = new ObservedChangeEvent(page, "foobar", new Object()); 230 231 pr.observeChange(event); 232 233 verify(); 234 } 235 236 public void testChangeToNonSpecifiedProperty() 237 { 238 Resource r = newResource(); 239 240 ErrorLog log = newErrorLog(); 241 242 IPage page = newPage(); 243 244 IComponentSpecification spec = newSpec(); 245 246 PropertyPersistenceStrategySource source = newMock(PropertyPersistenceStrategySource.class); 247 248 expect(page.getSpecification()).andReturn(spec); 249 250 expect(spec.getPropertySpecification("foobar")).andReturn(null); 251 252 expect(page.getExtendedId()).andReturn("TestPage"); 253 254 expect(page.getSpecification()).andReturn(spec); 255 256 expect(spec.getSpecificationLocation()).andReturn(r); 257 258 log.error( 259 "A property change event for property foobar of TestPage was observed, " 260 + "but no such property is identified in the specification (" + r + ").", 261 null, 262 null); 263 264 replay(); 265 266 PageRecorderImpl pr = new PageRecorderImpl("TestPage", source, log); 267 268 ObservedChangeEvent event = new ObservedChangeEvent(page, "foobar", new Object()); 269 270 pr.observeChange(event); 271 272 verify(); 273 } 274 }