Commit 45012216 authored by Daniel Gerhardt's avatar Daniel Gerhardt

Abstract common CRUD service functionality

Implemented a patch method which merges an existing entity with updated
properties from a HashMap. A new test dependency spring-security-test
has been added.
parent 31a06718
......@@ -224,6 +224,11 @@
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
......
package de.thm.arsnova.services;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import de.thm.arsnova.entities.Entity;
import de.thm.arsnova.entities.serialization.View;
import org.springframework.data.repository.CrudRepository;
import org.springframework.security.access.prepost.PreAuthorize;
import java.io.IOException;
import java.util.Map;
public class EntityService<T extends Entity> {
protected Class<T> type;
protected CrudRepository<T, String> repository;
private ObjectMapper objectMapper;
public EntityService(Class<T> type, CrudRepository<T, String> repository, ObjectMapper objectMapper) {
this.type = type;
this.repository = repository;
this.objectMapper = objectMapper;
}
@PreAuthorize("hasPermission(type, #id, 'read')")
public T findOne(final String id) {
return repository.findOne(id);
}
@PreAuthorize("hasPermission(#entity, 'create')")
public T create(final T entity) {
if (entity.getId() != null || entity.getRevision() != null) {
throw new IllegalArgumentException("Entity is not new.");
}
return repository.save(entity);
}
@PreAuthorize("hasPermission(#oldEntity, 'update')")
public T update(final T oldEntity, final T newEntity) {
newEntity.setId(oldEntity.getId());
return repository.save(newEntity);
}
@PreAuthorize("hasPermission(#entity, 'update')")
public T patch(final T entity, final Map<String, Object> changes) throws IOException {
ObjectReader reader = objectMapper.readerForUpdating(entity).withView(View.Public.class);
JsonNode tree = objectMapper.valueToTree(changes);
reader.readValue(tree);
return repository.save(entity);
}
@PreAuthorize("hasPermission(#entity, 'delete')")
public void delete(final T entity) {
repository.delete(entity);
}
}
package de.thm.arsnova.services;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.thm.arsnova.config.AppConfig;
import de.thm.arsnova.config.TestAppConfig;
import de.thm.arsnova.config.TestPersistanceConfig;
import de.thm.arsnova.config.TestSecurityConfig;
import de.thm.arsnova.entities.Session;
import de.thm.arsnova.persistance.SessionRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import static org.mockito.AdditionalAnswers.*;
import static org.mockito.Mockito.*;
import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = {AppConfig.class, TestAppConfig.class, TestPersistanceConfig.class, TestSecurityConfig.class})
@ActiveProfiles("test")
public class EntityServiceTest {
@Autowired
@Qualifier("defaultJsonMessageConverter")
private MappingJackson2HttpMessageConverter jackson2HttpMessageConverter;
@Autowired
private SessionRepository sessionRepository;
@Test
@WithMockUser(username="TestUser")
public void testPatch() throws IOException {
final ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper();
final EntityService<Session> entityService = new EntityService<>(Session.class, sessionRepository, objectMapper);
when(sessionRepository.save(any(Session.class))).then(returnsFirstArg());
final String originalId = "d8833f0d78964a9487ded02ba2dfbbad";
final String originalName = "Test Session";
final String originalCreator = "TestUser";
final boolean originalActive = false;
final Session session = new Session();
session.setId(originalId);
session.setName(originalName);
session.setActive(originalActive);
session.setCreator(originalCreator);
final String patchedName = "Patched Session";
final boolean patchedActive = true;
final Map<String, Object> patchedValues = new HashMap<>();
patchedValues.put("name", patchedName);
patchedValues.put("active", patchedActive);
patchedValues.put("creator", "Should not be changeable.");
entityService.patch(session, patchedValues);
assertEquals(originalId, session.getId());
assertEquals(patchedName, session.getName());
assertEquals(patchedActive, session.isActive());
assertEquals(originalCreator, session.getCreator());
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment