From 327e47840bcfa2fbbdefa978d19f746e8493d262 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=20Tr=C3=B6ger?= Date: Thu, 4 Sep 2025 10:16:42 +0200 Subject: [PATCH] Fixed tests and git actions (#30) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-on: https://git.letsstein.de/tom/arbeitszeitmessung/pulls/30 Co-authored-by: Tom Tröger Co-committed-by: Tom Tröger --- .gitea/workflows/build-deploy.yaml | 39 +++++++++++++++++++ .../{build.yaml => tests/go-test.yaml} | 26 +------------ Backend/endpoints/user-session.go | 6 ++- Backend/models/db_test.go | 10 +++-- Backend/models/user_test.go | 14 ++++--- DB/initdb/01_schema.sql | 18 ++++----- ...0250903233030_non_null_contraints.down.sql | 4 ++ .../20250903233030_non_null_contraints.up.sql | 4 ++ migrations/atlas.sum | 4 +- 9 files changed, 79 insertions(+), 46 deletions(-) create mode 100644 .gitea/workflows/build-deploy.yaml rename .gitea/workflows/{build.yaml => tests/go-test.yaml} (60%) create mode 100644 migrations/20250903233030_non_null_contraints.down.sql create mode 100644 migrations/20250903233030_non_null_contraints.up.sql diff --git a/.gitea/workflows/build-deploy.yaml b/.gitea/workflows/build-deploy.yaml new file mode 100644 index 0000000..0812aa6 --- /dev/null +++ b/.gitea/workflows/build-deploy.yaml @@ -0,0 +1,39 @@ +name: Arbeitszeitmessung Deploy +run-name: ${{ gitea.actor }} is building and deploying arbeitszeitmesssung +on: + push: + branches: + - "main" + tags: + - "*" + workflow_run: + workflows: [tests] + types: + - completed + +jobs: + build: + name: Build Go Image and Upload + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: git.letsstein.de + username: ${{ gitea.actor }} + password: ${{ secrets.REGISTRY_TOKEN }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Build and push + uses: docker/build-push-action@v6 + with: + platforms: linux/amd64,linux/arm64 + push: true + context: Backend + tags: | + git.letsstein.de/tom/arbeitszeitmessung:latest + git.letsstein.de/tom/arbeitszeitmessung:${{ github.ref_name }} diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/tests/go-test.yaml similarity index 60% rename from .gitea/workflows/build.yaml rename to .gitea/workflows/tests/go-test.yaml index 62c456c..3f5e644 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/tests/go-test.yaml @@ -1,6 +1,6 @@ name: GoLang Tests run-name: ${{ gitea.actor }} is testing golang Code -on: [push] +on: push jobs: testing: @@ -46,27 +46,3 @@ jobs: arbeitszeitmessung- - name: Run Go Tests run: cd Backend && go test ./... - build: - needs: testing - name: Build Go Image and Upload - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: git.letsstein.de - username: ${{ gitea.actor }} - password: ${{ secrets.REGISTRY_TOKEN }} - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Build and push - uses: docker/build-push-action@v6 - with: - platforms: linux/amd64,linux/arm64 - push: true - tags: git.letsstein.de/tom/arbeitszeitmessung:latest - context: Backend diff --git a/Backend/endpoints/user-session.go b/Backend/endpoints/user-session.go index ffed8b9..296fc3b 100644 --- a/Backend/endpoints/user-session.go +++ b/Backend/endpoints/user-session.go @@ -18,6 +18,7 @@ var Session *scs.SessionManager func CreateSessionManager(lifetime time.Duration) *scs.SessionManager { Session = scs.New() Session.Lifetime = lifetime + log.Println("Created Session") return Session } @@ -55,14 +56,15 @@ func loginUser(w http.ResponseWriter, r *http.Request) { user, err := models.GetUserByPersonalNr(personal_nummer) if err != nil { - log.Println("No user found under this personal number!") + log.Println("No user found under this personal number!", err) http.Error(w, "No user found!", http.StatusNotFound) } password := r.FormValue("password") if user.Login(password) { - log.Printf("New succesfull user login from %s %s!\n", user.Vorname, user.Name) + log.Printf("New succesfull user login from %s %s (%d)!\n", user.Vorname, user.Name, user.PersonalNummer) Session.Put(r.Context(), "user", user.PersonalNummer) + Session.Commit(r.Context()) http.Redirect(w, r, "/time", http.StatusSeeOther) //with this browser always uses GET } else { showLoginPage(w, r, true) diff --git a/Backend/models/db_test.go b/Backend/models/db_test.go index 629bd2d..be272c5 100644 --- a/Backend/models/db_test.go +++ b/Backend/models/db_test.go @@ -36,10 +36,12 @@ func SetupDBFixture(t *testing.T) *DBFixture { t.Fatalf("failed to connect to database: %v", err) } - // err = MigrateDB(db, "file://../../migrations") - // if err != nil && err != migrate.ErrNoChange { - // t.Fatalf("Failed to migrate database: %v", err) - // } + defer db.Close() + + err = MigrateDB(db, "file://../../migrations") + if err != nil && err != migrate.ErrNoChange { + t.Fatalf("Failed to migrate database: %v", err) + } tx, err := db.Begin() if err != nil { diff --git a/Backend/models/user_test.go b/Backend/models/user_test.go index 323f925..c214625 100644 --- a/Backend/models/user_test.go +++ b/Backend/models/user_test.go @@ -6,16 +6,20 @@ import ( "testing" ) -var testUser models.User = models.User{Vorname: "Kim", Name: "Mustermensch", PersonalNummer: 456, CardUID: "aaaa-aaaa", ArbeitszeitPerTag: 8} +var testUser models.User = models.User{Vorname: "Kim", Name: "Mustermensch", PersonalNummer: 456, CardUID: "aaaa-aaaa", ArbeitszeitPerTag: 8, ArbeitszeitPerWoche: 40} func SetupUserFixture(t *testing.T, db models.IDatabase) { t.Helper() - db.Exec(`INSERT INTO "s_personal_daten" ("personal_nummer", "aktiv_beschaeftigt", "vorname", "nachname", "geburtsdatum", "plz", "adresse", "geschlecht", "card_uid", "hauptbeschaeftigungs_ort", "arbeitszeit_per_tag", "arbeitszeit_min_start", "arbeitszeit_max_ende", "vorgesetzter_pers_nr") VALUES -(456, 't', 'Kim', 'Mustermensch', '2003-02-01', '08963', 'Altenburger Str. 44A', 1, 'aaaa-aaaa', 1, 8, '07:00:00', '20:00:00', 0);`) + _, err := db.Exec(`INSERT INTO s_personal_daten (personal_nummer, aktiv_beschaeftigt, vorname, nachname, geburtsdatum, plz, adresse, geschlecht, card_uid, hauptbeschaeftigungs_ort, arbeitszeit_per_tag, arbeitszeit_per_woche, arbeitszeit_min_start, arbeitszeit_max_ende, vorgesetzter_pers_nr) VALUES + (456, 't', 'Kim', 'Mustermensch', '2003-02-01', '08963', 'Altenburger Str. 44A', 1, 'aaaa-aaaa', 1, 8, 40, '07:00:00', '20:00:00', 0);`) + if err != nil { + t.Fatal("SetupUserFixture:", err) + } } func TestGetUserByPersonalNr(t *testing.T) { tc := SetupDBFixture(t) + SetupUserFixture(t, tc.Database) models.DB = tc.Database @@ -44,12 +48,12 @@ func TestCheckAnwesenheit(t *testing.T) { if actual = testUser.CheckAnwesenheit(); actual != false { t.Errorf("Checkabwesenheit with no booking should be false but is %t", actual) } - tc.Database.Exec("INSERT INTO anwesenheit (timestamp, card_uid, check_in_out, geraet_id) VALUES (NOW() - INTERVAL '2 minute', 'aaaa-aaaa', 1, 1);") + tc.Database.Exec("INSERT INTO anwesenheit (timestamp, card_uid, check_in_out, geraet_id, anwesenheit_typ) VALUES (NOW() - INTERVAL '2 minute', 'aaaa-aaaa', 1, 1, 1);") if actual = testUser.CheckAnwesenheit(); actual != true { t.Errorf("Checkabwesenheit with 'kommen' booking should be true but is %t", actual) } - tc.Database.Exec("INSERT INTO anwesenheit (timestamp, card_uid, check_in_out, geraet_id) VALUES (NOW() - INTERVAL '1 minute', 'aaaa-aaaa', 2, 1);") + tc.Database.Exec("INSERT INTO anwesenheit (timestamp, card_uid, check_in_out, geraet_id, anwesenheit_typ) VALUES (NOW() - INTERVAL '1 minute', 'aaaa-aaaa', 2, 1, 1);") if actual = testUser.CheckAnwesenheit(); actual != false { t.Errorf("Checkabwesenheit with 'gehen' booking should be false but is %t", actual) } diff --git a/DB/initdb/01_schema.sql b/DB/initdb/01_schema.sql index 14b71ad..8547504 100644 --- a/DB/initdb/01_schema.sql +++ b/DB/initdb/01_schema.sql @@ -4,11 +4,11 @@ DROP TABLE IF EXISTS "anwesenheit"; CREATE TABLE "anwesenheit" ( "counter_id" bigserial NOT NULL, - "timestamp" timestamptz NULL DEFAULT CURRENT_TIMESTAMP, + "timestamp" timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP, "card_uid" character varying(255) NOT NULL, "check_in_out" smallint NOT NULL, - "geraet_id" smallint NULL, - "anwesenheit_typ" int2, + "geraet_id" smallint NOT NULL, + "anwesenheit_typ" int2 NOT NULL, PRIMARY KEY ("counter_id") ); @@ -32,19 +32,19 @@ DROP TABLE IF EXISTS "s_personal_daten"; CREATE TABLE "s_personal_daten" ( "personal_nummer" int4 NOT NULL PRIMARY KEY, "aktiv_beschaeftigt" bool, - "vorname" varchar(255), - "nachname" varchar(255), + "vorname" varchar(255) NOT NULL, + "nachname" varchar(255) NOT NULL, "geburtsdatum" date, "plz" varchar(255), "adresse" varchar(255), "geschlecht" int2, "card_uid" varchar(255), "hauptbeschaeftigungs_ort" int2, - "arbeitszeit_per_tag" float4, - "arbeitszeit_per_woche" float4, + "arbeitszeit_per_tag" float4 NOT NULL, + "arbeitszeit_per_woche" float4 NOT NULL, "arbeitszeit_min_start" time(6), "arbeitszeit_max_ende" time(6), - "vorgesetzter_pers_nr" int4 + "vorgesetzter_pers_nr" int4 NOT NULL ); COMMENT ON COLUMN "s_personal_daten"."geschlecht" IS '1==weiblich, 2==maennlich, 3==divers'; @@ -94,7 +94,7 @@ CREATE TABLE "abwesenheit" ( "datum" timestamptz(6) DEFAULT NOW()::DATE ); - DROP TABLE IF EXISTS "s_abwesenheit_typen"; +DROP TABLE IF EXISTS "s_abwesenheit_typen"; CREATE TABLE "s_abwesenheit_typen" ( "abwesenheit_id" int2 PRIMARY KEY, "abwesenheit_name" varchar(255), diff --git a/migrations/20250903233030_non_null_contraints.down.sql b/migrations/20250903233030_non_null_contraints.down.sql new file mode 100644 index 0000000..120b393 --- /dev/null +++ b/migrations/20250903233030_non_null_contraints.down.sql @@ -0,0 +1,4 @@ +-- reverse: modify "s_personal_daten" table +ALTER TABLE "s_personal_daten" ALTER COLUMN "arbeitszeit_per_woche" DROP NOT NULL, ALTER COLUMN "vorgesetzter_pers_nr" DROP NOT NULL, ALTER COLUMN "arbeitszeit_per_tag" DROP NOT NULL, ALTER COLUMN "nachname" DROP NOT NULL, ALTER COLUMN "vorname" DROP NOT NULL; +-- reverse: modify "anwesenheit" table +ALTER TABLE "anwesenheit" ALTER COLUMN "anwesenheit_typ" DROP NOT NULL, ALTER COLUMN "geraet_id" DROP NOT NULL, ALTER COLUMN "timestamp" DROP NOT NULL; diff --git a/migrations/20250903233030_non_null_contraints.up.sql b/migrations/20250903233030_non_null_contraints.up.sql new file mode 100644 index 0000000..066f92a --- /dev/null +++ b/migrations/20250903233030_non_null_contraints.up.sql @@ -0,0 +1,4 @@ +-- modify "anwesenheit" table +ALTER TABLE "anwesenheit" ALTER COLUMN "timestamp" SET NOT NULL, ALTER COLUMN "geraet_id" SET NOT NULL, ALTER COLUMN "anwesenheit_typ" SET NOT NULL; +-- modify "s_personal_daten" table +ALTER TABLE "s_personal_daten" ALTER COLUMN "vorname" SET NOT NULL, ALTER COLUMN "nachname" SET NOT NULL, ALTER COLUMN "arbeitszeit_per_tag" SET NOT NULL, ALTER COLUMN "vorgesetzter_pers_nr" SET NOT NULL, ALTER COLUMN "arbeitszeit_per_woche" SET NOT NULL; diff --git a/migrations/atlas.sum b/migrations/atlas.sum index 18be8b2..f860f4a 100644 --- a/migrations/atlas.sum +++ b/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:hyA7xJMv355hJfvtzD9tKSrkAEtsQ/vVixDZDDBxoh0= +h1:8l1ysZIcRMDXUdjWvSQVhVJjVUEfiVlYw7Q/jUB0Wn0= 20250901201159_initial.down.sql h1:cmF5CvNGqEfcmbRgiqaqDWERdNNRaMzarbNLJ/Y35o4= 20250901201159_initial.up.sql h1:Yrak/+wfQ4Tu/dVR/cUZ/75DlAcv4G/OJXDqpgSw47U= 20250901201250_control_tables.down.sql h1:f/KmhO9pOI45J8ZRjFonvD3CypB+rOoGOPN2WMFHvOw= @@ -7,3 +7,5 @@ h1:hyA7xJMv355hJfvtzD9tKSrkAEtsQ/vVixDZDDBxoh0= 20250901201710_triggers_extension.up.sql h1:nUBPd2eDssi/TwMVF/nOJkIM5rUM0iINdg1K9pZRZN0= 20250903221313_overtime.down.sql h1:X+jJESqcZ6ZTd2H563z6kRaXb4dn4sA02D3ck2795v8= 20250903221313_overtime.up.sql h1:C3DSiNVpe9v0Un1DEQ0lsy5yToR8iqcggv91GSr6tRE= +20250903233030_non_null_contraints.down.sql h1:jAIc4pRyTS/X0qONQKhjhVx891JCA9/KZbx619240AY= +20250903233030_non_null_contraints.up.sql h1:Ts4CuDO3gP/VSBu1OhnVhiyOIiLnT8qvEf/kHjCmeCU=