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.Collection;
import java.util.Set;
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.collect.Lists;
import fr.openwide.core.test.wicket.more.business.person.model.Person;
import fr.openwide.core.test.wicket.more.business.person.service.IPersonService;
public abstract class AbstractTestGenericEntityCollectionModel<C extends Collection<Person>>
extends AbstractTestCollectionModel<C> {
protected static final Equivalence<Set<?>> ORDERED_SET_EQUIVALENCE = new Equivalence<Set<?>>() {
@Override
protected boolean doEquivalent(Set<?> a, Set<?> b) {
return Lists.newArrayList(a).equals(Lists.newArrayList(b)); // SortedSet.equals won't work on cloned transient instances
}
@Override
protected int doHash(Set<?> t) {
return Lists.newArrayList(t).hashCode();
}
@Override
public String toString() {
return "ORDERED_SET_EQUIVALENCE";
}
};
@Autowired
private IPersonService personService;
@PersistenceContext
private EntityManager entityManager;
public AbstractTestGenericEntityCollectionModel(Equivalence<? super C> equivalence) {
super(equivalence);
}
protected abstract IModel<C> createModel();
protected abstract C createCollection(Person ... person);
protected abstract C clone(C collection);
@Test
public void testNotAttached() {
IModel<C> model = createModel();
assertThat(model.getObject(), isEmpty());
model = serializeAndDeserialize(model);
assertThat(model.getObject(), isEmpty());
}
@Test
public void testAttachedNull() {
IModel<C> 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");
C collection = createCollection(person1, person2);
IModel<C> model = createModel();
model.setObject(clone(collection));
assertThat(model.getObject(), isEquivalent(collection));
model = serializeAndDeserialize(model);
C modelObject = model.getObject();
assertNotNull(modelObject);
assertEquals(collection.size(), modelObject.size());
assertThat(modelObject, not(isEquivalent(collection)));
}
@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());
C collection = createCollection(person1, person2);
IModel<C> model = createModel();
model.setObject(clone(collection));
assertThat(model.getObject(), isEquivalent(collection));
for (Person p : model.getObject()) {
assertThat(p, isAttachedToSession());
}
model = serializeAndDeserialize(model);
C modelObject = model.getObject();
assertThat(modelObject, isEquivalent(collection));
for (Person p : modelObject) {
assertThat(p, isAttachedToSession());
}
}
@Test
public void testAttachedWhenTransientAndDetachedWhenPersisted() throws Exception {
Person person1 = new Person("John", "Doe");
Person person2 = new Person("John2", "Doe2");
C collection = createCollection(person1, person2);
IModel<C> model = createModel();
model.setObject(clone(collection));
assertThat(model.getObject(), isEquivalent(collection));
personService.create(person1);
assertThat(person1, isAttachedToSession());
personService.create(person2);
assertThat(person2, isAttachedToSession());
for (Person p : model.getObject()) {
assertThat(p, isAttachedToSession());
}
model = serializeAndDeserialize(model);
C modelObject = model.getObject();
assertThat(modelObject, isEquivalent(collection));
for (Person p : 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());
C collection = createCollection(person1, person2);
IModel<C> model = createModel();
model.setObject(clone(collection));
assertThat(model.getObject(), isEquivalent(collection));
for (Person p : model.getObject()) {
assertThat(p, isAttachedToSession());
}
personService.delete(person1);
model = serializeAndDeserialize(model);
C modelObject = model.getObject();
C expected = createCollection(null, person2);
assertThat(modelObject, isEquivalent(expected));
}
@Test
public void testCollectionCopy() throws Exception {
Person person1 = new Person("John", "Doe");
Person person2 = new Person("John2", "Doe2");
personService.create(person1);
assertThat(person1, isAttachedToSession());
C collection = createCollection(person1, person2);
IModel<C> model = createModel();
C collectionSetOnModel = clone(collection);
model.setObject(collectionSetOnModel);
assertThat(model.getObject(), isEquivalent(collection));
Person person3 = new Person("John3", "Doe3");
collectionSetOnModel.add(person3);
assertThat(model.getObject(), isEquivalent(collection));
}
@Test
public void testDetachedWhenTransientThenDetachedWhenPersisted() throws Exception {
Person person1 = new Person("John", "Doe");
Person person2 = new Person("John2", "Doe2");
C collection = createCollection(person1, person2);
IModel<C> model = createModel();
model.setObject(clone(collection));
assertThat(model.getObject(), isEquivalent(collection));
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()
C modelObject = model.getObject();
assertThat(modelObject, isEquivalent(collection));
for (Person p : modelObject) {
assertThat(p, isAttachedToSession());
}
}
@Test
public void testCollectionGetObjectAdd() throws Exception {
Person person1 = new Person("John", "Doe");
Person person2 = new Person("John2", "Doe2");
personService.create(person1);
assertThat(person1, isAttachedToSession());
IModel<C> model = createModel();
C collectionSetOnModel = createCollection(person1, person2);
model.setObject(collectionSetOnModel);
C modelObject = model.getObject();
Person person3 = new Person("John3", "Doe3");
modelObject.add(person3);
assertThat(model.getObject(), isEquivalent(createCollection(person1, person2, person3)));
model = serializeAndDeserialize(model);
modelObject = model.getObject();
assertNotNull(modelObject);
assertEquals(3, modelObject.size());
}
@Test
public void testCollectionGetObjectRemove() throws Exception {
Person person1 = new Person("John", "Doe");
Person person2 = new Person("John2", "Doe2");
personService.create(person1);
assertThat(person1, isAttachedToSession());
IModel<C> model = createModel();
C collectionSetOnModel = createCollection(person1, person2);
model.setObject(collectionSetOnModel);
C modelObject = model.getObject();
modelObject.remove(person2);
assertThat(model.getObject(), isEquivalent(createCollection(person1)));
model = serializeAndDeserialize(model);
modelObject = model.getObject();
assertNotNull(modelObject);
assertEquals(1, modelObject.size());
assertThat(modelObject, isEquivalent(createCollection(person1)));
}
}