package fr.openwide.core.test.wicket.more.model; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import java.util.Map; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.apache.wicket.model.IModel; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import com.google.common.base.Equivalence; import com.google.common.base.Supplier; import com.google.common.collect.Lists; import fr.openwide.core.test.wicket.more.business.person.model.Person; import fr.openwide.core.test.wicket.more.business.person.service.IPersonService; import fr.openwide.core.wicket.more.markup.repeater.map.IMapModel; public abstract class AbstractTestGenericEntityMapCopyModel<K, V, M extends Map<K, V>> extends AbstractTestMapModel<M> { protected static final Equivalence<Map<?, ?>> ORDERED_MAP_EQUIVALENCE = new Equivalence<Map<?, ?>>() { @Override protected boolean doEquivalent(Map<?, ?> a, Map<?, ?> b) { return Lists.newArrayList(a.entrySet()).equals(Lists.newArrayList(b.entrySet())); // SortedMap.equals won't work on cloned transient instances } @Override protected int doHash(Map<?, ?> t) { return Lists.newArrayList(t.entrySet()).hashCode(); } @Override public String toString() { return "ORDERED_MAP_EQUIVALENCE"; } }; @Autowired protected IPersonService personService; @PersistenceContext protected EntityManager entityManager; public AbstractTestGenericEntityMapCopyModel(Supplier<? extends M> mapSupplier, Equivalence<? super M> equivalence) { super(mapSupplier, equivalence); } protected abstract IMapModel<K, V, M> createModel(); protected abstract M createMap(Person... persons); protected abstract Iterable<Person> personIterable(M map); @Test public void testNotAttached() { IModel<M> model = createModel(); assertThat(model.getObject(), isEmpty()); model = serializeAndDeserialize(model); assertThat(model.getObject(), isEmpty()); } @Test public void testAttachedNull() { IModel<M> model = createModel(); model.setObject(null); assertThat(model.getObject(), isEmpty()); model = serializeAndDeserialize(model); assertThat(model.getObject(), isEmpty()); } @Test public void testAttachedWhenTransient() { Person person1 = new Person("John", "Doe"); Person person2 = new Person("John2", "Doe2"); M map = createMap(person1, person2); IModel<M> model = createModel(); model.setObject(clone(map)); assertThat(model.getObject(), isEquivalent(map)); model = serializeAndDeserialize(model); M modelObject = model.getObject(); assertNotNull(modelObject); assertEquals(map.size(), modelObject.size()); assertThat(modelObject, not(isEquivalent(map))); } @Test public void testAttachedWhenPersisted() throws Exception { Person person1 = new Person("John", "Doe"); Person person2 = new Person("John2", "Doe2"); personService.create(person1); assertThat(person1, isAttachedToSession()); personService.create(person2); assertThat(person2, isAttachedToSession()); M map = createMap(person1, person2); IModel<M> model = createModel(); model.setObject(clone(map)); assertThat(model.getObject(), isEquivalent(map)); for (Person p : personIterable(model.getObject())) { assertThat(p, isAttachedToSession()); } model = serializeAndDeserialize(model); M modelObject = model.getObject(); assertThat(modelObject, isEquivalent(map)); for (Person p : personIterable(modelObject)) { assertThat(p, isAttachedToSession()); } } @Test public void testAttachedWhenTransientAndDetachedWhenPersisted() throws Exception { Person person1 = new Person("John", "Doe"); Person person2 = new Person("John2", "Doe2"); M map = createMap(person1, person2); IModel<M> model = createModel(); model.setObject(clone(map)); assertThat(model.getObject(), isEquivalent(map)); personService.create(person1); assertThat(person1, isAttachedToSession()); personService.create(person2); assertThat(person2, isAttachedToSession()); for (Person p : personIterable(model.getObject())) { assertThat(p, isAttachedToSession()); } model = serializeAndDeserialize(model); M modelObject = model.getObject(); assertThat(modelObject, isEquivalent(map)); for (Person p : personIterable(modelObject)) { assertThat(p, isAttachedToSession()); } } @Test public void testAttachedWhenPersistedAndDetachedWhenTransient() throws Exception { Person person1 = new Person("John", "Doe"); Person person2 = new Person("John2", "Doe2"); personService.create(person1); assertThat(person1, isAttachedToSession()); personService.create(person2); assertThat(person2, isAttachedToSession()); M map = createMap(person1, person2); IModel<M> model = createModel(); model.setObject(clone(map)); assertThat(model.getObject(), isEquivalent(map)); for (Person p : personIterable(model.getObject())) { assertThat(p, isAttachedToSession()); } personService.delete(person1); model = serializeAndDeserialize(model); M modelObject = model.getObject(); M expected = createMap(null, person2); assertThat(modelObject, isEquivalent(expected)); } @Test public void testDetachedWhenTransientThenDetachedWhenPersisted() throws Exception { Person person1 = new Person("John", "Doe"); Person person2 = new Person("John2", "Doe2"); M map = createMap(person1, person2); IModel<M> model = createModel(); model.setObject(clone(map)); assertThat(model.getObject(), isEquivalent(map)); personService.create(person1); assertThat(person1, isAttachedToSession()); model.detach(); // First detach() // Simulate work on the same object obtained from another model personService.create(person2); assertThat(person2, isAttachedToSession()); model = serializeAndDeserialize(model); // Includes a second detach() M modelObject = model.getObject(); assertThat(modelObject, isEquivalent(map)); for (Person p : personIterable(modelObject)) { assertThat(p, isAttachedToSession()); } } }