/* * Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. * * 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 org.jboss.errai.ui.nav.client.local; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import org.jboss.errai.enterprise.client.cdi.AbstractErraiCDITest; import org.jboss.errai.ioc.client.container.IOC; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.jboss.errai.ioc.client.lifecycle.api.LifecycleEvent; import org.jboss.errai.ioc.client.lifecycle.api.LifecycleListener; import org.jboss.errai.ioc.client.lifecycle.api.StateChange; import org.jboss.errai.ui.nav.client.local.testpages.PageWithExtraState; import org.jboss.errai.ui.nav.client.local.testpages.PageWithInheritedState; import org.jboss.errai.ui.nav.client.local.testpages.PageWithRenamedStateFields; import com.google.common.collect.ImmutableMultimap; public class PageStateTest extends AbstractErraiCDITest { private final SyncBeanManager beanManager = IOC.getBeanManager(); private Navigation navigation; @Override public String getModuleName() { return "org.jboss.errai.ui.nav.NavigationTest"; } @Override protected void gwtSetUp() throws Exception { disableBus = true; super.gwtSetUp(); navigation = beanManager.lookupBean(Navigation.class).getInstance(); } private static void assertAllFieldsHaveDefaultValues(PageWithExtraState page) { assertNull(page.getStringThing()); assertEquals((byte) 0, page.getByteThing()); assertEquals((short) 0, page.getShortThing()); assertEquals(0, page.getIntThing()); assertEquals(0L, page.getLongThing()); assertEquals(0f, page.getFloatThing(), 0f); assertEquals(0.0, page.getDoubleThing(), 0.0); assertEquals(false, page.getBoolThing()); assertNull(page.getBoxedByteThing()); assertNull(page.getBoxedShortThing()); assertNull(page.getBoxedIntThing()); assertNull(page.getBoxedLongThing()); assertNull(page.getBoxedFloatThing()); assertNull(page.getBoxedDoubleThing()); assertNull(page.getBoxedBoolThing()); assertNotNull(page.getStringCollection()); assertNotNull(page.getStringList()); assertNotNull(page.getStringSet()); assertNotNull(page.getIntList()); assertTrue(page.getStringCollection().isEmpty()); assertTrue(page.getStringList().isEmpty()); assertTrue(page.getStringSet().isEmpty()); assertTrue(page.getIntList().isEmpty()); } /** * If a {@code @PageState} field has no corresponding parameter in the history * token, its value should be set to default (0 or null) when we call * putState(). */ public void testAbsentParameterGivesDefault() throws Exception { PageWithExtraState page = beanManager.lookupBean(PageWithExtraState.class).getInstance(); // force fields back to defaults before we start navigation.goTo(PageWithExtraState.class, ImmutableMultimap.<String,String>of()); assertAllFieldsHaveDefaultValues(page); navigation.goTo(PageWithExtraState.class, ImmutableMultimap.<String,String>builder() .put("stringThing", "string") .put("byteThing", "12") .put("shortThing", "123") .put("intThing", "1234") .put("longThing", "12345") .put("floatThing", "1.2") .put("doubleThing", "1.23") .put("boolThing", "true") .put("boxedByteThing", "12") .put("boxedShortThing", "123") .put("boxedIntThing", "1234") .put("boxedLongThing", "12345") .put("boxedFloatThing", "1.2") .put("boxedDoubleThing", "1.23") .put("boxedBoolThing", "true") .put("stringList", "0") .put("stringList", "1") .put("stringList", "0") .put("stringSet", "0") .put("stringSet", "1") .put("stringSet", "0") .put("stringCollection", "0") .put("stringCollection", "1") .put("stringCollection", "0") .put("intList", "0") .put("intList", "1") .put("intList", "0") .build()); navigation.goTo(PageWithExtraState.class, ImmutableMultimap.<String,String>of()); // this is the point of the test: the empty goTo() should have reset all state fields assertAllFieldsHaveDefaultValues(page); } public void testPassAllStateTokens() throws Exception { PageWithExtraState page = beanManager.lookupBean(PageWithExtraState.class).getInstance(); // force fields back to defaults before we start navigation.goTo(PageWithExtraState.class, ImmutableMultimap.<String,String>of()); assertAllFieldsHaveDefaultValues(page); ImmutableMultimap<String, String> stateValues = ImmutableMultimap.<String,String>builder() .put("stringThing", "string") .put("byteThing", "12") .put("shortThing", "123") .put("intThing", "1234") .put("longThing", "12345") .put("floatThing", "1.2") .put("doubleThing", "1.23") .put("boolThing", "true") .put("boxedByteThing", "12") .put("boxedShortThing", "123") .put("boxedIntThing", "1234") .put("boxedLongThing", "12345") .put("boxedFloatThing", "1.2") .put("boxedDoubleThing", "1.23") .put("boxedBoolThing", "true") .put("stringList", "0") .put("stringList", "1") .put("stringList", "0") .put("stringSet", "0") .put("stringSet", "1") .put("stringSet", "0") .put("stringCollection", "0") .put("stringCollection", "1") .put("stringCollection", "0") .put("intList", "0") .put("intList", "1") .put("intList", "0") .build(); navigation.goTo(PageWithExtraState.class, stateValues); // ensure all values were set on the page object assertEquals("string", page.getStringThing()); assertEquals((byte) 12, page.getByteThing()); assertEquals((short) 123, page.getShortThing()); assertEquals(1234, page.getIntThing()); assertEquals(12345L, page.getLongThing()); assertEquals(1.2f, page.getFloatThing(), 0.0001f); assertEquals(1.23, page.getDoubleThing(), 0.0001); assertEquals(true, page.getBoolThing()); assertEquals(Byte.valueOf("12"), page.getBoxedByteThing()); assertEquals(Short.valueOf("123"), page.getBoxedShortThing()); assertEquals(Integer.valueOf("1234"), page.getBoxedIntThing()); assertEquals(Long.valueOf("12345"), page.getBoxedLongThing()); assertEquals(Float.valueOf("1.2"), page.getBoxedFloatThing(), 0f); assertEquals(Double.valueOf("1.23"), page.getBoxedDoubleThing(), 0.0); assertEquals(Boolean.TRUE, page.getBoxedBoolThing()); assertEquals(Arrays.asList("0", "1", "0"), page.getStringList()); assertEquals(Arrays.asList("0", "1", "0"), page.getStringCollection()); assertEquals(new HashSet<String>(Arrays.asList("0", "1", "0")), page.getStringSet()); assertEquals(Arrays.asList(0, 1, 0), page.getIntList()); } public void testSettingPageStateTriggersIOCLifecycleEvent() throws Exception { final PageWithExtraState page = beanManager.lookupBean(PageWithExtraState.class).getInstance(); // force fields back to defaults before we start navigation.goTo(PageWithExtraState.class, ImmutableMultimap.<String,String>of()); assertAllFieldsHaveDefaultValues(page); // register an IOC lifecycle listener that should be invoked when the state of the managed bean changes final List<LifecycleEvent<PageWithExtraState>> observedEvents = new ArrayList<LifecycleEvent<PageWithExtraState>>(); LifecycleListener<PageWithExtraState> lifecycleListener = new LifecycleListener<PageWithExtraState>() { @Override public void observeEvent(LifecycleEvent<PageWithExtraState> event) { assertEquals("string", page.getStringThing()); observedEvents.add(event); } @Override public boolean isObserveableEventType(Class<? extends LifecycleEvent<PageWithExtraState>> eventType) { return eventType.equals(StateChange.class); } }; IOC.registerLifecycleListener(page, lifecycleListener); assertTrue(observedEvents.isEmpty()); ImmutableMultimap<String, String> stateValues = ImmutableMultimap.<String,String>builder() .put("stringThing", "string") .build(); navigation.goTo(PageWithExtraState.class, stateValues); assertEquals(1, observedEvents.size()); } public void testInheritedStateFieldsAreWritten() throws Exception { PageWithInheritedState page = beanManager.lookupBean(PageWithInheritedState.class).getInstance(); assertNull(page.getMyState()); navigation.goTo(PageWithInheritedState.class, ImmutableMultimap.of("inheritedState", "inherit this!")); assertEquals("inherit this!", page.getMyState()); } /** * If there are multiple values for the same key, but the corresponding * {@code @PageState} field in the page is not a collection, the field should * get the <i>first</i> value for its key. */ public void testScalarGetsFirstValueInToken() throws Exception { PageWithExtraState page = beanManager.lookupBean(PageWithExtraState.class).getInstance(); // force fields back to defaults before we start navigation.goTo(PageWithExtraState.class, ImmutableMultimap.<String,String>of()); assertNull(page.getStringThing()); navigation.goTo(PageWithExtraState.class, ImmutableMultimap.of( "nonexistent", "====", "stringThing", "string0", "stringThing", "string1", "stringThing", "string2")); assertEquals("string0", page.getStringThing()); } public void testFieldWithGivenName() throws Exception { PageWithRenamedStateFields page = beanManager.lookupBean(PageWithRenamedStateFields.class).getInstance(); assertNull(page.getField()); navigation.goTo(PageWithRenamedStateFields.class, ImmutableMultimap.of("givenName", "value")); assertEquals("value", page.getField()); // and ensure the field doesn't respond to its real name navigation.goTo(PageWithRenamedStateFields.class, ImmutableMultimap.of("field", "value")); assertNull(page.getField()); } }