diff --git a/pom.xml b/pom.xml index 1942ee3..f8134b0 100644 --- a/pom.xml +++ b/pom.xml @@ -79,6 +79,16 @@ rest-assured test + + io.quarkus + quarkus-test-security + test + + + io.quarkus + quarkus-panache-mock + test + org.webjars bootstrap diff --git a/src/main/java/de/mbremer/extension/CommonExtensions.java b/src/main/java/de/mbremer/extension/CommonExtensions.java new file mode 100644 index 0000000..564ba9a --- /dev/null +++ b/src/main/java/de/mbremer/extension/CommonExtensions.java @@ -0,0 +1,15 @@ +package de.mbremer.extension; + +import io.quarkus.qute.TemplateExtension; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; + +@TemplateExtension +public class CommonExtensions { + + public static String formatCommon(LocalDate date) { + return date == null ? "" : date.atStartOfDay(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("EEEE, d.M.yyyy")); + } +} diff --git a/src/main/java/de/mbremer/kalender/KalenderResource.java b/src/main/java/de/mbremer/kalender/KalenderResource.java index d31834f..f16ca48 100644 --- a/src/main/java/de/mbremer/kalender/KalenderResource.java +++ b/src/main/java/de/mbremer/kalender/KalenderResource.java @@ -1,19 +1,31 @@ package de.mbremer.kalender; +import de.mbremer.secutity.User; import io.quarkus.qute.Template; import io.quarkus.qute.TemplateInstance; +import io.quarkus.security.identity.SecurityIdentity; +import org.jboss.logging.Logger; +import org.jboss.resteasy.annotations.providers.multipart.MultipartForm; import javax.annotation.security.RolesAllowed; import javax.inject.Inject; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; +import javax.persistence.NoResultException; +import javax.transaction.Transactional; +import javax.ws.rs.*; import javax.ws.rs.core.MediaType; +import java.time.LocalDate; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; @Path("/kalender") @RolesAllowed({"USER", "ADMIN"}) public class KalenderResource { + @Inject + Logger log; + @Inject + SecurityIdentity identity; @Inject Template kalender; @@ -21,6 +33,54 @@ public class KalenderResource { @GET @Produces(MediaType.TEXT_HTML) public TemplateInstance kalender() { - return kalender.instance(); + User currentUser = User.find("username", identity.getPrincipal().getName()).singleResult(); + LocalDate today = LocalDate.now(); + + LocalDate montag = today.minusDays(today.getDayOfWeek().getValue() - 1); + + List week0 = getWeek(currentUser, montag); + List week1 = getWeek(currentUser, montag.plusDays(7)); + List week2 = getWeek(currentUser, montag.plusDays(14)); + + return kalender + .data("today", today) + .data("week0", week0) + .data("week1", week1) + .data("week2", week2); + } + + private List getWeek(User currentUser, LocalDate start) { + return Stream.iterate(0, i -> i < 5, i -> ++i) + .map(d -> { + LocalDate day = start.plusDays(d); + KalenderTag tag = (KalenderTag) KalenderTag.find("day", day).singleResultOptional().orElse(new KalenderTag(day)); + tag.setCurrentUserInOffice(currentUser.equals(tag.getInOffice())); + return tag; + }) + .collect(Collectors.toList()); + } + + @POST + @Transactional + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Path("/inoffice/{day}") + public TemplateInstance update(@PathParam("day") String day, @MultipartForm KalenderTagForm kalenderForm) { + LocalDate dayParsed = LocalDate.parse(day); + + User currentUser = User.find("username", identity.getPrincipal().getName()).singleResult(); + try { + KalenderTag tag = KalenderTag.find("day", dayParsed).singleResult(); + if (kalenderForm.isInOffice() && tag.getInOffice() == null) { + tag.setInOffice(currentUser); + } else if (!kalenderForm.isInOffice() && currentUser.equals(tag.getInOffice())) { + tag.setInOffice(null); + } + } catch (NoResultException e) { + KalenderTag tag = new KalenderTag(dayParsed); + tag.setInOffice(currentUser); + tag.persist(); + } + + return kalender(); } } diff --git a/src/main/java/de/mbremer/kalender/KalenderTag.java b/src/main/java/de/mbremer/kalender/KalenderTag.java index a352080..f51ce16 100644 --- a/src/main/java/de/mbremer/kalender/KalenderTag.java +++ b/src/main/java/de/mbremer/kalender/KalenderTag.java @@ -3,18 +3,27 @@ package de.mbremer.kalender; import de.mbremer.secutity.User; import io.quarkus.hibernate.orm.panache.PanacheEntity; import lombok.Getter; +import lombok.RequiredArgsConstructor; import lombok.Setter; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.OneToMany; +import javax.persistence.Entity; +import javax.persistence.OneToOne; +import javax.persistence.Transient; import java.time.LocalDate; @Getter @Setter +@RequiredArgsConstructor +@Entity public class KalenderTag extends PanacheEntity { - private LocalDate date; - @OneToMany + private LocalDate day; + @OneToOne private User inOffice; + @Transient + private boolean currentUserInOffice; + + public KalenderTag(LocalDate day) { + this.day = day; + } } diff --git a/src/main/java/de/mbremer/kalender/KalenderTagForm.java b/src/main/java/de/mbremer/kalender/KalenderTagForm.java new file mode 100644 index 0000000..41d960e --- /dev/null +++ b/src/main/java/de/mbremer/kalender/KalenderTagForm.java @@ -0,0 +1,16 @@ +package de.mbremer.kalender; + +import org.jboss.resteasy.annotations.providers.multipart.PartType; + +import javax.ws.rs.FormParam; +import javax.ws.rs.core.MediaType; + +public class KalenderTagForm { + @FormParam("inoffice") + @PartType(MediaType.TEXT_PLAIN) + String inOffice; + + boolean isInOffice() { + return "on".equals(inOffice); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index da63bd1..ef46f07 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -11,6 +11,6 @@ quarkus.flyway.migrate-at-start=true # Security quarkus.http.auth.form.enabled=true -quarkus.http.auth.session.encryption-key=zHId14V+uiyxmbzhEPCyi7VvbaI80UeEO5yu0H/hVLs= +#quarkus.http.auth.session.encryption-key=zHId14V+uiyxmbzhEPCyi7VvbaI80UeEO5yu0H/hVLs= # 24h quarkus.http.auth.form.timeout=86400 diff --git a/src/main/resources/db/migration/V0001__initial.sql b/src/main/resources/db/migration/V0001__initial.sql index 32bd62e..25db8bb 100644 --- a/src/main/resources/db/migration/V0001__initial.sql +++ b/src/main/resources/db/migration/V0001__initial.sql @@ -9,6 +9,6 @@ create table users ( create table kalendertag ( id bigint not null primary key, - date date not null unique, - inoffice_id bigint not null references users + day date not null unique, + inoffice_id bigint references users ); \ No newline at end of file diff --git a/src/main/resources/templates/kalender.html b/src/main/resources/templates/kalender.html index 77c057e..fcc1140 100644 --- a/src/main/resources/templates/kalender.html +++ b/src/main/resources/templates/kalender.html @@ -3,10 +3,93 @@ {#contents}
- aktuelle Woche
- nächste Woche
- übernächste Woche
+ Heute ist {today.formatCommon} +
+
+ + + + + + + + + + {#for day in week0} + + + + + + + {/for} + +
Ich will ins BüroDatumIm Büro
+
+
+ +
+
+
+ {day.day.formatCommon} + + {#if day.inOffice}{day.inOffice.username}{/if} +
-{/contents} -{/include} \ No newline at end of file +
+ + + {#for day in week1} + + + + + + + + {/for} + +
+
+
+ +
+
+
+ {day.day.formatCommon} + + {#if day.inOffice}{day.inOffice.username}{/if} +
+ +
+ + + {#for day in week2} + + + + + + + + {/for} + +
+
+
+ +
+
+
+ {day.day.formatCommon} + + {#if day.inOffice}{day.inOffice.username}{/if} +
+
+ + {/contents} + {/include} \ No newline at end of file diff --git a/src/test/java/de/mbremer/extension/CommonExtensionsTest.java b/src/test/java/de/mbremer/extension/CommonExtensionsTest.java new file mode 100644 index 0000000..6ae2a96 --- /dev/null +++ b/src/test/java/de/mbremer/extension/CommonExtensionsTest.java @@ -0,0 +1,15 @@ +package de.mbremer.extension; + +import org.junit.jupiter.api.Test; + +import java.time.LocalDate; + +import static org.junit.jupiter.api.Assertions.*; + +class CommonExtensionsTest { + + @Test + void testFormatCommon() { + assertEquals("Sonntag, 4.7.2021", CommonExtensions.formatCommon(LocalDate.of(2021, 7, 4))); + } +} \ No newline at end of file diff --git a/src/test/java/de/mbremer/kalender/KalenderResourceTest.java b/src/test/java/de/mbremer/kalender/KalenderResourceTest.java new file mode 100644 index 0000000..b9c90ae --- /dev/null +++ b/src/test/java/de/mbremer/kalender/KalenderResourceTest.java @@ -0,0 +1,44 @@ +package de.mbremer.kalender; + +import de.mbremer.secutity.User; +import io.quarkus.hibernate.orm.panache.PanacheEntityBase; +import io.quarkus.hibernate.orm.panache.PanacheQuery; +import io.quarkus.panache.mock.PanacheMock; +import io.quarkus.security.identity.SecurityIdentity; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.mockito.InjectMock; +import io.quarkus.test.security.TestSecurity; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.security.Principal; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.containsString; +import static org.mockito.Mockito.when; + +@QuarkusTest +class KalenderResourceTest { + + @InjectMock + SecurityIdentity identity; + + @Test + @TestSecurity(authorizationEnabled = false) + void testKalender() { + PanacheMock.mock(User.class); + Principal principal = Mockito.mock(Principal.class); + PanacheQuery query = Mockito.mock(PanacheQuery.class); + + when(principal.getName()).thenReturn("admin"); + when(identity.getPrincipal()).thenReturn(principal); + when(query.singleResult()).thenReturn(new User()); + when(User.find("username", "admin")).thenReturn(query); + + given() + .when().get("/kalender") + .then() + .statusCode(200) + .body(containsString("Heute ist")); + } +} \ No newline at end of file