| /* |
| * Copyright 2010 Google 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.google.web.bindery.requestfactory.gwt.client; |
| |
| import com.google.web.bindery.event.shared.HandlerRegistration; |
| import com.google.web.bindery.requestfactory.shared.EntityProxyChange; |
| import com.google.web.bindery.requestfactory.shared.EntityProxyId; |
| import com.google.web.bindery.requestfactory.shared.MapKeyProxy; |
| import com.google.web.bindery.requestfactory.shared.MapValueProxy; |
| import com.google.web.bindery.requestfactory.shared.Receiver; |
| import com.google.web.bindery.requestfactory.shared.Request; |
| import com.google.web.bindery.requestfactory.shared.SimpleBarProxy; |
| import com.google.web.bindery.requestfactory.shared.SimpleBarRequest; |
| import com.google.web.bindery.requestfactory.shared.SimpleFooProxy; |
| import com.google.web.bindery.requestfactory.shared.SimpleFooRequest; |
| import com.google.web.bindery.requestfactory.shared.SimpleRequestFactory; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** |
| * Tests for {@link com.google.web.bindery.requestfactory.shared.RequestFactory} |
| * . |
| */ |
| public class FindServiceTest extends RequestFactoryTestBase { |
| /* |
| * DO NOT USE finishTest(). Instead, call finishTestAndReset(); |
| */ |
| |
| private static final int TEST_DELAY = 5000; |
| |
| private static final String[] SIMPLE_FOO_RELATIONS = { "barField", "simpleBarKeyMap", |
| "simpleBarValueMap", "entityKeyAndValueMap" }; |
| |
| @Override |
| public String getModuleName() { |
| return "com.google.web.bindery.requestfactory.gwt.RequestFactorySuite"; |
| } |
| |
| /** |
| * Tests {@code RequestContext.find()}, which uses the same plumbing as |
| * {@code RequestFactory.find()}, but can be chained. |
| */ |
| public void testChainedFind() { |
| delayTestFinish(TEST_DELAY); |
| List<String> ids = Arrays.asList("1L", "999L"); |
| final List<SimpleBarProxy> proxies = new ArrayList<SimpleBarProxy>(); |
| SimpleBarRequest ctx = req.simpleBarRequest(); |
| for (String id : ids) { |
| ctx.findSimpleBarById(id).to(new Receiver<SimpleBarProxy>() { |
| @Override |
| public void onSuccess(SimpleBarProxy response) { |
| proxies.add(response); |
| } |
| }); |
| } |
| ctx.fire(new Receiver<Void>() { |
| @Override |
| public void onSuccess(Void response) { |
| final List<SimpleBarProxy> reloaded = new ArrayList<SimpleBarProxy>(); |
| SimpleBarRequest ctx = req.simpleBarRequest(); |
| for (SimpleBarProxy proxy : proxies) { |
| ctx.find(proxy.stableId()).to(new Receiver<SimpleBarProxy>() { |
| @Override |
| public void onSuccess(SimpleBarProxy response) { |
| reloaded.add(response); |
| } |
| }); |
| } |
| ctx.fire(new Receiver<Void>() { |
| @Override |
| public void onSuccess(Void response) { |
| assertEquals(proxies, reloaded); |
| finishTest(); |
| } |
| }); |
| } |
| }); |
| } |
| |
| public void testFetchDeletedEntity() { |
| delayTestFinish(TEST_DELAY); |
| SimpleBarRequest context = req.simpleBarRequest(); |
| SimpleBarProxy willDelete = context.create(SimpleBarProxy.class); |
| context.persistAndReturnSelf().using(willDelete).fire(new Receiver<SimpleBarProxy>() { |
| @Override |
| public void onSuccess(SimpleBarProxy response) { |
| final EntityProxyId<SimpleBarProxy> id = response.stableId(); |
| |
| // Make the entity behave as though it's been deleted |
| SimpleBarRequest context = req.simpleBarRequest(); |
| Request<Void> persist = context.persist().using(response); |
| context.edit(response).setFindFails(true); |
| persist.fire(new Receiver<Void>() { |
| |
| @Override |
| public void onSuccess(Void response) { |
| // Now try fetching the deleted instance |
| req.find(id).fire(new Receiver<SimpleBarProxy>() { |
| @Override |
| public void onSuccess(SimpleBarProxy response) { |
| assertNull(response); |
| finishTestAndReset(); |
| } |
| }); |
| } |
| }); |
| } |
| }); |
| } |
| |
| public void testFetchEntityWithLongId() { |
| final boolean relationsAbsent = false; |
| delayTestFinish(TEST_DELAY); |
| req.simpleFooRequest().findSimpleFooById(999L).fire(new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| checkReturnedProxy(response, relationsAbsent); |
| |
| final EntityProxyId<SimpleFooProxy> stableId = response.stableId(); |
| req.find(stableId).fire(new Receiver<SimpleFooProxy>() { |
| |
| @Override |
| public void onSuccess(SimpleFooProxy returnedProxy) { |
| assertEquals(stableId, returnedProxy.stableId()); |
| checkReturnedProxy(returnedProxy, relationsAbsent); |
| finishTestAndReset(); |
| } |
| }); |
| } |
| }); |
| } |
| |
| public void testFetchEntityWithRelation() { |
| final boolean relationsPresent = true; |
| delayTestFinish(TEST_DELAY); |
| req.simpleFooRequest().findSimpleFooById(999L).with(SIMPLE_FOO_RELATIONS).fire( |
| new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| checkReturnedProxy(response, relationsPresent); |
| |
| final EntityProxyId<SimpleFooProxy> stableId = response.stableId(); |
| req.find(stableId).with(SIMPLE_FOO_RELATIONS).fire(new Receiver<SimpleFooProxy>() { |
| |
| @Override |
| public void onSuccess(SimpleFooProxy returnedProxy) { |
| assertEquals(stableId, returnedProxy.stableId()); |
| checkReturnedProxy(returnedProxy, relationsPresent); |
| finishTestAndReset(); |
| } |
| }); |
| } |
| }); |
| } |
| |
| public void testFetchEntityWithEntityKeyValueMapNoChildren() { |
| delayTestFinish(TEST_DELAY); |
| req.simpleFooRequest().findSimpleFooById(999L).with("entityKeyAndValueMap").fire( |
| new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| |
| assertEquals(1, response.getEntityKeyAndValueMap().size()); |
| |
| Map.Entry<MapKeyProxy, MapValueProxy> entry = |
| response.getEntityKeyAndValueMap().entrySet().iterator().next(); |
| |
| assertNotNull(entry.getKey()); |
| assertNotNull(entry.getValue()); |
| |
| assertNull(entry.getKey().getSimple()); |
| assertNull(entry.getValue().getSimple()); |
| |
| finishTestAndReset(); |
| } |
| }); |
| } |
| |
| public void testFetchEntityWithEntityKeyValueMapJustKeyChildren() { |
| delayTestFinish(TEST_DELAY); |
| req.simpleFooRequest().findSimpleFooById(999L).with("entityKeyAndValueMap.keys.simple").fire( |
| new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| assertEquals(1, response.getEntityKeyAndValueMap().size()); |
| |
| Map.Entry<MapKeyProxy, MapValueProxy> entry = |
| response.getEntityKeyAndValueMap().entrySet().iterator().next(); |
| |
| assertNotNull(entry.getKey()); |
| assertNotNull(entry.getValue()); |
| |
| assertNotNull(entry.getKey().getSimple()); |
| assertNull(entry.getValue().getSimple()); |
| finishTestAndReset(); |
| } |
| }); |
| } |
| |
| public void testFetchEntityWithEntityKeyValueMapJustValueChildren() { |
| delayTestFinish(TEST_DELAY); |
| req.simpleFooRequest().findSimpleFooById(999L).with("entityKeyAndValueMap.values.simple").fire( |
| new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| assertEquals(1, response.getEntityKeyAndValueMap().size()); |
| |
| Map.Entry<MapKeyProxy, MapValueProxy> entry = |
| response.getEntityKeyAndValueMap().entrySet().iterator().next(); |
| |
| assertNotNull(entry.getKey()); |
| assertNotNull(entry.getValue()); |
| |
| assertNull(entry.getKey().getSimple()); |
| assertNotNull(entry.getValue().getSimple()); |
| finishTestAndReset(); |
| } |
| }); |
| } |
| |
| public void testFetchEntityWithEntityKeyValueMapBothKeyAndValueChildren() { |
| delayTestFinish(TEST_DELAY); |
| req.simpleFooRequest().findSimpleFooById(999L).with("entityKeyAndValueMap.keys.simple", |
| "entityKeyAndValueMap.values.simple").fire( |
| new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| assertEquals(1, response.getEntityKeyAndValueMap().size()); |
| |
| Map.Entry<MapKeyProxy, MapValueProxy> entry = |
| response.getEntityKeyAndValueMap().entrySet().iterator().next(); |
| |
| assertNotNull(entry.getKey()); |
| assertNotNull(entry.getValue()); |
| |
| assertNotNull(entry.getKey().getSimple()); |
| assertNotNull(entry.getValue().getSimple()); |
| finishTestAndReset(); |
| } |
| }); |
| } |
| |
| public void testFetchEntityWithRelationWithEmptyMaps() { |
| final boolean relationsPresent = true; |
| delayTestFinish(TEST_DELAY); |
| req.simpleFooRequest().findSimpleFooById(999L).with(SIMPLE_FOO_RELATIONS).fire( |
| new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| checkReturnedProxy(response, relationsPresent); |
| |
| SimpleFooRequest editRequest = req.simpleFooRequest(); |
| SimpleFooProxy editableSimpleFoo = editRequest.edit(response); |
| editableSimpleFoo.setSimpleBarKeyMap( new HashMap<SimpleBarProxy, Integer>()); |
| editableSimpleFoo.setSimpleBarValueMap( new HashMap<Integer, SimpleBarProxy>()); |
| editRequest.persistAndReturnSelf().using(editableSimpleFoo).with(SIMPLE_FOO_RELATIONS).fire( |
| new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy returnedProxy) { |
| assertEquals(0, returnedProxy.getSimpleBarKeyMap().size()); |
| assertEquals(0, returnedProxy.getSimpleBarValueMap().size()); |
| finishTestAndReset(); |
| } |
| }); |
| } |
| }); |
| } |
| |
| public void testFetchEntityWithStringId() { |
| delayTestFinish(TEST_DELAY); |
| req.simpleBarRequest().findSimpleBarById("999L").fire(new Receiver<SimpleBarProxy>() { |
| @Override |
| public void onSuccess(SimpleBarProxy response) { |
| final EntityProxyId<SimpleBarProxy> stableId = response.stableId(); |
| req.find(stableId).fire(new Receiver<SimpleBarProxy>() { |
| |
| @Override |
| public void onSuccess(SimpleBarProxy returnedProxy) { |
| assertEquals(stableId, returnedProxy.stableId()); |
| finishTestAndReset(); |
| } |
| }); |
| } |
| }); |
| } |
| |
| public void testFetchsAfterCreateDontUpdate() { |
| final int[] count = {0}; |
| final HandlerRegistration registration = |
| EntityProxyChange.registerForProxyType(req.getEventBus(), SimpleFooProxy.class, |
| new EntityProxyChange.Handler<SimpleFooProxy>() { |
| @Override |
| public void onProxyChange(EntityProxyChange<SimpleFooProxy> event) { |
| count[0]++; |
| } |
| }); |
| delayTestFinish(TEST_DELAY); |
| SimpleFooRequest context = req.simpleFooRequest(); |
| SimpleFooProxy proxy = context.create(SimpleFooProxy.class); |
| context.persistAndReturnSelf().using(proxy).fire(new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| // Persist and Update events |
| assertEquals(2, count[0]); |
| req.find(response.stableId()).fire(new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| // No new events |
| assertEquals(2, count[0]); |
| registration.removeHandler(); |
| finishTestAndReset(); |
| } |
| }); |
| } |
| }); |
| } |
| |
| /** |
| * Demonstrates behavior when fetching an unpersisted id. The setup is |
| * analagous to saving a future id into a cookie and then trying to fetch it |
| * later. |
| */ |
| public void testFetchUnpersistedFutureId() { |
| String historyToken; |
| |
| // Here's the factory from the "previous invocation" of the client |
| { |
| SimpleRequestFactory oldFactory = createFactory(); |
| EntityProxyId<SimpleBarProxy> id = |
| oldFactory.simpleBarRequest().create(SimpleBarProxy.class).stableId(); |
| historyToken = oldFactory.getHistoryToken(id); |
| } |
| |
| EntityProxyId<SimpleBarProxy> id = req.getProxyId(historyToken); |
| assertNotNull(id); |
| try { |
| req.find(id); |
| fail(); |
| } catch (IllegalArgumentException expected) { |
| } |
| } |
| |
| /** |
| * A second fetch for an unchanged object should not result in any update |
| * event. |
| */ |
| public void testMultipleFetchesDontUpdate() { |
| final int[] count = {0}; |
| final HandlerRegistration registration = |
| EntityProxyChange.registerForProxyType(req.getEventBus(), SimpleFooProxy.class, |
| new EntityProxyChange.Handler<SimpleFooProxy>() { |
| @Override |
| public void onProxyChange(EntityProxyChange<SimpleFooProxy> event) { |
| count[0]++; |
| } |
| }); |
| delayTestFinish(TEST_DELAY); |
| req.simpleFooRequest().findSimpleFooById(999L).fire(new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| assertEquals(1, count[0]); |
| |
| final EntityProxyId<SimpleFooProxy> stableId = response.stableId(); |
| req.find(stableId).fire(new Receiver<SimpleFooProxy>() { |
| |
| @Override |
| public void onSuccess(SimpleFooProxy returnedProxy) { |
| assertEquals(1, count[0]); |
| registration.removeHandler(); |
| finishTestAndReset(); |
| } |
| }); |
| } |
| }); |
| } |
| |
| private void checkReturnedProxy(SimpleFooProxy response, boolean checkForRelations) { |
| assertEquals(42, (int) response.getIntId()); |
| assertEquals("GWT", response.getUserName()); |
| assertEquals(8L, (long) response.getLongField()); |
| assertEquals(com.google.web.bindery.requestfactory.shared.SimpleEnum.FOO, response |
| .getEnumField()); |
| assertEquals(3, response.getValueMap().size()); |
| if (checkForRelations) { |
| assertNotNull(response.getBarField()); |
| assertEquals(1, response.getSimpleBarKeyMap().size()); |
| assertEquals(1, response.getEntityKeyAndValueMap().size()); |
| } else { |
| assertEquals(null, response.getBarField()); |
| assertEquals(null, response.getSimpleBarKeyMap()); |
| assertEquals(null, response.getEntityKeyAndValueMap()); |
| } |
| } |
| } |