refactor vorerst fertig, bugsuche
This commit is contained in:
@ -2,14 +2,9 @@ CREATE TABLE event
|
||||
(
|
||||
event_id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
group_id VARCHAR(36) NOT NULL,
|
||||
user_id VARCHAR(50) NOT NULL,
|
||||
group_version INT NOT NULL,
|
||||
exec_id VARCHAR(50) NOT NULL,
|
||||
target_id VARCHAR(50),
|
||||
event_type VARCHAR(32) NOT NULL,
|
||||
event_payload JSON
|
||||
);
|
||||
|
||||
CREATE TABLE invite
|
||||
(
|
||||
invite_id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
group_id VARCHAR(36) NOT NULL,
|
||||
invite_link VARCHAR(36) NOT NULL
|
||||
event_payload VARCHAR(2500) NOT NULL
|
||||
);
|
||||
|
@ -38,7 +38,7 @@ public class AddMemberEvent extends Event {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
public String type() {
|
||||
return EventType.ADDMEMBER.toString();
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ public class CreateGroupEvent extends Event {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
public String type() {
|
||||
return EventType.CREATEGROUP.toString();
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ public class DestroyGroupEvent extends Event {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
public String type() {
|
||||
return EventType.DESTROYGROUP.toString();
|
||||
}
|
||||
}
|
||||
|
@ -52,10 +52,10 @@ public abstract class Event {
|
||||
|
||||
public void init(long version) {
|
||||
if (this.version != 0) {
|
||||
throw new BadArgumentException("Event wurde schon initialisiert. (" + getType() + ")");
|
||||
throw new BadArgumentException("Event wurde schon initialisiert. (" + type() + ")");
|
||||
}
|
||||
|
||||
log.trace("Event wurde initialisiert. (" + getType() + "," + version + ")");
|
||||
log.trace("Event wurde initialisiert. (" + type() + "," + version + ")");
|
||||
|
||||
this.version = version;
|
||||
}
|
||||
@ -88,5 +88,5 @@ public abstract class Event {
|
||||
protected abstract void applyEvent(Group group) throws EventException;
|
||||
|
||||
@JsonIgnore
|
||||
public abstract String getType();
|
||||
public abstract String type();
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class KickMemberEvent extends Event {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
public String type() {
|
||||
return EventType.KICKMEMBER.toString();
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public class SetDescriptionEvent extends Event {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
public String type() {
|
||||
return EventType.SETDESCRIPTION.toString();
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public class SetInviteLinkEvent extends Event {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
public String type() {
|
||||
return EventType.SETLINK.toString();
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public class SetLimitEvent extends Event {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
public String type() {
|
||||
return EventType.SETLIMIT.toString();
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public class SetParentEvent extends Event {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
public String type() {
|
||||
return EventType.SETPARENT.toString();
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public class SetTitleEvent extends Event {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
public String type() {
|
||||
return EventType.SETTITLE.toString();
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ public class SetTypeEvent extends Event {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
public String type() {
|
||||
return EventType.SETTYPE.toString();
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ public class UpdateRoleEvent extends Event {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
public String type() {
|
||||
return EventType.UPDATEROLE.toString();
|
||||
}
|
||||
|
||||
|
@ -32,4 +32,10 @@ public final class CommonHelper {
|
||||
public static boolean uuidIsEmpty(UUID uuid) {
|
||||
return "00000000-0000-0000-0000-000000000000".equals(uuid.toString());
|
||||
}
|
||||
|
||||
public static List<UUID> stringsToUUID(List<String> groupids) {
|
||||
return groupids.stream()
|
||||
.map(UUID::fromString)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package mops.gruppen2.domain.model.group;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import mops.gruppen2.domain.exception.BadArgumentException;
|
||||
import mops.gruppen2.domain.exception.GroupFullException;
|
||||
@ -11,6 +10,7 @@ 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.helper.CommonHelper;
|
||||
import mops.gruppen2.domain.helper.ValidationHelper;
|
||||
import mops.gruppen2.domain.model.group.wrapper.Body;
|
||||
import mops.gruppen2.domain.model.group.wrapper.Description;
|
||||
@ -36,12 +36,10 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
@Log4j2
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
@ToString(onlyExplicitlyIncluded = true)
|
||||
public class Group {
|
||||
|
||||
// Metainformationen
|
||||
@EqualsAndHashCode.Include
|
||||
@ToString.Include
|
||||
private UUID groupid;
|
||||
|
||||
@Getter
|
||||
@ -53,7 +51,6 @@ public class Group {
|
||||
|
||||
private Link link = Link.RANDOM();
|
||||
|
||||
@ToString.Include
|
||||
private GroupMeta meta = GroupMeta.EMPTY();
|
||||
|
||||
private GroupOptions options = GroupOptions.DEFAULT();
|
||||
@ -62,9 +59,9 @@ public class Group {
|
||||
//private LocalDateTime age;
|
||||
|
||||
// Inhalt
|
||||
private Title title;
|
||||
private Title title = Title.EMPTY();
|
||||
|
||||
private Description description;
|
||||
private Description description = Description.EMPTY();
|
||||
|
||||
private Body body;
|
||||
|
||||
@ -123,6 +120,12 @@ public class Group {
|
||||
memberships.put(target, memberships.get(target).setRole(role));
|
||||
}
|
||||
|
||||
public boolean memberHasRole(String target, Role role) {
|
||||
ValidationHelper.throwIfNoMember(this, target);
|
||||
|
||||
return memberships.get(target).getRole() == role;
|
||||
}
|
||||
|
||||
public boolean isMember(String target) {
|
||||
return memberships.containsKey(target);
|
||||
}
|
||||
@ -148,7 +151,7 @@ public class Group {
|
||||
}
|
||||
|
||||
public UUID getParent() {
|
||||
return parent.getGroupid();
|
||||
return parent.getValue();
|
||||
}
|
||||
|
||||
public long getLimit() {
|
||||
@ -191,6 +194,10 @@ public class Group {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
public boolean exists() {
|
||||
return groupid != null && !CommonHelper.uuidIsEmpty(groupid);
|
||||
}
|
||||
|
||||
public boolean isPublic() {
|
||||
return type == Type.PUBLIC;
|
||||
}
|
||||
@ -272,22 +279,35 @@ public class Group {
|
||||
|
||||
|
||||
public void destroy(String userid) throws NoAccessException {
|
||||
if (!isEmpty()) {
|
||||
ValidationHelper.throwIfNoAdmin(this, userid);
|
||||
}
|
||||
|
||||
groupid = null;
|
||||
parent = null;
|
||||
type = null;
|
||||
title = null;
|
||||
description = null;
|
||||
parent = null;
|
||||
limit = null;
|
||||
memberships = null;
|
||||
link = null;
|
||||
meta = null;
|
||||
options = null;
|
||||
title = null;
|
||||
description = null;
|
||||
body = null;
|
||||
memberships = null;
|
||||
}
|
||||
|
||||
public String format() {
|
||||
return title + " " + description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "group("
|
||||
+ (groupid == null ? "groupid: null" : groupid.toString())
|
||||
+ ", "
|
||||
+ (parent == null ? "parent: null" : parent.toString())
|
||||
+ ", "
|
||||
+ (meta == null ? "meta: null" : meta.toString())
|
||||
+ ")";
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public class User {
|
||||
@JsonProperty("familyname")
|
||||
String familyname;
|
||||
|
||||
@JsonProperty("mail")
|
||||
@JsonProperty("email")
|
||||
String email;
|
||||
|
||||
public User(KeycloakAuthenticationToken token) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package mops.gruppen2.domain.model.group.wrapper;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Value;
|
||||
|
||||
@ -18,4 +19,9 @@ public class Description {
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public static Description EMPTY() {
|
||||
return new Description("EMPTY");
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package mops.gruppen2.domain.model.group.wrapper;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.ToString;
|
||||
import lombok.Value;
|
||||
import mops.gruppen2.domain.helper.CommonHelper;
|
||||
|
||||
@ -12,15 +13,16 @@ import java.beans.ConstructorProperties;
|
||||
import java.util.UUID;
|
||||
|
||||
@Value
|
||||
@ToString
|
||||
public class Parent {
|
||||
|
||||
@NotNull
|
||||
@JsonProperty("id")
|
||||
UUID groupid;
|
||||
UUID value;
|
||||
|
||||
@ConstructorProperties("id")
|
||||
public Parent(@NotBlank @Size(min = 36, max = 36) String parentid) {
|
||||
groupid = UUID.fromString(parentid);
|
||||
value = UUID.fromString(parentid);
|
||||
}
|
||||
|
||||
public static Parent EMPTY() {
|
||||
@ -29,6 +31,6 @@ public class Parent {
|
||||
|
||||
@JsonIgnore
|
||||
public boolean isEmpty() {
|
||||
return CommonHelper.uuidIsEmpty(groupid);
|
||||
return CommonHelper.uuidIsEmpty(value);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package mops.gruppen2.domain.model.group.wrapper;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Value;
|
||||
|
||||
@ -18,4 +19,9 @@ public class Title {
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public static Title EMPTY() {
|
||||
return new Title("EMPTY");
|
||||
}
|
||||
}
|
||||
|
@ -8,14 +8,18 @@ import mops.gruppen2.domain.event.AddMemberEvent;
|
||||
import mops.gruppen2.domain.event.CreateGroupEvent;
|
||||
import mops.gruppen2.domain.event.Event;
|
||||
import mops.gruppen2.domain.event.EventType;
|
||||
import mops.gruppen2.domain.event.SetTypeEvent;
|
||||
import mops.gruppen2.domain.exception.BadPayloadException;
|
||||
import mops.gruppen2.domain.exception.InvalidInviteException;
|
||||
import mops.gruppen2.domain.helper.CommonHelper;
|
||||
import mops.gruppen2.domain.helper.JsonHelper;
|
||||
import mops.gruppen2.domain.model.group.Type;
|
||||
import mops.gruppen2.persistance.EventRepository;
|
||||
import mops.gruppen2.persistance.dto.EventDTO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@ -24,6 +28,7 @@ import java.util.stream.Collectors;
|
||||
import static mops.gruppen2.domain.event.EventType.CREATEGROUP;
|
||||
import static mops.gruppen2.domain.event.EventType.DESTROYGROUP;
|
||||
import static mops.gruppen2.domain.event.EventType.SETLINK;
|
||||
import static mops.gruppen2.domain.event.EventType.SETTYPE;
|
||||
import static mops.gruppen2.domain.helper.CommonHelper.eventTypesToString;
|
||||
import static mops.gruppen2.domain.helper.CommonHelper.uuidsToString;
|
||||
|
||||
@ -93,7 +98,7 @@ public class EventStoreService {
|
||||
event.getVersion(),
|
||||
event.getExec(),
|
||||
event.getTarget(),
|
||||
event.getType(),
|
||||
event.type(),
|
||||
payload);
|
||||
} catch (JsonProcessingException e) {
|
||||
log.error("Event ({}) konnte nicht serialisiert werden!", event, e);
|
||||
@ -155,13 +160,12 @@ public class EventStoreService {
|
||||
*
|
||||
* @return Liste von neuen und alten Events
|
||||
*/
|
||||
List<Event> findChangedGroupEvents(long status) {
|
||||
List<UUID> findChangedGroups(long status) {
|
||||
List<String> changedGroupIds = eventStore.findGroupIdsWhereEventIdGreaterThanStatus(status);
|
||||
List<EventDTO> groupEventDTOS = eventStore.findEventDTOsByGroup(changedGroupIds);
|
||||
|
||||
log.debug("Seit Event {} haben sich {} Gruppen geändert!", status, changedGroupIds.size());
|
||||
|
||||
return getEventsFromDTOs(groupEventDTOS);
|
||||
return CommonHelper.stringsToUUID(changedGroupIds);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -179,6 +183,30 @@ public class EventStoreService {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<UUID> findPublicGroupIds() {
|
||||
List<UUID> groups = findExistingGroupIds();
|
||||
List<Event> typeEvents = findLatestEventsFromGroupsByType(SETTYPE);
|
||||
|
||||
typeEvents.removeIf(event -> ((SetTypeEvent) event).getType() == Type.PRIVATE);
|
||||
typeEvents.removeIf(event -> !groups.contains(event.getGroupid()));
|
||||
|
||||
return typeEvents.stream()
|
||||
.map(Event::getGroupid)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<UUID> findLectureGroupIds() {
|
||||
List<UUID> groups = findExistingGroupIds();
|
||||
List<Event> typeEvents = findLatestEventsFromGroupsByType(SETTYPE);
|
||||
|
||||
typeEvents.removeIf(event -> ((SetTypeEvent) event).getType() != Type.LECTURE);
|
||||
typeEvents.removeIf(event -> !groups.contains(event.getGroupid()));
|
||||
|
||||
return typeEvents.stream()
|
||||
.map(Event::getGroupid)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert Gruppen-Ids von existierenden (ungelöschten) Gruppen, in welchen der User teilnimmt.
|
||||
*
|
||||
@ -239,16 +267,16 @@ public class EventStoreService {
|
||||
}
|
||||
|
||||
List<Event> findEventsByType(String... types) {
|
||||
return getEventsFromDTOs(eventStore.findEventDTOsByType(types));
|
||||
return getEventsFromDTOs(eventStore.findEventDTOsByType(Arrays.asList(types)));
|
||||
}
|
||||
|
||||
List<Event> findEventsByType(String type) {
|
||||
return getEventsFromDTOs(eventStore.findEventDTOsByType(type));
|
||||
return getEventsFromDTOs(eventStore.findEventDTOsByType(Collections.singletonList(type)));
|
||||
}
|
||||
|
||||
List<Event> findEventsByGroupAndType(List<UUID> groupIds, String... types) {
|
||||
return getEventsFromDTOs(eventStore.findEventDTOsByGroupAndType(uuidsToString(groupIds),
|
||||
types));
|
||||
Arrays.asList(types)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -259,7 +287,7 @@ public class EventStoreService {
|
||||
* @return Eine Liste von einem Add- oder DeleteUserEvent pro Gruppe
|
||||
*/
|
||||
private List<Event> findLatestEventsFromGroupsByUser(String userid) {
|
||||
return getEventsFromDTOs(eventStore.findLatestEventDTOsPartitionedByGroupByUser(userid));
|
||||
return getEventsFromDTOs(eventStore.findLatestEventDTOsPartitionedByGroupTarget(userid));
|
||||
}
|
||||
|
||||
|
||||
@ -271,6 +299,6 @@ public class EventStoreService {
|
||||
* @return Eine Liste von einem Event pro Gruppe
|
||||
*/
|
||||
private List<Event> findLatestEventsFromGroupsByType(EventType... types) {
|
||||
return getEventsFromDTOs(eventStore.findLatestEventDTOsPartitionedByGroupByType(eventTypesToString(types)));
|
||||
return getEventsFromDTOs(eventStore.findLatestEventDTOsPartitionedByGroupByType(Arrays.asList(eventTypesToString(types))));
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package mops.gruppen2.domain.service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import mops.gruppen2.aspect.annotation.TraceMethodCalls;
|
||||
import mops.gruppen2.domain.event.AddMemberEvent;
|
||||
import mops.gruppen2.domain.event.CreateGroupEvent;
|
||||
import mops.gruppen2.domain.event.DestroyGroupEvent;
|
||||
@ -36,6 +37,7 @@ import java.util.UUID;
|
||||
* Es werden übergebene Gruppen bearbeitet und dementsprechend Events erzeugt und gespeichert.
|
||||
*/
|
||||
@Log4j2
|
||||
@TraceMethodCalls
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class GroupService {
|
||||
@ -166,11 +168,11 @@ public class GroupService {
|
||||
* Erzeugt, speichert ein DeleteUserEvent und wendet es auf eine Gruppe an.
|
||||
* Prüft, ob der Nutzer Mitglied ist und ob er der letzte Admin ist.
|
||||
*/
|
||||
public void deleteUser(Group group, String exec, String target) {
|
||||
public void kickMember(Group group, String exec, String target) {
|
||||
applyAndSave(group, new KickMemberEvent(group, exec, target));
|
||||
|
||||
if (ValidationHelper.checkIfGroupEmpty(group)) {
|
||||
deleteGroup(group, target);
|
||||
deleteGroup(group, exec);
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,6 +181,10 @@ public class GroupService {
|
||||
* Prüft, ob der Nutzer Admin ist.
|
||||
*/
|
||||
public void deleteGroup(Group group, String exec) {
|
||||
if (!group.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
applyAndSave(group, new DestroyGroupEvent(group, exec));
|
||||
}
|
||||
|
||||
@ -188,6 +194,10 @@ public class GroupService {
|
||||
* Bei keiner Änderung wird nichts erzeugt.
|
||||
*/
|
||||
public void setTitle(Group group, String exec, Title title) {
|
||||
if (group.getTitle().equals(title.getValue())) {
|
||||
return;
|
||||
}
|
||||
|
||||
applyAndSave(group, new SetTitleEvent(group, exec, title));
|
||||
}
|
||||
|
||||
@ -197,6 +207,10 @@ public class GroupService {
|
||||
* Bei keiner Änderung wird nichts erzeugt.
|
||||
*/
|
||||
public void setDescription(Group group, String exec, Description description) {
|
||||
if (group.getDescription().equals(description.getValue())) {
|
||||
return;
|
||||
}
|
||||
|
||||
applyAndSave(group, new SetDescriptionEvent(group, exec, description));
|
||||
}
|
||||
|
||||
@ -206,6 +220,10 @@ public class GroupService {
|
||||
* Bei keiner Änderung wird nichts erzeugt.
|
||||
*/
|
||||
private void updateRole(Group group, String exec, String target, Role role) {
|
||||
if (group.memberHasRole(target, role)) {
|
||||
return;
|
||||
}
|
||||
|
||||
applyAndSave(group, new UpdateRoleEvent(group, exec, target, role));
|
||||
}
|
||||
|
||||
@ -215,18 +233,34 @@ public class GroupService {
|
||||
* Bei keiner Änderung wird nichts erzeugt.
|
||||
*/
|
||||
public void setLimit(Group group, String exec, Limit userLimit) {
|
||||
if (userLimit.getValue() == group.getLimit()) {
|
||||
return;
|
||||
}
|
||||
|
||||
applyAndSave(group, new SetLimitEvent(group, exec, userLimit));
|
||||
}
|
||||
|
||||
public void setParent(Group group, String exec, Parent parent) {
|
||||
if (parent.getValue() == group.getParent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
applyAndSave(group, new SetParentEvent(group, exec, parent));
|
||||
}
|
||||
|
||||
public void setLink(Group group, String exec, Link link) {
|
||||
if (group.getLink().equals(link.getValue())) {
|
||||
return;
|
||||
}
|
||||
|
||||
applyAndSave(group, new SetInviteLinkEvent(group, exec, link));
|
||||
}
|
||||
|
||||
private void setType(Group group, String exec, Type type) {
|
||||
if (group.getType() == type) {
|
||||
return;
|
||||
}
|
||||
|
||||
applyAndSave(group, new SetTypeEvent(group, exec, type));
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@ import mops.gruppen2.domain.exception.EventException;
|
||||
import mops.gruppen2.domain.exception.GroupNotFoundException;
|
||||
import mops.gruppen2.domain.helper.CommonHelper;
|
||||
import mops.gruppen2.domain.model.group.Group;
|
||||
import mops.gruppen2.domain.model.group.Type;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -17,13 +16,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static mops.gruppen2.domain.event.EventType.CREATEGROUP;
|
||||
import static mops.gruppen2.domain.event.EventType.SETDESCRIPTION;
|
||||
import static mops.gruppen2.domain.event.EventType.SETLIMIT;
|
||||
import static mops.gruppen2.domain.event.EventType.SETTITLE;
|
||||
import static mops.gruppen2.domain.helper.CommonHelper.eventTypesToString;
|
||||
|
||||
/**
|
||||
* Liefert verschiedene Projektionen auf Gruppen.
|
||||
@ -40,23 +32,6 @@ public class ProjectionService {
|
||||
// ################################## STATISCHE PROJEKTIONEN #################################
|
||||
|
||||
|
||||
/**
|
||||
* Konstruiert Gruppen aus einer Liste von Events.
|
||||
*
|
||||
* @param events Liste an Events
|
||||
*
|
||||
* @return Liste an Projizierten Gruppen
|
||||
*
|
||||
* @throws EventException Projektionsfehler
|
||||
*/
|
||||
static List<Group> projectGroups(List<Event> events) throws EventException {
|
||||
Map<UUID, Group> groupMap = new HashMap<>();
|
||||
|
||||
events.forEach(event -> event.apply(getOrCreateGroup(groupMap, event.getGroupid())));
|
||||
|
||||
return new ArrayList<>(groupMap.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Projiziert Events, geht aber davon aus, dass alle zu derselben Gruppe gehören.
|
||||
*
|
||||
@ -66,7 +41,7 @@ public class ProjectionService {
|
||||
*
|
||||
* @throws EventException Projektionsfehler, z.B. falls Events von verschiedenen Gruppen übergeben werden
|
||||
*/
|
||||
static Group projectSingleGroup(List<Event> events) throws EventException {
|
||||
private static Group projectGroupByEvents(List<Event> events) throws EventException {
|
||||
if (events.isEmpty()) {
|
||||
throw new GroupNotFoundException(ProjectionService.class.toString());
|
||||
}
|
||||
@ -78,6 +53,23 @@ public class ProjectionService {
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Konstruiert Gruppen aus einer Liste von Events.
|
||||
*
|
||||
* @param events Liste an Events
|
||||
*
|
||||
* @return Liste an Projizierten Gruppen
|
||||
*
|
||||
* @throws EventException Projektionsfehler
|
||||
*/
|
||||
private static List<Group> projectGroupsByEvents(List<Event> events) throws EventException {
|
||||
Map<UUID, Group> groupMap = new HashMap<>();
|
||||
|
||||
events.forEach(event -> event.apply(getOrCreateGroup(groupMap, event.getGroupid())));
|
||||
|
||||
return new ArrayList<>(groupMap.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt die Gruppe mit der richtigen Id aus der übergebenen Map wieder, existiert diese nicht
|
||||
* wird die Gruppe erstellt und der Map hizugefügt.
|
||||
@ -99,6 +91,41 @@ public class ProjectionService {
|
||||
// ############################### PROJEKTIONEN MIT DATENBANK ################################
|
||||
|
||||
|
||||
/**
|
||||
* Gibt die Gruppe zurück, die zu der übergebenen Id passt.
|
||||
* Enthält alle verfügbaren Informationen, also auch User (langsam).
|
||||
* Gibt eine leere Gruppe zurück, falls die Id leer ist.
|
||||
*
|
||||
* @param groupId Die Id der gesuchten Gruppe
|
||||
*
|
||||
* @return Die gesuchte Gruppe
|
||||
*
|
||||
* @throws GroupNotFoundException Wenn die Gruppe nicht gefunden wird
|
||||
*/
|
||||
public Group projectGroupById(UUID groupId) throws GroupNotFoundException {
|
||||
try {
|
||||
List<Event> events = eventStoreService.findGroupEvents(groupId);
|
||||
return projectGroupByEvents(events);
|
||||
} catch (Exception e) {
|
||||
log.error("Gruppe {} wurde nicht gefunden!", groupId.toString(), e);
|
||||
throw new GroupNotFoundException(groupId + ": " + ProjectionService.class);
|
||||
}
|
||||
}
|
||||
|
||||
public Group projectParent(UUID parent) {
|
||||
if (CommonHelper.uuidIsEmpty(parent)) {
|
||||
return new Group();
|
||||
}
|
||||
|
||||
return projectGroupById(parent);
|
||||
}
|
||||
|
||||
public List<Group> projectGroupsByIds(List<UUID> groupids) {
|
||||
List<Event> events = eventStoreService.findGroupEvents(groupids);
|
||||
|
||||
return projectGroupsByEvents(events);
|
||||
}
|
||||
|
||||
/**
|
||||
* Projiziert Gruppen, welche sich seit einer übergebenen eventId geändert haben.
|
||||
* Die Gruppen werden dabei vollständig konstruiert.
|
||||
@ -107,10 +134,10 @@ public class ProjectionService {
|
||||
*
|
||||
* @return Liste an Gruppen
|
||||
*/
|
||||
public List<Group> projectNewGroups(long status) {
|
||||
List<Event> events = eventStoreService.findChangedGroupEvents(status);
|
||||
public List<Group> projectChangedGroups(long status) {
|
||||
List<UUID> changedids = eventStoreService.findChangedGroups(status);
|
||||
|
||||
return projectGroups(events);
|
||||
return projectGroupsByIds(changedids);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -124,23 +151,13 @@ public class ProjectionService {
|
||||
*/
|
||||
@Cacheable("groups")
|
||||
public List<Group> projectPublicGroups() throws EventException {
|
||||
List<UUID> groupIds = eventStoreService.findExistingGroupIds();
|
||||
List<UUID> groupIds = eventStoreService.findPublicGroupIds();
|
||||
|
||||
if (groupIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<Event> events = eventStoreService.findEventsByGroupAndType(groupIds,
|
||||
eventTypesToString(CREATEGROUP,
|
||||
SETDESCRIPTION,
|
||||
SETTITLE,
|
||||
SETLIMIT));
|
||||
|
||||
List<Group> groups = projectGroups(events);
|
||||
|
||||
return groups.stream()
|
||||
.filter(group -> group.getType() != Type.PRIVATE)
|
||||
.collect(Collectors.toList());
|
||||
return projectGroupsByIds(groupIds);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -151,21 +168,13 @@ public class ProjectionService {
|
||||
*/
|
||||
@Cacheable("groups")
|
||||
public List<Group> projectLectures() {
|
||||
List<UUID> groupIds = eventStoreService.findExistingGroupIds();
|
||||
List<UUID> groupIds = eventStoreService.findLectureGroupIds();
|
||||
|
||||
if (groupIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<Event> events = eventStoreService.findEventsByGroupAndType(groupIds,
|
||||
eventTypesToString(CREATEGROUP,
|
||||
SETTITLE));
|
||||
|
||||
List<Group> lectures = projectGroups(events);
|
||||
|
||||
return lectures.stream()
|
||||
.filter(group -> group.getType() == Type.LECTURE)
|
||||
.collect(Collectors.toList());
|
||||
return projectGroupsByIds(groupIds);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -184,41 +193,7 @@ public class ProjectionService {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<Event> groupEvents = eventStoreService.findEventsByGroupAndType(groupIds,
|
||||
eventTypesToString(CREATEGROUP,
|
||||
SETTITLE,
|
||||
SETDESCRIPTION));
|
||||
|
||||
return projectGroups(groupEvents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt die Gruppe zurück, die zu der übergebenen Id passt.
|
||||
* Enthält alle verfügbaren Informationen, also auch User (langsam).
|
||||
* Gibt eine leere Gruppe zurück, falls die Id leer ist.
|
||||
*
|
||||
* @param groupId Die Id der gesuchten Gruppe
|
||||
*
|
||||
* @return Die gesuchte Gruppe
|
||||
*
|
||||
* @throws GroupNotFoundException Wenn die Gruppe nicht gefunden wird
|
||||
*/
|
||||
public Group projectSingleGroup(UUID groupId) throws GroupNotFoundException {
|
||||
try {
|
||||
List<Event> events = eventStoreService.findGroupEvents(groupId);
|
||||
return projectSingleGroup(events);
|
||||
} catch (Exception e) {
|
||||
log.error("Gruppe {} wurde nicht gefunden!", groupId.toString(), e);
|
||||
throw new GroupNotFoundException(groupId + ": " + ProjectionService.class);
|
||||
}
|
||||
}
|
||||
|
||||
public Group projectParent(UUID parent) {
|
||||
if (CommonHelper.uuidIsEmpty(parent)) {
|
||||
return new Group();
|
||||
}
|
||||
|
||||
return projectSingleGroup(parent);
|
||||
return projectGroupsByIds(groupIds);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -234,7 +209,7 @@ public class ProjectionService {
|
||||
}
|
||||
|
||||
public Group projectGroupByLink(String link) {
|
||||
return projectSingleGroup(eventStoreService.findGroupByLink(link));
|
||||
return projectGroupById(eventStoreService.findGroupByLink(link));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,9 +32,11 @@ public class SearchService {
|
||||
* @throws EventException Projektionsfehler
|
||||
*/
|
||||
@Cacheable("groups")
|
||||
public List<Group> searchPublicGroups(String search, String userid) {
|
||||
public List<Group> searchPublicGroups(String search, String principal) {
|
||||
List<Group> groups = projectionService.projectPublicGroups();
|
||||
projectionService.removeUserGroups(groups, userid);
|
||||
System.out.println(groups);
|
||||
projectionService.removeUserGroups(groups, principal);
|
||||
System.out.println(groups);
|
||||
SortHelper.sortByGroupType(groups);
|
||||
|
||||
if (search.isEmpty()) {
|
||||
|
@ -13,10 +13,10 @@ public interface EventRepository extends CrudRepository<EventDTO, Long> {
|
||||
|
||||
// ####################################### GROUP IDs #########################################
|
||||
|
||||
@Query("SELECT DISTINCT group_id FROM event"
|
||||
/*@Query("SELECT DISTINCT group_id FROM event"
|
||||
+ " WHERE user_id = :userId AND event_type = :type")
|
||||
List<String> findGroupIdsByUserAndType(@Param("userId") String userId,
|
||||
@Param("type") String type);
|
||||
@Param("type") String type);*/
|
||||
|
||||
@Query("SELECT DISTINCT group_id FROM event"
|
||||
+ " WHERE event_id > :status")
|
||||
@ -28,33 +28,33 @@ public interface EventRepository extends CrudRepository<EventDTO, Long> {
|
||||
+ " WHERE group_id IN (:groupIds) ")
|
||||
List<EventDTO> findEventDTOsByGroup(@Param("groupIds") List<String> groupIds);
|
||||
|
||||
@Query("SELECT * FROM event"
|
||||
/*@Query("SELECT * FROM event"
|
||||
+ " WHERE group_id IN (:userIds) ")
|
||||
List<EventDTO> findEventDTOsByUser(@Param("groupIds") String... userIds);
|
||||
List<EventDTO> findEventDTOsByUser(@Param("groupIds") String... userIds);*/
|
||||
|
||||
@Query("SELECT * FROM event"
|
||||
+ " WHERE event_type IN (:types)")
|
||||
List<EventDTO> findEventDTOsByType(@Param("types") String... types);
|
||||
List<EventDTO> findEventDTOsByType(@Param("types") List<String> types);
|
||||
|
||||
@Query("SELECT * FROM event"
|
||||
+ " WHERE event_type IN (:types) AND group_id IN (:groupIds)")
|
||||
List<EventDTO> findEventDTOsByGroupAndType(@Param("groupIds") List<String> groupIds,
|
||||
@Param("types") String... types);
|
||||
@Param("types") List<String> types);
|
||||
|
||||
@Query("SELECT * FROM event"
|
||||
/*@Query("SELECT * FROM event"
|
||||
+ " WHERE event_type IN (:types) AND user_id = :userId")
|
||||
List<EventDTO> findEventDTOsByUserAndType(@Param("userId") String userId,
|
||||
@Param("types") String... types);
|
||||
@Param("types") String... types);*/
|
||||
|
||||
// ################################ LATEST EVENT DTOs ########################################
|
||||
|
||||
@Query("WITH ranked_events AS ("
|
||||
+ "SELECT *, ROW_NUMBER() OVER (PARTITION BY group_id ORDER BY event_id DESC) AS rn"
|
||||
+ " FROM event"
|
||||
+ " WHERE user_id = :userId AND event_type IN ('ADDMEMBER', 'KICKMEMBER')"
|
||||
+ " WHERE target_id = :userId AND event_type IN ('ADDMEMBER', 'KICKMEMBER')"
|
||||
+ ")"
|
||||
+ "SELECT * FROM ranked_events WHERE rn = 1;")
|
||||
List<EventDTO> findLatestEventDTOsPartitionedByGroupByUser(@Param("userId") String userId);
|
||||
List<EventDTO> findLatestEventDTOsPartitionedByGroupTarget(@Param("userId") String target);
|
||||
|
||||
@Query("WITH ranked_events AS ("
|
||||
+ "SELECT *, ROW_NUMBER() OVER (PARTITION BY group_id ORDER BY event_id DESC) AS rn"
|
||||
@ -62,10 +62,12 @@ public interface EventRepository extends CrudRepository<EventDTO, Long> {
|
||||
+ " WHERE event_type IN (:types)"
|
||||
+ ")"
|
||||
+ "SELECT * FROM ranked_events WHERE rn = 1;")
|
||||
List<EventDTO> findLatestEventDTOsPartitionedByGroupByType(@Param("types") String... types);
|
||||
List<EventDTO> findLatestEventDTOsPartitionedByGroupByType(@Param("types") List<String> types);
|
||||
|
||||
|
||||
// ######################################### COUNT ###########################################
|
||||
|
||||
|
||||
@Query("SELECT MAX(event_id) FROM event")
|
||||
Long findMaxEventId();
|
||||
}
|
||||
|
@ -16,8 +16,8 @@ public class EventDTO {
|
||||
String group_id;
|
||||
long group_version;
|
||||
|
||||
String exec_user_id;
|
||||
String target_user_id;
|
||||
String exec_id;
|
||||
String target_id;
|
||||
|
||||
String event_type;
|
||||
String event_payload;
|
||||
|
@ -47,7 +47,7 @@ public class APIController {
|
||||
@PathVariable("id") long eventId) {
|
||||
|
||||
return APIHelper.wrap(eventStoreService.findMaxEventId(),
|
||||
projectionService.projectNewGroups(eventId));
|
||||
projectionService.projectChangedGroups(eventId));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,7 +71,7 @@ public class APIController {
|
||||
public Group getApiGroup(@ApiParam("Gruppen-Id der gefordeten Gruppe")
|
||||
@PathVariable("id") String groupId) {
|
||||
|
||||
return projectionService.projectSingleGroup(UUID.fromString(groupId));
|
||||
return projectionService.projectGroupById(UUID.fromString(groupId));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ public class GroupDetailsController {
|
||||
@PathVariable("id") String groupId) {
|
||||
|
||||
String principal = token.getName();
|
||||
Group group = projectionService.projectSingleGroup(UUID.fromString(groupId));
|
||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
||||
|
||||
// Parent Badge
|
||||
Group parent = projectionService.projectParent(group.getParent());
|
||||
@ -69,7 +69,7 @@ public class GroupDetailsController {
|
||||
@PathVariable("id") String groupId) {
|
||||
|
||||
String principal = token.getName();
|
||||
Group group = projectionService.projectSingleGroup(UUID.fromString(groupId));
|
||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
||||
|
||||
if (ValidationHelper.checkIfMember(group, principal)) {
|
||||
return "redirect:/gruppen2/details/" + groupId;
|
||||
@ -87,9 +87,9 @@ public class GroupDetailsController {
|
||||
@PathVariable("id") String groupId) {
|
||||
|
||||
String principal = token.getName();
|
||||
Group group = projectionService.projectSingleGroup(UUID.fromString(groupId));
|
||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
||||
|
||||
groupService.deleteUser(group, principal, principal);
|
||||
groupService.kickMember(group, principal, principal);
|
||||
|
||||
return "redirect:/gruppen2";
|
||||
}
|
||||
@ -102,7 +102,7 @@ public class GroupDetailsController {
|
||||
@PathVariable("id") String groupId) {
|
||||
|
||||
String principal = token.getName();
|
||||
Group group = projectionService.projectSingleGroup(UUID.fromString(groupId));
|
||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
||||
|
||||
// Invite Link
|
||||
String actualURL = request.getRequestURL().toString();
|
||||
@ -126,7 +126,7 @@ public class GroupDetailsController {
|
||||
@Valid Description description) {
|
||||
|
||||
String principal = token.getName();
|
||||
Group group = projectionService.projectSingleGroup(UUID.fromString(groupId));
|
||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
||||
|
||||
groupService.setTitle(group, principal, title);
|
||||
groupService.setDescription(group, principal, description);
|
||||
@ -141,7 +141,7 @@ public class GroupDetailsController {
|
||||
@PathVariable("id") String groupId,
|
||||
@Valid Limit limit) {
|
||||
String principal = token.getName();
|
||||
Group group = projectionService.projectSingleGroup(UUID.fromString(groupId));
|
||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
||||
|
||||
groupService.setLimit(group, principal, limit);
|
||||
|
||||
@ -156,7 +156,7 @@ public class GroupDetailsController {
|
||||
@RequestParam(value = "file", required = false) MultipartFile file) {
|
||||
|
||||
String principal = token.getName();
|
||||
Group group = projectionService.projectSingleGroup(UUID.fromString(groupId));
|
||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
||||
|
||||
groupService.addUsersToGroup(group, principal, CsvHelper.readCsvFile(file));
|
||||
|
||||
@ -171,7 +171,7 @@ public class GroupDetailsController {
|
||||
@PathVariable("userid") String target) {
|
||||
|
||||
String principal = token.getName();
|
||||
Group group = projectionService.projectSingleGroup(UUID.fromString(groupId));
|
||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
||||
|
||||
ValidationHelper.throwIfNoAdmin(group, principal);
|
||||
|
||||
@ -193,13 +193,13 @@ public class GroupDetailsController {
|
||||
@PathVariable("userid") String target) {
|
||||
|
||||
String principal = token.getName();
|
||||
Group group = projectionService.projectSingleGroup(UUID.fromString(groupId));
|
||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
||||
|
||||
ValidationHelper.throwIfNoAdmin(group, principal);
|
||||
|
||||
// Der eingeloggte User kann sich nicht selbst entfernen (er kann aber verlassen)
|
||||
if (!principal.equals(target)) {
|
||||
groupService.deleteUser(group, principal, target);
|
||||
groupService.kickMember(group, principal, target);
|
||||
}
|
||||
|
||||
return "redirect:/gruppen2/details/" + groupId + "/edit";
|
||||
@ -212,7 +212,7 @@ public class GroupDetailsController {
|
||||
@PathVariable("id") String groupid) {
|
||||
|
||||
String principal = token.getName();
|
||||
Group group = projectionService.projectSingleGroup(UUID.fromString(groupid));
|
||||
Group group = projectionService.projectGroupById(UUID.fromString(groupid));
|
||||
|
||||
groupService.deleteGroup(group, principal);
|
||||
|
||||
|
@ -5,8 +5,8 @@ CREATE TABLE event
|
||||
event_id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
group_id VARCHAR(36) NOT NULL,
|
||||
group_version INT NOT NULL,
|
||||
exec_user_id VARCHAR(50) NOT NULL,
|
||||
target_user_id VARCHAR(50),
|
||||
exec_id VARCHAR(50) NOT NULL,
|
||||
target_id VARCHAR(50),
|
||||
event_type VARCHAR(32) NOT NULL,
|
||||
event_payload VARCHAR(2500) NOT NULL
|
||||
);
|
||||
|
@ -44,7 +44,7 @@
|
||||
</div>
|
||||
|
||||
<!--Bearbeiten-Button-->
|
||||
<div class="mb-2" th:if="${group.isAdmin(user.getId())}">
|
||||
<div class="mb-2" th:if="${group.isAdmin(principal.getId())}">
|
||||
<form method="get"
|
||||
th:action="@{/gruppen2/details/{id}/edit(id=${group.getId()})}">
|
||||
<button class="btn btn-secondary btn-block">Gruppe verwalten</button>
|
||||
@ -56,7 +56,7 @@
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item d-flex justify-content-between"
|
||||
th:each="member : ${group.getMembers()}">
|
||||
<span th:text="${member}"></span>
|
||||
<span th:text="${member.format()}"></span>
|
||||
<span th:replace="~{fragments/groups :: userbadges}"></span>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -98,7 +98,7 @@
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item d-flex justify-content-between" th:each="member : ${group.getMembers()}">
|
||||
<div>
|
||||
<span th:text="${member.getGivenname() + ' ' + member.getFamilyname().charAt(0) + '.'}"></span>
|
||||
<span th:text="${member.format()}"></span>
|
||||
<span th:replace="~{fragments/groups :: userbadges}"></span>
|
||||
</div>
|
||||
|
||||
|
@ -1,7 +1,12 @@
|
||||
<!DOCTYPE HTML>
|
||||
<!--suppress ALL -->
|
||||
<html lang="de" xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<!--/*@thymesVar id="parent" type="mops.gruppen2.domain.model.group.Group"*/-->
|
||||
<!--/*@thymesVar id="group" type="mops.gruppen2.domain.model.group.Group"*/-->
|
||||
<!--/*@thymesVar id="member" type="mops.gruppen2.domain.model.group.User"*/-->
|
||||
<!--/*@thymesVar id="account" type="mops.gruppen2.domain.Account"*/-->
|
||||
<!--/*@thymesVar id="lectures" type="java.util.List<mops.gruppen2.domain.model.group.Group>"*/-->
|
||||
|
||||
<!--Meta-->
|
||||
<th:block th:fragment="meta">
|
||||
<!--Gruppentitel-->
|
||||
@ -14,6 +19,7 @@
|
||||
th:value="${group?.getTitle()}" required>
|
||||
</div>
|
||||
|
||||
|
||||
<!--Gruppenbeschreibung-->
|
||||
<div class="input-group"
|
||||
title="Eine kurze Gruppenbeschreibung zwischen 4 und 512 Zeichen. Die Beschreibung ist öffentlich.">
|
||||
|
@ -1,6 +1,10 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="de" xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<!--/*@thymesVar id="parent" type="mops.gruppen2.domain.model.group.Group"*/-->
|
||||
<!--/*@thymesVar id="group" type="mops.gruppen2.domain.model.group.Group"*/-->
|
||||
<!--/*@thymesVar id="member" type="mops.gruppen2.domain.model.group.User"*/-->
|
||||
|
||||
<!--Grouptype Badges-->
|
||||
<th:block th:fragment="badges">
|
||||
<span class="badge badge-pill private"
|
||||
@ -14,7 +18,7 @@
|
||||
th:if='${group.isLecture()}'>Veranstaltung</span>
|
||||
|
||||
<span class="badge badge-pill parent"
|
||||
th:if="${parent != null && parent?.getTitle() != null && parent?.getTitle() != ''}"
|
||||
th:if="${parent?.exists()}"
|
||||
th:title="${'Die Gruppe gehört zur Veranstaltung ' + parent.getTitle() + '.'}"
|
||||
th:text="${parent.getTitle()}">Parent</span>
|
||||
|
||||
@ -27,7 +31,7 @@
|
||||
<!--User Badges-->
|
||||
<th:block th:fragment="userbadges">
|
||||
<span class="badge badge-success align-self-start ml-2"
|
||||
th:if="${group.isAdmin(member.getUserid())}">Admin</span>
|
||||
th:if="${group.isAdmin(member.getId())}">Admin</span>
|
||||
</th:block>
|
||||
|
||||
<th:block th:fragment="groupcontent">
|
||||
@ -56,7 +60,7 @@
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<form method="post" th:action="@{/gruppen2/details/{id}/join(id = ${group.getGroupId()})}"
|
||||
<form method="post" th:action="@{/gruppen2/details/{id}/join(id = ${group.getId()})}"
|
||||
th:unless="${group.isFull()}">
|
||||
<button class="btn btn-success" type="submit">Gruppe beitreten.</button>
|
||||
</form>
|
||||
|
@ -21,6 +21,7 @@ class ControllerServiceTest {
|
||||
Account account;
|
||||
Account account2;
|
||||
Account account3;
|
||||
GroupEmpty
|
||||
@Autowired
|
||||
EventStoreService eventStoreService;
|
||||
@Autowired
|
||||
|
@ -70,7 +70,7 @@ class GroupServiceTest {
|
||||
void rightClassForSuccessfulGroup() {
|
||||
List<Event> eventList = completePrivateGroup(1);
|
||||
|
||||
List<Group> groups = ProjectionService.projectGroups(eventList);
|
||||
List<Group> groups = ProjectionService.projectGroupsByEvents(eventList);
|
||||
assertThat(groups.get(0)).isInstanceOf(Group.class);
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ class GroupServiceTest {
|
||||
void projectEventList_SingleGroup() {
|
||||
List<Event> eventList = completePrivateGroup(5);
|
||||
|
||||
List<Group> groups = ProjectionService.projectGroups(eventList);
|
||||
List<Group> groups = ProjectionService.projectGroupsByEvents(eventList);
|
||||
|
||||
assertThat(groups).hasSize(1);
|
||||
assertThat(groups.get(0).getMemberships()).hasSize(5);
|
||||
@ -92,7 +92,7 @@ class GroupServiceTest {
|
||||
List<Event> eventList = completePrivateGroups(10, 2);
|
||||
eventList.addAll(completePublicGroups(10, 5));
|
||||
|
||||
List<Group> groups = ProjectionService.projectGroups(eventList);
|
||||
List<Group> groups = ProjectionService.projectGroupsByEvents(eventList);
|
||||
|
||||
assertThat(groups).hasSize(20);
|
||||
assertThat(groups.stream().map(group -> group.getMemberships().size()).reduce(Integer::sum).get()).isEqualTo(70);
|
||||
|
Reference in New Issue
Block a user