package fr.openwide.core.test.jpa.more.business.property; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.junit.Rule; import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.mockito.stubbing.Answer; import org.springframework.context.ApplicationEventPublisher; import org.springframework.transaction.PlatformTransactionManager; import fr.openwide.core.jpa.exception.SecurityServiceException; import fr.openwide.core.jpa.exception.ServiceException; import fr.openwide.core.spring.config.spring.event.PropertyRegistryInitEvent; import fr.openwide.core.spring.property.dao.IImmutablePropertyDao; import fr.openwide.core.spring.property.dao.IMutablePropertyDao; import fr.openwide.core.spring.property.exception.PropertyServiceDuplicateRegistrationException; import fr.openwide.core.spring.property.exception.PropertyServiceIncompleteRegistrationException; import fr.openwide.core.spring.property.model.AbstractPropertyIds; import fr.openwide.core.spring.property.model.IMutablePropertyValueMap; import fr.openwide.core.spring.property.model.ImmutablePropertyId; import fr.openwide.core.spring.property.model.MutablePropertyId; import fr.openwide.core.spring.property.model.MutablePropertyValueMap; import fr.openwide.core.spring.property.service.PropertyServiceImpl; public class TestPropertyService { @Mock private IImmutablePropertyDao immutablePropertyDao; @Mock private IMutablePropertyDao mutablePropertyDao; @Mock private PlatformTransactionManager platformTransactionManager; @Mock private ApplicationEventPublisher publisher; @InjectMocks private PropertyServiceImpl propertyService; @Rule public MockitoRule rule = MockitoJUnit.rule(); private static class PropertyIds extends AbstractPropertyIds { static final MutablePropertyId<String> MUTABLE_STRING = mutable("mutable.property.string"); static final MutablePropertyId<Long> MUTABLE_LONG = mutable("mutable.property.long"); static final MutablePropertyId<String> MUTABLE_STRING_WITH_DEFAULT = mutable("mutable.property.string.default"); } private static class ImmutablePropertyIds extends AbstractPropertyIds { static final ImmutablePropertyId<String> IMMUTABLE_STRING = immutable("immutable.property.string"); static final ImmutablePropertyId<Long> IMMUTABLE_LONG = immutable("immutable.property.long"); } private void initPropertyService(Answer<Void> registrationCallback) { propertyService.setApplicationEventPublisher(publisher); propertyService.setPlatformTransactionManager(platformTransactionManager); doAnswer(registrationCallback).when(publisher).publishEvent(Matchers.any(PropertyRegistryInitEvent.class)); propertyService.init(); } @Test public void mutablePropertyGet() throws ServiceException, SecurityServiceException { initPropertyService(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { propertyService.registerString(PropertyIds.MUTABLE_STRING); propertyService.registerLong(PropertyIds.MUTABLE_LONG); propertyService.registerString(PropertyIds.MUTABLE_STRING_WITH_DEFAULT, "MyDefaultValue"); return null; } }); when(mutablePropertyDao.getInTransaction("mutable.property.string")).thenReturn("MyValue"); when(mutablePropertyDao.getInTransaction("mutable.property.long")).thenReturn("1"); when(mutablePropertyDao.getInTransaction("mutable.property.string.default")).thenReturn("MyDefaultValue"); assertEquals("MyValue", propertyService.get(PropertyIds.MUTABLE_STRING)); assertEquals((Long) 1L, propertyService.get(PropertyIds.MUTABLE_LONG)); assertEquals("MyDefaultValue", propertyService.get(PropertyIds.MUTABLE_STRING_WITH_DEFAULT)); } @Test public void mutablePropertySet() throws ServiceException, SecurityServiceException { initPropertyService(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { propertyService.registerString(PropertyIds.MUTABLE_STRING); propertyService.registerLong(PropertyIds.MUTABLE_LONG); propertyService.registerString(PropertyIds.MUTABLE_STRING_WITH_DEFAULT, "MyDefaultValue"); return null; } }); propertyService.set(PropertyIds.MUTABLE_STRING, "MyValue2"); propertyService.set(PropertyIds.MUTABLE_LONG, 2L); propertyService.set(PropertyIds.MUTABLE_STRING_WITH_DEFAULT, "MyValue3"); verify(mutablePropertyDao).setInTransaction("mutable.property.string", "MyValue2"); verify(mutablePropertyDao).setInTransaction("mutable.property.long", "2"); verify(mutablePropertyDao).setInTransaction("mutable.property.string.default", "MyValue3"); } @Test public void mutablePropertySetAll() throws ServiceException, SecurityServiceException { initPropertyService(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { propertyService.registerString(PropertyIds.MUTABLE_STRING); propertyService.registerLong(PropertyIds.MUTABLE_LONG); propertyService.registerString(PropertyIds.MUTABLE_STRING_WITH_DEFAULT, "MyDefaultValue"); return null; } }); IMutablePropertyValueMap propertyValueMap = new MutablePropertyValueMap(); propertyValueMap.put(PropertyIds.MUTABLE_STRING, "MyValue2"); propertyValueMap.put(PropertyIds.MUTABLE_LONG, 2L); propertyValueMap.put(PropertyIds.MUTABLE_STRING_WITH_DEFAULT, "MyValue3"); propertyService.setAll(propertyValueMap); verify(mutablePropertyDao).setInTransaction("mutable.property.string", "MyValue2"); verify(mutablePropertyDao).setInTransaction("mutable.property.long", "2"); verify(mutablePropertyDao).setInTransaction("mutable.property.string.default", "MyValue3"); } @Test(expected = PropertyServiceIncompleteRegistrationException.class) public void partialRegistration() { initPropertyService(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { propertyService.registerString(PropertyIds.MUTABLE_STRING); propertyService.registerString(PropertyIds.MUTABLE_STRING_WITH_DEFAULT, "MyDefaultValue"); // Do not register the last property return null; } }); } @Test(expected = PropertyServiceIncompleteRegistrationException.class) public void mutablePropertyUnregistered() { // Do not register any property when(mutablePropertyDao.getInTransaction("mutable.property.string")).thenReturn("MyValue"); propertyService.get(PropertyIds.MUTABLE_STRING); } @Test public void immutablePropertyGet() { initPropertyService(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { propertyService.registerString(ImmutablePropertyIds.IMMUTABLE_STRING); propertyService.registerLong(ImmutablePropertyIds.IMMUTABLE_LONG); return null; } }); when(immutablePropertyDao.get("immutable.property.string")).thenReturn("MyValue"); when(immutablePropertyDao.get("immutable.property.long")).thenReturn("1"); assertEquals("MyValue", propertyService.get(ImmutablePropertyIds.IMMUTABLE_STRING)); assertEquals((Long) 1L, propertyService.get(ImmutablePropertyIds.IMMUTABLE_LONG)); } @Test(expected = PropertyServiceIncompleteRegistrationException.class) public void immutablePropertyUnregistered() { // Do not register any property when(immutablePropertyDao.get("immutable.property.string")).thenReturn("MyValue"); propertyService.get(ImmutablePropertyIds.IMMUTABLE_STRING); } private static class DuplicatePropertyIds extends AbstractPropertyIds { static final MutablePropertyId<String> MUTABLE_STRING = mutable(ImmutablePropertyIds.IMMUTABLE_STRING.getKey()); static final ImmutablePropertyId<String> IMMUTABLE_STRING = immutable(ImmutablePropertyIds.IMMUTABLE_STRING.getKey()); } @Test(expected = PropertyServiceDuplicateRegistrationException.class) public void propertyAlreadyRegistered() { initPropertyService(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { propertyService.registerString(ImmutablePropertyIds.IMMUTABLE_STRING); propertyService.registerString(DuplicatePropertyIds.IMMUTABLE_STRING); return null; } }); } public void propertiesMutableImmutableWithSameKey() { initPropertyService(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { propertyService.registerString(DuplicatePropertyIds.IMMUTABLE_STRING); propertyService.registerString(DuplicatePropertyIds.MUTABLE_STRING); return null; } }); } }