diff --git a/docker-compose.yml b/docker-compose.yml index 922610f..7ec3d59 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,6 +26,7 @@ services: volumes: - pb_data:/htwkalender-data-manager/data # for production with volume # - ./data-manager:/htwkalender/data # for development with bind mount from project directory + user: "ical" htwkalender-ical: build: diff --git a/services/data-manager/Dockerfile b/services/data-manager/Dockerfile index f1bcae8..9e52f5d 100644 --- a/services/data-manager/Dockerfile +++ b/services/data-manager/Dockerfile @@ -29,19 +29,20 @@ COPY common/. ./common RUN CGO_ENABLED=1 GOOS=linux go build -o /htwkalender-data-manager data-manager/main.go # production stage -FROM alpine:latest AS prod +FROM alpine:3.20.1 AS prod WORKDIR /htwkalender-data-manager ARG USER=ical -RUN adduser -Ds /bin/sh $USER && \ - chown $USER:$USER ./ +RUN adduser -Ds /bin/sh "$USER" && \ + chown "$USER":"$USER" ./ USER $USER RUN mkdir -p data # copies executable from build container -COPY --chown=$USER:$USER --from=build /htwkalender-data-manager ./ +COPY --chown=$USER:$USER --chmod=644 --from=build /htwkalender-data-manager ./ +RUN chmod +x main # Expose port 8090 to the outside world EXPOSE 8090 @@ -54,6 +55,12 @@ FROM golang:1.21.6 AS dev # Set the Current Working Directory inside the container WORKDIR /htwkalender-data-manager +ARG USER=ical +RUN adduser "$USER" && \ + chown "$USER":"$USER" ./ \ + && mkdir -p /htwkalender-data-manager/data \ + && chown "$USER":"$USER" /htwkalender-data-manager/data + # Copy go mod and sum files COPY go.mod go.sum ./ RUN go mod download @@ -68,5 +75,7 @@ RUN CGO_ENABLED=1 GOOS=linux go build -o /htwkalender-data-manager data-manager/ # Expose port 8091 to the outside world EXPOSE 8091 +USER $USER + # Entry point ENTRYPOINT ["./main", "serve"] \ No newline at end of file diff --git a/services/data-manager/main.go b/services/data-manager/main.go index c49c157..1e50b50 100644 --- a/services/data-manager/main.go +++ b/services/data-manager/main.go @@ -27,7 +27,7 @@ import ( "strings" ) -func main() { +func setupApp() *pocketbase.PocketBase { app := pocketbase.New() // loosely check if it was executed using "go run" @@ -44,8 +44,12 @@ func main() { service.AddRoutes(app) service.AddSchedules(app) + return app +} + +func main() { + app := setupApp() if err := app.Start(); err != nil { slog.Error("Failed to start app: ", "error", err) } - } diff --git a/services/data-manager/main_test.go b/services/data-manager/main_test.go new file mode 100644 index 0000000..773d375 --- /dev/null +++ b/services/data-manager/main_test.go @@ -0,0 +1,42 @@ +//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format. +//Copyright (C) 2024 HTWKalender support@htwkalender.de + +//This program is free software: you can redistribute it and/or modify +//it under the terms of the GNU Affero General Public License as published by +//the Free Software Foundation, either version 3 of the License, or +//(at your option) any later version. + +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU Affero General Public License for more details. + +//You should have received a copy of the GNU Affero General Public License +//along with this program. If not, see . + +package main + +import ( + "testing" +) + +func Test_setupApp(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "Test setupApp", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + app := setupApp() + go func() { + if err := app.Start(); err != nil { + t.Errorf("Failed to start app: %v", err) + return + } + }() + }) + } +} diff --git a/services/data-manager/service/fetch/v1/fetchSeminarEventService_test.go b/services/data-manager/service/fetch/v1/fetchSeminarEventService_test.go index 10b55cd..8f88b4a 100644 --- a/services/data-manager/service/fetch/v1/fetchSeminarEventService_test.go +++ b/services/data-manager/service/fetch/v1/fetchSeminarEventService_test.go @@ -501,3 +501,122 @@ func Test_replaceTimeForDate(t *testing.T) { }) } } + +func Test_isSummerSemester(t *testing.T) { + type args struct { + month time.Month + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "Test Summer March", + args: args{ + month: time.March, + }, + want: true, + }, + { + name: "Test Summer September", + args: args{ + month: time.September, + }, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := isSummerSemester(tt.args.month); got != tt.want { + t.Errorf("isSummerSemester() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_isWinterSemester(t *testing.T) { + type args struct { + month time.Month + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "Test Winter March", + args: args{ + month: time.March, + }, + want: true, + }, + { + name: "Test Winter September", + args: args{ + month: time.September, + }, + want: true, + }, + { + name: "Test Winter November", + args: args{ + month: time.November, + }, + want: true, + }, + { + name: "Test Winter February", + args: args{ + month: time.February, + }, + want: true, + }, + { + name: "Test Winter June", + args: args{ + month: time.June, + }, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := isWinterSemester(tt.args.month); got != tt.want { + t.Errorf("isWinterSemester() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_parseSeminarGroup(t *testing.T) { + type args struct { + result string + } + tests := []struct { + name string + args args + want model.SeminarGroup + }{ + { + name: "Test 1", + args: args{ + result: "B435 SBB (wpf) & B348 BIB (pf) 5. FS", + }, + want: model.SeminarGroup{ + Events: []model.Event{ + { + Name: "B435 SBB (wpf) & B348 BIB (pf) 5. FS", + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := parseSeminarGroup(tt.args.result); !reflect.DeepEqual(got, tt.want) { + t.Errorf("parseSeminarGroup() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/services/data-manager/sonar-project.properties b/services/data-manager/sonar-project.properties index a0ad568..c9b68d8 100644 --- a/services/data-manager/sonar-project.properties +++ b/services/data-manager/sonar-project.properties @@ -1,2 +1,3 @@ sonar.projectKey=HTWKalender sonar.qualitygate.wait=true +sonar.exclusions=migrations/** \ No newline at end of file