| /* |
| * 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.gwt.requestfactory.client.ui; |
| |
| import com.google.gwt.core.client.GWT; |
| import com.google.gwt.core.client.Scheduler; |
| import com.google.gwt.core.client.Scheduler.RepeatingCommand; |
| import com.google.gwt.editor.client.Editor; |
| import com.google.gwt.editor.client.EditorDelegate; |
| import com.google.gwt.editor.client.EditorError; |
| import com.google.gwt.editor.client.HasEditorDelegate; |
| import com.google.gwt.editor.client.HasEditorErrors; |
| import com.google.gwt.editor.client.adapters.EditorSource; |
| import com.google.gwt.editor.client.adapters.ListEditor; |
| import com.google.gwt.editor.client.adapters.SimpleEditor; |
| import com.google.gwt.requestfactory.client.RequestFactoryEditorDriver; |
| import com.google.gwt.requestfactory.client.RequestFactoryTestBase; |
| import com.google.gwt.requestfactory.shared.Receiver; |
| import com.google.gwt.requestfactory.shared.Request; |
| import com.google.gwt.requestfactory.shared.SimpleBarProxy; |
| import com.google.gwt.requestfactory.shared.SimpleFooProxy; |
| import com.google.gwt.requestfactory.shared.SimpleFooRequest; |
| import com.google.gwt.requestfactory.shared.Violation; |
| |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.Set; |
| |
| /** |
| * Integration test of the Editor framework. Only tests for |
| * RequestFactory-specific features belong here; all other tests should use the |
| * SimpleBeanEditorDriver to make the tests simpler. |
| */ |
| public class EditorTest extends RequestFactoryTestBase { |
| /* |
| * DO NOT USE finishTest(). Instead, call finishTestAndReset(); |
| */ |
| |
| static class SimpleBarEditor implements Editor<SimpleBarProxy> { |
| protected final SimpleEditor<String> userName = SimpleEditor.of(); |
| } |
| |
| static class SimpleFooBarOnlyEditor implements Editor<SimpleFooProxy> { |
| SimpleBarEditor barField = new SimpleBarEditor(); |
| } |
| |
| interface SimpleFooDriver extends |
| RequestFactoryEditorDriver<SimpleFooProxy, SimpleFooEditor> { |
| } |
| |
| static class SimpleFooEditor implements HasEditorErrors<SimpleFooProxy> { |
| /** |
| * Test field-based access. |
| */ |
| final SimpleEditor<String> userName = SimpleEditor.of(); |
| |
| /** |
| * Test nested path access. |
| */ |
| @Path("barField.userName") |
| final SimpleEditor<String> barName = SimpleEditor.of(); |
| |
| final ListEditor<SimpleFooProxy, SimpleFooBarOnlyEditor> selfOneToManyField = ListEditor.of(new EditorSource<SimpleFooBarOnlyEditor>() { |
| @Override |
| public SimpleFooBarOnlyEditor create(int index) { |
| return new SimpleFooBarOnlyEditor(); |
| } |
| }); |
| |
| private final SimpleBarEditor barEditor = new SimpleBarEditor(); |
| |
| List<EditorError> errors; |
| |
| public void showErrors(List<EditorError> errors) { |
| this.errors = errors; |
| } |
| |
| /** |
| * Test method-based access with path override. |
| */ |
| @Path("barField") |
| SimpleBarEditor barEditor() { |
| return barEditor; |
| } |
| } |
| |
| static class SimpleFooEditorWithDelegate extends SimpleFooEditor implements |
| HasEditorDelegate<SimpleFooProxy> { |
| EditorDelegate<SimpleFooProxy> delegate; |
| |
| public void setDelegate(EditorDelegate<SimpleFooProxy> delegate) { |
| this.delegate = delegate; |
| } |
| } |
| |
| private static final int TEST_TIMEOUT = 5000; |
| |
| @Override |
| public String getModuleName() { |
| return "com.google.gwt.requestfactory.RequestFactorySuite"; |
| } |
| |
| public void test() { |
| delayTestFinish(TEST_TIMEOUT); |
| final SimpleFooEditor editor = new SimpleFooEditor(); |
| |
| final SimpleFooDriver driver = GWT.create(SimpleFooDriver.class); |
| driver.initialize(req, editor); |
| |
| req.simpleFooRequest().findSimpleFooById(1L).with(driver.getPaths()).fire( |
| new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| |
| SimpleFooRequest context = req.simpleFooRequest(); |
| driver.edit(response, context); |
| context.persistAndReturnSelf().using(response).with( |
| driver.getPaths()).to(new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| assertEquals("EditorFooTest", response.getUserName()); |
| assertEquals("EditorBarTest", |
| response.getBarField().getUserName()); |
| finishTestAndReset(); |
| } |
| }); |
| assertEquals("GWT", editor.userName.getValue()); |
| assertEquals("FOO", editor.barEditor().userName.getValue()); |
| assertEquals("FOO", editor.barName.getValue()); |
| editor.userName.setValue("EditorFooTest"); |
| // When there are duplicate paths, last declared editor wins |
| editor.barEditor().userName.setValue("EditorBarTest"); |
| editor.barName.setValue("ignored"); |
| driver.flush().fire(); |
| } |
| }); |
| } |
| |
| public void testNoSubscription() { |
| final SimpleFooEditorWithDelegate editor = new SimpleFooEditorWithDelegate(); |
| |
| final SimpleFooDriver driver = GWT.create(SimpleFooDriver.class); |
| driver.initialize(req, editor); |
| |
| /* |
| * Confirm that it's always safe to call subscribe. The editor's delegate |
| * isn't set until edit is called, so edit nothing. |
| */ |
| driver.edit(null, null); |
| assertNull(editor.delegate.subscribe()); |
| } |
| |
| /** |
| * Tests the editor can be re-used while the initial context is locked and |
| * therefore its attached proxies are frozen.. |
| * |
| * @see http://code.google.com/p/google-web-toolkit/issues/detail?id=5752 |
| */ |
| public void testReuse() { |
| delayTestFinish(TEST_TIMEOUT); |
| final SimpleFooEditor editor = new SimpleFooEditor(); |
| |
| final SimpleFooDriver driver = GWT.create(SimpleFooDriver.class); |
| driver.initialize(req, editor); |
| |
| req.simpleFooRequest().findSimpleFooById(1L).with(driver.getPaths()).fire( |
| new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| |
| SimpleFooRequest context = req.simpleFooRequest(); |
| driver.edit(response, context); |
| editor.userName.setValue("One"); |
| context.persistAndReturnSelf().using(response).with( |
| driver.getPaths()).to(new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| assertEquals("One", response.getUserName()); |
| // just testing that it doesn't throw (see issue 5752) |
| driver.edit(response, req.simpleFooRequest()); |
| editor.userName.setValue("Two"); |
| driver.flush(); |
| finishTestAndReset(); |
| } |
| }); |
| // The fire() will freeze the proxies and lock the context |
| driver.flush().fire(); |
| } |
| }); |
| } |
| |
| public void testSubscription() { |
| delayTestFinish(TEST_TIMEOUT); |
| final SimpleFooEditorWithDelegate editor = new SimpleFooEditorWithDelegate(); |
| |
| final SimpleFooDriver driver = GWT.create(SimpleFooDriver.class); |
| driver.initialize(req, editor); |
| |
| String[] paths = driver.getPaths(); |
| assertEquals(Arrays.asList("barField.userName", "selfOneToManyField", |
| "selfOneToManyField.barField", "barField"), Arrays.asList(paths)); |
| |
| req.simpleFooRequest().findSimpleFooById(1L).with(paths).fire( |
| new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| // Set up driver in read-only mode |
| driver.edit(response, null); |
| assertNotNull(editor.delegate.subscribe()); |
| |
| // Simulate edits occurring elsewhere in the module |
| SimpleFooRequest context = req.simpleFooRequest(); |
| Request<SimpleFooProxy> request = context.persistAndReturnSelf().using( |
| response); |
| SimpleBarProxy newBar = context.create(SimpleBarProxy.class); |
| newBar = context.edit(newBar); |
| newBar.setUserName("newBar"); |
| response = context.edit(response); |
| response.setBarField(newBar); |
| response.setUserName("updated"); |
| |
| request.fire(new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| System.out.println("B"); |
| // EventBus notifications occur after the onSuccess() |
| Scheduler.get().scheduleFixedDelay(new RepeatingCommand() { |
| public boolean execute() { |
| System.out.println("fo"); |
| if ("updated".equals(editor.userName.getValue())) { |
| assertEquals("updated", editor.userName.getValue()); |
| assertEquals("newBar", |
| editor.barEditor().userName.getValue()); |
| finishTestAndReset(); |
| return false; |
| } |
| return true; |
| } |
| }, 50); |
| } |
| }); |
| } |
| }); |
| } |
| |
| public void testViolations() { |
| delayTestFinish(TEST_TIMEOUT); |
| final SimpleFooEditor editor = new SimpleFooEditor(); |
| |
| final SimpleFooDriver driver = GWT.create(SimpleFooDriver.class); |
| driver.initialize(req, editor); |
| |
| req.simpleFooRequest().findSimpleFooById(1L).with(driver.getPaths()).fire( |
| new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| |
| SimpleFooRequest context = req.simpleFooRequest(); |
| driver.edit(response, context); |
| context.persistAndReturnSelf().using(response).with( |
| driver.getPaths()).to(new Receiver<SimpleFooProxy>() { |
| @Override |
| public void onSuccess(SimpleFooProxy response) { |
| fail("Expected errors. You may be missing jars, see " |
| + "the comment in RequestFactoryTest.ShouldNotSucceedReceiver.onSuccess"); |
| } |
| |
| @Override |
| public void onViolation(Set<Violation> errors) { |
| assertEquals(1, errors.size()); |
| Violation v = errors.iterator().next(); |
| |
| driver.setViolations(errors); |
| assertEquals(1, editor.errors.size()); |
| EditorError error = editor.errors.get(0); |
| assertEquals("userName", error.getAbsolutePath()); |
| assertSame(editor.userName, error.getEditor()); |
| assertTrue(error.getMessage().length() > 0); |
| assertEquals("userName", error.getPath()); |
| assertSame(v, error.getUserData()); |
| assertNull(error.getValue()); |
| finishTestAndReset(); |
| } |
| }); |
| // Set to an illegal value |
| editor.userName.setValue(""); |
| |
| driver.flush().fire(); |
| } |
| }); |
| } |
| } |