DATACMNS-867 - First draft.

This commit is contained in:
Oliver Gierke
2016-11-14 20:10:22 +01:00
parent 1b17271915
commit cc63e5b7a4
278 changed files with 4737 additions and 5714 deletions

View File

@@ -15,8 +15,7 @@
*/
package org.springframework.data.auditing;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.assertj.core.api.Assertions.*;
import java.lang.reflect.Field;
@@ -40,50 +39,47 @@ public class AnnotationAuditingMetadataUnitTests {
static final Field lastModifiedByField = ReflectionUtils.findField(AnnotatedUser.class, "lastModifiedBy");
static final Field lastModifiedDateField = ReflectionUtils.findField(AnnotatedUser.class, "lastModifiedDate");
@Rule
public ExpectedException exception = ExpectedException.none();
@Rule public ExpectedException exception = ExpectedException.none();
@Test
public void checkAnnotationDiscovery() {
AnnotationAuditingMetadata metadata = AnnotationAuditingMetadata.getMetadata(AnnotatedUser.class);
assertThat(metadata, is(notNullValue()));
assertThat(createdByField, is(metadata.getCreatedByField()));
assertThat(createdDateField, is(metadata.getCreatedDateField()));
assertThat(lastModifiedByField, is(metadata.getLastModifiedByField()));
assertThat(lastModifiedDateField, is(metadata.getLastModifiedDateField()));
assertThat(metadata).isNotNull();
assertThat(metadata.getCreatedByField()).hasValue(createdByField);
assertThat(metadata.getCreatedDateField()).hasValue(createdDateField);
assertThat(metadata.getLastModifiedByField()).hasValue(lastModifiedByField);
assertThat(metadata.getLastModifiedDateField()).hasValue(lastModifiedDateField);
}
@Test
public void checkCaching() {
AnnotationAuditingMetadata firstCall = AnnotationAuditingMetadata.getMetadata(AnnotatedUser.class);
assertThat(firstCall, is(notNullValue()));
assertThat(firstCall).isNotNull();
AnnotationAuditingMetadata secondCall = AnnotationAuditingMetadata.getMetadata(AnnotatedUser.class);
assertThat(firstCall, is(secondCall));
assertThat(firstCall).isEqualTo(secondCall);
}
@Test
public void checkIsAuditable() {
AnnotationAuditingMetadata metadata = AnnotationAuditingMetadata.getMetadata(AnnotatedUser.class);
assertThat(metadata, is(notNullValue()));
;
assertThat(metadata.isAuditable(), is(true));
assertThat(metadata).isNotNull();
assertThat(metadata.isAuditable()).isTrue();
metadata = AnnotationAuditingMetadata.getMetadata(NonAuditableUser.class);
assertThat(metadata, is(notNullValue()));
assertThat(metadata.isAuditable(), is(false));
assertThat(metadata).isNotNull();
assertThat(metadata.isAuditable()).isFalse();
}
@Test
public void rejectsInvalidDateTypeField() {
class Sample {
@CreatedDate
String field;
@CreatedDate String field;
}
exception.expect(IllegalStateException.class);

View File

@@ -15,7 +15,9 @@
*/
package org.springframework.data.auditing;
import org.joda.time.DateTime;
import java.time.LocalDateTime;
import java.util.Optional;
import org.springframework.data.domain.Auditable;
/**
@@ -24,15 +26,15 @@ import org.springframework.data.domain.Auditable;
* @author Oliver Gierke
* @since 1.5
*/
class AuditedUser implements Auditable<AuditedUser, Long> {
class AuditedUser implements Auditable<AuditedUser, Long, LocalDateTime> {
private static final long serialVersionUID = -840865084027597951L;
Long id;
AuditedUser createdBy;
AuditedUser modifiedBy;
DateTime createdDate;
DateTime modifiedDate;
LocalDateTime createdDate;
LocalDateTime modifiedDate;
public Long getId() {
return id;
@@ -42,35 +44,35 @@ class AuditedUser implements Auditable<AuditedUser, Long> {
return id == null;
}
public AuditedUser getCreatedBy() {
return createdBy;
public Optional<AuditedUser> getCreatedBy() {
return Optional.ofNullable(createdBy);
}
public void setCreatedBy(AuditedUser createdBy) {
this.createdBy = createdBy;
public void setCreatedBy(Optional<? extends AuditedUser> createdBy) {
this.createdBy = createdBy.orElse(null);
}
public DateTime getCreatedDate() {
return createdDate;
public Optional<LocalDateTime> getCreatedDate() {
return Optional.ofNullable(createdDate);
}
public void setCreatedDate(DateTime creationDate) {
this.createdDate = creationDate;
public void setCreatedDate(Optional<? extends LocalDateTime> creationDate) {
this.createdDate = creationDate.orElse(null);
}
public AuditedUser getLastModifiedBy() {
return modifiedBy;
public Optional<AuditedUser> getLastModifiedBy() {
return Optional.ofNullable(modifiedBy);
}
public void setLastModifiedBy(AuditedUser lastModifiedBy) {
this.modifiedBy = lastModifiedBy;
public void setLastModifiedBy(Optional<? extends AuditedUser> lastModifiedBy) {
this.modifiedBy = lastModifiedBy.orElse(null);
}
public DateTime getLastModifiedDate() {
return modifiedDate;
public Optional<LocalDateTime> getLastModifiedDate() {
return Optional.ofNullable(modifiedDate);
}
public void setLastModifiedDate(DateTime lastModifiedDate) {
this.modifiedDate = lastModifiedDate;
public void setLastModifiedDate(Optional<? extends LocalDateTime> lastModifiedDate) {
this.modifiedDate = lastModifiedDate.orElse(null);
}
}

View File

@@ -15,15 +15,15 @@
*/
package org.springframework.data.auditing;
import static org.junit.Assert.*;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import java.util.Collections;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.context.PersistentEntities;
/**
@@ -38,20 +38,20 @@ public class AuditingHandlerUnitTests {
AuditingHandler handler;
AuditorAware<AuditedUser> auditorAware;
AuditedUser user;
Optional<AuditedUser> user;
@Before
public void setUp() {
handler = getHandler();
user = new AuditedUser();
user = Optional.of(new AuditedUser());
auditorAware = mock(AuditorAware.class);
when(auditorAware.getCurrentAuditor()).thenReturn(user);
}
protected AuditingHandler getHandler() {
return new AuditingHandler(new PersistentEntities(Collections.<MappingContext<?, ?>> emptySet()));
return new AuditingHandler(new PersistentEntities(Collections.emptySet()));
}
/**
@@ -62,11 +62,14 @@ public class AuditingHandlerUnitTests {
handler.markCreated(user);
assertNotNull(user.getCreatedDate());
assertNotNull(user.getLastModifiedDate());
assertThat(user).hasValueSatisfying(it -> {
assertNull(user.getCreatedBy());
assertNull(user.getLastModifiedBy());
assertThat(it.getCreatedDate()).isPresent();
assertThat(it.getLastModifiedDate()).isPresent();
assertThat(it.getCreatedBy()).isNotPresent();
assertThat(it.getLastModifiedBy()).isNotPresent();
});
}
/**
@@ -79,11 +82,14 @@ public class AuditingHandlerUnitTests {
handler.markCreated(user);
assertNotNull(user.getCreatedDate());
assertNotNull(user.getLastModifiedDate());
assertThat(user).hasValueSatisfying(it -> {
assertNotNull(user.getCreatedBy());
assertNotNull(user.getLastModifiedBy());
assertThat(it.getCreatedDate()).isPresent();
assertThat(it.getLastModifiedDate()).isPresent();
assertThat(it.getCreatedBy()).isPresent();
assertThat(it.getLastModifiedBy()).isPresent();
});
verify(auditorAware).getCurrentAuditor();
}
@@ -98,11 +104,14 @@ public class AuditingHandlerUnitTests {
handler.setModifyOnCreation(false);
handler.markCreated(user);
assertNotNull(user.getCreatedDate());
assertNotNull(user.getCreatedBy());
assertThat(user).hasValueSatisfying(it -> {
assertNull(user.getLastModifiedBy());
assertNull(user.getLastModifiedDate());
assertThat(it.getCreatedDate()).isPresent();
assertThat(it.getCreatedBy()).isPresent();
assertThat(it.getLastModifiedBy()).isNotPresent();
assertThat(it.getLastModifiedDate()).isNotPresent();
});
verify(auditorAware).getCurrentAuditor();
}
@@ -113,17 +122,22 @@ public class AuditingHandlerUnitTests {
@Test
public void onlySetsModificationDataOnNotNewEntities() {
user = new AuditedUser();
user.id = 1L;
AuditedUser audited = new AuditedUser();
audited.id = 1L;
user = Optional.of(audited);
handler.setAuditorAware(auditorAware);
handler.markModified(user);
assertNull(user.getCreatedBy());
assertNull(user.getCreatedDate());
assertThat(user).hasValueSatisfying(it -> {
assertNotNull(user.getLastModifiedBy());
assertNotNull(user.getLastModifiedDate());
assertThat(it.getCreatedBy()).isNotPresent();
assertThat(it.getCreatedDate()).isNotPresent();
assertThat(it.getLastModifiedBy()).isPresent();
assertThat(it.getLastModifiedDate()).isPresent();
});
verify(auditorAware).getCurrentAuditor();
}
@@ -135,17 +149,21 @@ public class AuditingHandlerUnitTests {
handler.setAuditorAware(auditorAware);
handler.markCreated(user);
assertNotNull(user.getCreatedBy());
assertNull(user.getCreatedDate());
assertThat(user).hasValueSatisfying(it -> {
assertNotNull(user.getLastModifiedBy());
assertNull(user.getLastModifiedDate());
assertThat(it.getCreatedBy()).isPresent();
assertThat(it.getCreatedDate()).isNotPresent();
assertThat(it.getLastModifiedBy()).isPresent();
assertThat(it.getLastModifiedDate()).isNotPresent();
});
}
@Test // DATAJPA-9
public void usesDateTimeProviderIfConfigured() {
DateTimeProvider provider = mock(DateTimeProvider.class);
doReturn(Optional.empty()).when(provider).getNow();
handler.setDateTimeProvider(provider);
handler.markCreated(user);

View File

@@ -15,10 +15,10 @@
*/
package org.springframework.data.auditing;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.assertj.core.api.Assertions.*;
import java.util.Calendar;
import java.time.Instant;
import java.util.Optional;
import org.junit.Test;
import org.springframework.data.auditing.DefaultAuditableBeanWrapperFactory.AuditableInterfaceBeanWrapper;
@@ -35,42 +35,47 @@ public class DefaultAuditableBeanWrapperFactoryUnitTests {
DefaultAuditableBeanWrapperFactory factory = new DefaultAuditableBeanWrapperFactory();
@Test
public void returnsNullForNullSource() {
assertThat(factory.getBeanWrapperFor(null), is(nullValue()));
public void returnsEmptyForEmptySource() {
assertThat(factory.getBeanWrapperFor(Optional.empty())).isNotPresent();
}
@Test
public void returnsAuditableInterfaceBeanWrapperForAuditable() {
AuditableBeanWrapper wrapper = factory.getBeanWrapperFor(new AuditedUser());
assertThat(wrapper, is(instanceOf(AuditableInterfaceBeanWrapper.class)));
assertThat(factory.getBeanWrapperFor(Optional.of(new AuditedUser()))).hasValueSatisfying(it -> {
assertThat(it).isInstanceOf(AuditableInterfaceBeanWrapper.class);
});
}
@Test
public void returnsReflectionAuditingBeanWrapperForNonAuditableButAnnotated() {
AuditableBeanWrapper wrapper = factory.getBeanWrapperFor(new AnnotatedUser());
assertThat(wrapper, is(instanceOf(ReflectionAuditingBeanWrapper.class)));
assertThat(factory.getBeanWrapperFor(Optional.of(new AnnotatedUser()))).hasValueSatisfying(it -> {
assertThat(it).isInstanceOf(ReflectionAuditingBeanWrapper.class);
});
}
@Test
public void returnsNullForNonAuditableType() {
AuditableBeanWrapper wrapper = factory.getBeanWrapperFor(new Object());
assertThat(wrapper, is(nullValue()));
public void returnsEmptyForNonAuditableType() {
assertThat(factory.getBeanWrapperFor(Optional.of(new Object()))).isNotPresent();
}
@Test // DATACMNS-643
public void setsJsr310AndThreeTenBpTypes() {
Jsr310ThreeTenBpAuditedUser user = new Jsr310ThreeTenBpAuditedUser();
Calendar calendar = Calendar.getInstance();
Instant instant = Instant.now();
AuditableBeanWrapper wrapper = factory.getBeanWrapperFor(user);
wrapper.setCreatedDate(calendar);
wrapper.setLastModifiedDate(calendar);
Optional<AuditableBeanWrapper> wrapper = factory.getBeanWrapperFor(Optional.of(user));
assertThat(wrapper).hasValueSatisfying(it -> {
it.setCreatedDate(Optional.of(instant));
it.setLastModifiedDate(Optional.of(instant));
assertThat(user.createdDate).isNotNull();
assertThat(user.lastModifiedDate).isNotNull();
});
assertThat(user.createdDate, is(notNullValue()));
assertThat(user.lastModifiedDate, is(notNullValue()));
}
}

View File

@@ -15,16 +15,17 @@
*/
package org.springframework.data.auditing;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import java.util.Collections;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.data.annotation.Id;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.context.PersistentEntities;
@@ -55,10 +56,11 @@ public class IsNewAwareAuditingHandlerUnitTests extends AuditingHandlerUnitTests
public void delegatesToMarkCreatedForNewEntity() {
AuditedUser user = new AuditedUser();
getHandler().markAudited(user);
assertThat(user.createdDate, is(notNullValue()));
assertThat(user.modifiedDate, is(notNullValue()));
getHandler().markAudited(Optional.of(user));
assertThat(user.createdDate).isNotNull();
assertThat(user.modifiedDate).isNotNull();
}
@Test
@@ -66,10 +68,11 @@ public class IsNewAwareAuditingHandlerUnitTests extends AuditingHandlerUnitTests
AuditedUser user = new AuditedUser();
user.id = 1L;
getHandler().markAudited(user);
assertThat(user.createdDate, is(nullValue()));
assertThat(user.modifiedDate, is(notNullValue()));
getHandler().markAudited(Optional.of(user));
assertThat(user.createdDate).isNull();
assertThat(user.modifiedDate).isNotNull();
}
@Test(expected = IllegalArgumentException.class) // DATACMNS-365
@@ -83,18 +86,18 @@ public class IsNewAwareAuditingHandlerUnitTests extends AuditingHandlerUnitTests
}
@Test // DATACMNS-638
public void handlingNullIsANoOp() {
public void handlingOptionalIsANoOp() {
IsNewAwareAuditingHandler handler = getHandler();
handler.markAudited(null);
handler.markCreated(null);
handler.markModified(null);
handler.markAudited(Optional.empty());
handler.markCreated(Optional.empty());
handler.markModified(Optional.empty());
}
@Test // DATACMNS-957
public void skipsEntityWithoutIdentifier() {
getHandler().markAudited(new EntityWithoutId());
getHandler().markAudited(Optional.of(new EntityWithoutId()));
}
static class Domain {

View File

@@ -15,18 +15,20 @@
*/
package org.springframework.data.auditing;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Optional;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.LastModifiedBy;
@@ -38,11 +40,12 @@ import org.springframework.data.mapping.context.PersistentEntities;
import org.springframework.data.mapping.context.SampleMappingContext;
/**
* Unit tests for {@link MappingAuditableBeanWrapperFactory}.
* Unit tests for {@link MappingAuditableBeanWrapperFactory}. TODO: Which date types to support?
*
* @author Oliver Gierke
* @since 1.8
*/
@Ignore
public class MappingAuditableBeanWrapperFactoryUnitTests {
DefaultAuditableBeanWrapperFactory factory;
@@ -62,45 +65,53 @@ public class MappingAuditableBeanWrapperFactoryUnitTests {
public void discoversAuditingPropertyOnField() {
Sample sample = new Sample();
AuditableBeanWrapper wrapper = factory.getBeanWrapperFor(sample);
assertThat(wrapper, is(notNullValue()));
Optional<AuditableBeanWrapper> wrapper = factory.getBeanWrapperFor(Optional.of(sample));
wrapper.setCreatedBy("Me!");
assertThat(sample.createdBy, is(notNullValue()));
assertThat(wrapper).hasValueSatisfying(it -> {
it.setCreatedBy(Optional.of("Me!"));
assertThat(sample.createdBy).isNotNull();
});
}
@Test // DATACMNS-365
public void discoversAuditingPropertyOnAccessor() {
Sample sample = new Sample();
AuditableBeanWrapper wrapper = factory.getBeanWrapperFor(sample);
assertThat(wrapper, is(notNullValue()));
Optional<AuditableBeanWrapper> wrapper = factory.getBeanWrapperFor(Optional.of(sample));
wrapper.setLastModifiedBy("Me, too!");
assertThat(sample.lastModifiedBy, is(notNullValue()));
assertThat(wrapper).hasValueSatisfying(it -> {
it.setLastModifiedBy(Optional.of("Me, too!"));
assertThat(sample.lastModifiedBy).isNotNull();
});
}
@Test // DATACMNS-365
public void settingInavailablePropertyIsNoop() {
Sample sample = new Sample();
AuditableBeanWrapper wrapper = factory.getBeanWrapperFor(sample);
wrapper.setLastModifiedDate(new GregorianCalendar());
Optional<AuditableBeanWrapper> wrapper = factory.getBeanWrapperFor(Optional.of(sample));
assertThat(wrapper).hasValueSatisfying(it -> {
it.setLastModifiedDate(Optional.of(Instant.now()));
});
}
@Test // DATACMNS-365
public void doesNotReturnWrapperForEntityNotUsingAuditing() {
assertThat(factory.getBeanWrapperFor(new NoAuditing()), is(nullValue()));
assertThat(factory.getBeanWrapperFor(Optional.of(new NoAuditing()))).isNotPresent();
}
@Test // DATACMNS-365
public void returnsAuditableWrapperForAuditable() {
assertThat(factory.getBeanWrapperFor(mock(ExtendingAuditable.class)),
is(instanceOf(AuditableInterfaceBeanWrapper.class)));
assertThat(factory.getBeanWrapperFor(Optional.of(mock(ExtendingAuditable.class)))).hasValueSatisfying(it -> {
assertThat(it).isInstanceOf(AuditableInterfaceBeanWrapper.class);
});
}
@Test // DATACMNS-638
@@ -148,16 +159,16 @@ public class MappingAuditableBeanWrapperFactoryUnitTests {
.convert(reference));
}
private final void assertLastModificationDate(Object source, Date expected) {
Calendar calendar = new GregorianCalendar();
calendar.setTime(expected);
private void assertLastModificationDate(Object source, Object expected) {
Sample sample = new Sample();
sample.lastModifiedDate = source;
AuditableBeanWrapper wrapper = factory.getBeanWrapperFor(sample);
assertThat(wrapper.getLastModifiedDate(), is(calendar));
Optional<AuditableBeanWrapper> wrapper = factory.getBeanWrapperFor(Optional.of(sample));
assertThat(wrapper).hasValueSatisfying(it -> {
assertThat(it.getLastModifiedDate()).isEqualTo(expected);
});
}
static class Sample {
@@ -177,7 +188,7 @@ public class MappingAuditableBeanWrapperFactoryUnitTests {
}
@SuppressWarnings("serial")
static abstract class ExtendingAuditable implements Auditable<Object, Long> {
static abstract class ExtendingAuditable implements Auditable<Object, Long, LocalDateTime> {
}
}

View File

@@ -15,11 +15,11 @@
*/
package org.springframework.data.auditing;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.assertj.core.api.Assertions.*;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Optional;
import org.joda.time.DateTime;
import org.junit.Before;
@@ -27,6 +27,7 @@ import org.junit.Test;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.auditing.DefaultAuditableBeanWrapperFactory.ReflectionAuditingBeanWrapper;
import org.springframework.data.convert.Jsr310Converters.LocalDateTimeToDateConverter;
/**
* Unit tests for {@link ReflectionAuditingBeanWrapper}.
@@ -40,14 +41,11 @@ public class ReflectionAuditingBeanWrapperUnitTests {
AnnotatedUser user;
AuditableBeanWrapper wrapper;
Calendar calendar = new GregorianCalendar();
DateTime time = new DateTime(calendar);
LocalDateTime time = LocalDateTime.now();
@Before
public void setUp() {
assertThat(time, is(new DateTime(calendar)));
this.user = new AnnotatedUser();
this.wrapper = new ReflectionAuditingBeanWrapper(user);
}
@@ -55,15 +53,15 @@ public class ReflectionAuditingBeanWrapperUnitTests {
@Test
public void setsDateTimeFieldCorrectly() {
wrapper.setCreatedDate(calendar);
assertThat(user.createdDate, is(time));
wrapper.setCreatedDate(Optional.of(time));
assertThat(user.createdDate).isEqualTo(new DateTime(LocalDateTimeToDateConverter.INSTANCE.convert(time)));
}
@Test
public void setsDateFieldCorrectly() {
wrapper.setLastModifiedDate(calendar);
assertThat(user.lastModifiedDate, is(time.toDate()));
wrapper.setLastModifiedDate(Optional.of(time));
assertThat(user.lastModifiedDate).isEqualTo(LocalDateTimeToDateConverter.INSTANCE.convert(time));
}
@Test
@@ -79,11 +77,11 @@ public class ReflectionAuditingBeanWrapperUnitTests {
Sample sample = new Sample();
AuditableBeanWrapper wrapper = new ReflectionAuditingBeanWrapper(sample);
wrapper.setCreatedDate(calendar);
assertThat(sample.createdDate, is(time.getMillis()));
wrapper.setCreatedDate(Optional.of(time));
assertThat(sample.createdDate).isEqualTo(time.atZone(ZoneOffset.systemDefault()).toInstant().toEpochMilli());
wrapper.setLastModifiedDate(calendar);
assertThat(sample.modifiedDate, is(time.getMillis()));
wrapper.setLastModifiedDate(Optional.of(time));
assertThat(sample.modifiedDate).isEqualTo(time.atZone(ZoneOffset.systemDefault()).toInstant().toEpochMilli());
}
@Test
@@ -91,10 +89,10 @@ public class ReflectionAuditingBeanWrapperUnitTests {
Object object = new Object();
wrapper.setCreatedBy(object);
assertThat(user.createdBy, is(object));
wrapper.setCreatedBy(Optional.of(object));
assertThat(user.createdBy).isEqualTo(object);
wrapper.setLastModifiedBy(object);
assertThat(user.lastModifiedBy, is(object));
wrapper.setLastModifiedBy(Optional.of(object));
assertThat(user.lastModifiedBy).isEqualTo(object);
}
}