1

groupservice test

This commit is contained in:
Christoph
2020-04-18 17:47:03 +02:00
parent 3d42e87dca
commit 7a633c0396
10 changed files with 317 additions and 13 deletions

View File

@ -78,7 +78,7 @@ public abstract class Event {
checkGroupIdMatch(group.getId());
applyEvent(group);
updateCache(cache, group);
updateCache(cache, group); // Update erst nachdem apply keine exception geworfen hat
// Danach hat die Gruppe nur Nullfelder
if (this instanceof DestroyGroupEvent) {

View File

@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Value;
import lombok.extern.log4j.Log4j2;
import mops.gruppen2.domain.exception.BadArgumentException;
import mops.gruppen2.domain.exception.NoAccessException;
import mops.gruppen2.domain.model.group.Group;
import mops.gruppen2.domain.model.group.wrapper.Parent;
@ -29,7 +30,7 @@ public class SetParentEvent extends Event {
protected void updateCache(GroupCache cache, Group group) {}
@Override
protected void applyEvent(Group group) throws NoAccessException {
protected void applyEvent(Group group) throws NoAccessException, BadArgumentException {
group.setParent(exec, parent);
log.trace("\t\t\t\t\tNeues Parent: {}", group.getParent());

View File

@ -278,14 +278,20 @@ public class Group {
this.limit = limit;
}
public void setParent(String exec, @Valid Parent parent) throws NoAccessException {
public void setParent(String exec, @Valid Parent parent) throws NoAccessException, BadArgumentException {
ValidationHelper.throwIfNoAdmin(this, exec);
if (parent.getValue().equals(groupid)) {
throw new BadArgumentException("Die Gruppe kann nicht zu sich selbst gehören!");
}
this.parent = parent;
}
public void setLink(String exec, @Valid Link link) throws NoAccessException {
ValidationHelper.throwIfNoAdmin(this, exec);
if (link.getValue().equals(groupid.toString())) {
throw new BadArgumentException("Link kann nicht der GruppenID entsprechen.");
}
this.link = link;
}

View File

@ -12,6 +12,7 @@ import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
@Log4j2
@Value
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@AllArgsConstructor
public class User {

View File

@ -4,18 +4,24 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Value;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.UUID;
@Value
public class Link {
@NotNull
@Size(min = 36, max = 36)
@JsonProperty("value")
String value;
UUID value;
public Link(String value) {
this.value = UUID.fromString(value);
}
public static Link RANDOM() {
return new Link(UUID.randomUUID().toString());
}
public String getValue() {
return value.toString();
}
}

View File

@ -24,12 +24,15 @@ import mops.gruppen2.domain.model.group.wrapper.Limit;
import mops.gruppen2.domain.model.group.wrapper.Link;
import mops.gruppen2.domain.model.group.wrapper.Parent;
import mops.gruppen2.domain.model.group.wrapper.Title;
import mops.gruppen2.domain.service.helper.ValidationHelper;
import mops.gruppen2.infrastructure.GroupCache;
import org.springframework.stereotype.Service;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* Behandelt Aufgaben, welche sich auf eine Gruppe beziehen.
@ -94,9 +97,11 @@ public class GroupService {
* @param exec Ausführender User
*/
public void addUsersToGroup(Group group, String exec, List<User> newUsers) {
setLimit(group, exec, getAdjustedUserLimit(newUsers, group));
List<User> users = newUsers.stream().distinct().collect(Collectors.toUnmodifiableList());
newUsers.forEach(newUser -> addUserSilent(group, exec, newUser.getId(), newUser));
setLimit(group, exec, getAdjustedUserLimit(users, group));
users.forEach(newUser -> addUserSilent(group, exec, newUser.getId(), newUser));
}
/**
@ -123,6 +128,8 @@ public class GroupService {
* @throws EventException Falls der User nicht gefunden wird
*/
public void toggleMemberRole(Group group, String exec, String target) {
ValidationHelper.throwIfNoMember(group, target);
updateRole(group, exec, target, group.getRole(target).toggle());
}
@ -192,7 +199,7 @@ public class GroupService {
* Prüft, ob der Nutzer Admin ist und ob der Titel valide ist.
* Bei keiner Änderung wird nichts erzeugt.
*/
public void setTitle(Group group, String exec, Title title) {
public void setTitle(Group group, String exec, @Valid Title title) {
if (group.getTitle().equals(title.getValue())) {
return;
}
@ -205,7 +212,7 @@ public class GroupService {
* Prüft, ob der Nutzer Admin ist und ob die Beschreibung valide ist.
* Bei keiner Änderung wird nichts erzeugt.
*/
public void setDescription(Group group, String exec, Description description) {
public void setDescription(Group group, String exec, @Valid Description description) {
if (group.getDescription().equals(description.getValue())) {
return;
}
@ -231,7 +238,7 @@ public class GroupService {
* Prüft, ob der Nutzer Admin ist und ob das Limit valide ist.
* Bei keiner Änderung wird nichts erzeugt.
*/
public void setLimit(Group group, String exec, Limit userLimit) {
public void setLimit(Group group, String exec, @Valid Limit userLimit) {
if (userLimit.getValue() == group.getLimit()) {
return;
}
@ -247,7 +254,8 @@ public class GroupService {
applyAndSave(group, new SetParentEvent(group.getId(), exec, parent));
}
public void setLink(Group group, String exec, Link link) {
//TODO: UI Link regenerieren button
public void setLink(Group group, String exec, @Valid Link link) {
if (group.getLink().equals(link.getValue())) {
return;
}

View File

@ -22,7 +22,6 @@ import java.util.UUID;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class ProjectionHelper {
public static List<Group> project(List<Event> events) {
Map<UUID, Group> groups = new HashMap<>();

View File

@ -21,6 +21,13 @@ import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* Cached alle existierenden Gruppen und einige Beziehungen.
* Gruppen können nach Typ angefragt werden, nach ID, nach Link oder nach User.
* Der Cache wird von den Events aktualisiert.
* Beim Aufruf der init() Methode werden alle bisherigen Events projiziert und die Gruppen gespeichert.
* Die Komplette Anwendung verwendet eine Instanz des Caches.
*/
@Log4j2
@RequiredArgsConstructor
@Component

View File

@ -1,5 +1,8 @@
package mops.gruppen2;
import mops.gruppen2.domain.event.Event;
import java.util.List;
import java.util.UUID;
public final class TestHelper {
@ -12,4 +15,10 @@ public final class TestHelper {
return UUID.fromString(string);
}
public static void initEvents(List<Event> events) {
for (int i = 1; i <= events.size(); i++) {
events.get(i - 1).init(i);
}
}
}

View File

@ -0,0 +1,267 @@
package mops.gruppen2.domain.service;
import mops.gruppen2.GroupBuilder;
import mops.gruppen2.domain.exception.BadArgumentException;
import mops.gruppen2.domain.exception.GroupFullException;
import mops.gruppen2.domain.exception.LastAdminException;
import mops.gruppen2.domain.exception.NoAccessException;
import mops.gruppen2.domain.exception.UserAlreadyExistsException;
import mops.gruppen2.domain.exception.UserNotFoundException;
import mops.gruppen2.domain.model.group.Group;
import mops.gruppen2.domain.model.group.Type;
import mops.gruppen2.domain.model.group.User;
import mops.gruppen2.domain.model.group.wrapper.Description;
import mops.gruppen2.domain.model.group.wrapper.Limit;
import mops.gruppen2.domain.model.group.wrapper.Link;
import mops.gruppen2.domain.model.group.wrapper.Parent;
import mops.gruppen2.domain.model.group.wrapper.Title;
import mops.gruppen2.infrastructure.GroupCache;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import static mops.gruppen2.TestHelper.uuid;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
class GroupServiceTest {
private GroupService groupService;
@BeforeEach
void setUp() {
groupService = new GroupService(mock(GroupCache.class), mock(EventStoreService.class));
}
@Test
void createGroup() {
Group group = groupService.createGroup("TEST");
assertThat(group.getId()).isNotNull();
assertThat(group.creator()).isEqualTo("TEST");
}
@Test
void initGroupMembers() {
Group group = groupService.createGroup("TEST");
groupService.initGroupMembers(group, "TEST", "TEST", new User("TEST"), new Limit(1));
assertThat(group.getMembers()).containsExactly(new User("TEST"));
assertThat(group.getLimit()).isEqualTo(1);
assertThat(group.isAdmin("TEST")).isTrue();
}
@Test
void initGroupMeta() {
Group group = groupService.createGroup("TEST");
groupService.initGroupMembers(group, "TEST", "TEST", new User("TEST"), new Limit(1));
groupService.initGroupMeta(group, "TEST", Type.PUBLIC, Parent.EMPTY());
assertThat(group.isPublic()).isTrue();
assertThat(group.hasParent()).isFalse();
}
@Test
void initGroupText() {
Group group = groupService.createGroup("TEST");
groupService.initGroupMembers(group, "TEST", "TEST", new User("TEST"), new Limit(1));
groupService.initGroupMeta(group, "TEST", Type.PUBLIC, Parent.EMPTY());
groupService.initGroupText(group, "TEST", new Title("TITLE"), new Description("DESCR"));
assertThat(group.getTitle()).isEqualTo("TITLE");
assertThat(group.getDescription()).isEqualTo("DESCR");
}
@Test
void addUsersToGroup() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().build();
groupService.addUsersToGroup(group, "TEST", Arrays.asList(
new User("A"),
new User("B"),
new User("C"),
new User("C")));
assertThat(group.getLimit()).isEqualTo(4);
assertThat(group.size()).isEqualTo(4);
assertThat(group.getRegulars()).hasSize(3);
assertThat(group.getAdmins()).hasSize(1);
}
@Test
void toggleMemberRole_lastAdmin_lastUser() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().build();
groupService.toggleMemberRole(group, "TEST", "TEST");
}
@Test
void toggleMemberRole_lastAdmin() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().limit(2).add("PETER").build();
assertThatThrownBy(() -> groupService.toggleMemberRole(group, "TEST", "TEST"))
.isInstanceOf(LastAdminException.class);
}
@Test
void toggleMemberRole_noMember() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().build();
assertThatThrownBy(() -> groupService.toggleMemberRole(group, "TEST", "PETER"))
.isInstanceOf(UserNotFoundException.class);
}
@Test
void addMember_newMember() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().limit(2).build();
groupService.addMember(group, "Test", "PETER", new User("PETER"));
assertThat(group.size()).isEqualTo(2);
assertThat(group.getAdmins()).hasSize(1);
assertThat(group.getRegulars()).hasSize(1);
}
@Test
void addMember_newMember_groupFull() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().build();
assertThatThrownBy(() -> groupService.addMember(group, "Test", "PETER", new User("PETER")))
.isInstanceOf(GroupFullException.class);
}
@Test
void addMember_newMember_userExists() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().limit(3).add("PETER").build();
assertThatThrownBy(() -> groupService.addMember(group, "Test", "PETER", new User("PETER")))
.isInstanceOf(UserAlreadyExistsException.class);
}
@Test
void kickMember_noMember() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().build();
assertThatThrownBy(() -> groupService.kickMember(group, "TEST", "PETER"))
.isInstanceOf(UserNotFoundException.class);
}
@Test
void kickMember_lastMember() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().build();
groupService.kickMember(group, "TEST", "TEST");
assertThat(group.exists()).isFalse();
}
@Test
void kickMember_lastAdmin() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().limit(2).add("PETER").build();
assertThatThrownBy(() -> groupService.kickMember(group, "TEST", "TEST"))
.isInstanceOf(LastAdminException.class);
}
@Test
void deleteGroup_noGroup() {
groupService.deleteGroup(Group.EMPTY(), "TEST");
}
@Test
void deleteGroup() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().limit(2).add("PETER").build();
groupService.deleteGroup(group, "TEST");
assertThat(group.exists()).isFalse();
}
@Test
void deleteGroup_noAdmin() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().limit(2).add("PETER").build();
assertThatThrownBy(() -> groupService.deleteGroup(group, "PETER"))
.isInstanceOf(NoAccessException.class);
assertThat(group.exists()).isTrue();
}
@Test
void setTitle() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().build();
groupService.setTitle(group, "TEST", new Title("TITLE"));
assertThat(group.getTitle()).isEqualTo("TITLE");
}
@Test
void setDescription() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().build();
groupService.setDescription(group, "TEST", new Description("DESCR"));
assertThat(group.getDescription()).isEqualTo("DESCR");
}
@Test
void setLimit_tooLow() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().limit(2).add("PETER").build();
assertThatThrownBy(() -> groupService.setLimit(group, "TEST", new Limit(1)))
.isInstanceOf(BadArgumentException.class);
assertThat(group.getLimit()).isEqualTo(2);
}
@Test
void setLimit() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().build();
groupService.setLimit(group, "TEST", new Limit(8));
assertThat(group.getLimit()).isEqualTo(8);
}
@Test
void setParent_sameGroup() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().build();
assertThatThrownBy(() -> groupService.setParent(group, "TEST", new Parent(uuid(1).toString())))
.isInstanceOf(BadArgumentException.class);
assertThat(group.getParent()).isEqualTo(uuid(0));
assertThat(group.hasParent()).isFalse();
}
@Test
void setParent() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().build();
groupService.setParent(group, "TEST", new Parent(uuid(2).toString()));
assertThat(group.getParent()).isEqualTo(uuid(2));
assertThat(group.hasParent()).isTrue();
}
@Test
void setLink_sameAsGroupId() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().build();
assertThatThrownBy(() -> groupService.setLink(group, "TEST", new Link(uuid(1).toString())))
.isInstanceOf(BadArgumentException.class);
assertThat(group.getLink()).isNotEqualTo(uuid(1).toString());
}
@Test
void setLink() {
Group group = GroupBuilder.get(mock(GroupCache.class), 1).group().testadmin().build();
groupService.setLink(group, "TEST", new Link(uuid(2).toString()));
assertThat(group.getLink()).isEqualTo(uuid(2).toString());
}
}