Fixed tests and git actions #30
39
.gitea/workflows/build-deploy.yaml
Normal file
39
.gitea/workflows/build-deploy.yaml
Normal file
@@ -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 }}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
name: GoLang Tests
|
name: GoLang Tests
|
||||||
run-name: ${{ gitea.actor }} is testing golang Code
|
run-name: ${{ gitea.actor }} is testing golang Code
|
||||||
on: [push]
|
on: push
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
testing:
|
testing:
|
||||||
@@ -46,27 +46,3 @@ jobs:
|
|||||||
arbeitszeitmessung-
|
arbeitszeitmessung-
|
||||||
- name: Run Go Tests
|
- name: Run Go Tests
|
||||||
run: cd Backend && go test ./...
|
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
|
|
||||||
@@ -18,6 +18,7 @@ var Session *scs.SessionManager
|
|||||||
func CreateSessionManager(lifetime time.Duration) *scs.SessionManager {
|
func CreateSessionManager(lifetime time.Duration) *scs.SessionManager {
|
||||||
Session = scs.New()
|
Session = scs.New()
|
||||||
Session.Lifetime = lifetime
|
Session.Lifetime = lifetime
|
||||||
|
log.Println("Created Session")
|
||||||
return Session
|
return Session
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,14 +56,15 @@ func loginUser(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
user, err := models.GetUserByPersonalNr(personal_nummer)
|
user, err := models.GetUserByPersonalNr(personal_nummer)
|
||||||
if err != nil {
|
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)
|
http.Error(w, "No user found!", http.StatusNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
password := r.FormValue("password")
|
password := r.FormValue("password")
|
||||||
if user.Login(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.Put(r.Context(), "user", user.PersonalNummer)
|
||||||
|
Session.Commit(r.Context())
|
||||||
http.Redirect(w, r, "/time", http.StatusSeeOther) //with this browser always uses GET
|
http.Redirect(w, r, "/time", http.StatusSeeOther) //with this browser always uses GET
|
||||||
} else {
|
} else {
|
||||||
showLoginPage(w, r, true)
|
showLoginPage(w, r, true)
|
||||||
|
|||||||
@@ -36,10 +36,12 @@ func SetupDBFixture(t *testing.T) *DBFixture {
|
|||||||
t.Fatalf("failed to connect to database: %v", err)
|
t.Fatalf("failed to connect to database: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// err = MigrateDB(db, "file://../../migrations")
|
defer db.Close()
|
||||||
// if err != nil && err != migrate.ErrNoChange {
|
|
||||||
// t.Fatalf("Failed to migrate database: %v", err)
|
err = MigrateDB(db, "file://../../migrations")
|
||||||
// }
|
if err != nil && err != migrate.ErrNoChange {
|
||||||
|
t.Fatalf("Failed to migrate database: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
tx, err := db.Begin()
|
tx, err := db.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -6,16 +6,20 @@ import (
|
|||||||
"testing"
|
"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) {
|
func SetupUserFixture(t *testing.T, db models.IDatabase) {
|
||||||
t.Helper()
|
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
|
_, 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, '07:00:00', '20:00:00', 0);`)
|
(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) {
|
func TestGetUserByPersonalNr(t *testing.T) {
|
||||||
tc := SetupDBFixture(t)
|
tc := SetupDBFixture(t)
|
||||||
|
|
||||||
SetupUserFixture(t, tc.Database)
|
SetupUserFixture(t, tc.Database)
|
||||||
|
|
||||||
models.DB = tc.Database
|
models.DB = tc.Database
|
||||||
@@ -44,12 +48,12 @@ func TestCheckAnwesenheit(t *testing.T) {
|
|||||||
if actual = testUser.CheckAnwesenheit(); actual != false {
|
if actual = testUser.CheckAnwesenheit(); actual != false {
|
||||||
t.Errorf("Checkabwesenheit with no booking should be false but is %t", actual)
|
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 {
|
if actual = testUser.CheckAnwesenheit(); actual != true {
|
||||||
t.Errorf("Checkabwesenheit with 'kommen' booking should be true but is %t", actual)
|
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 {
|
if actual = testUser.CheckAnwesenheit(); actual != false {
|
||||||
t.Errorf("Checkabwesenheit with 'gehen' booking should be false but is %t", actual)
|
t.Errorf("Checkabwesenheit with 'gehen' booking should be false but is %t", actual)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
DROP TABLE IF EXISTS "anwesenheit";
|
DROP TABLE IF EXISTS "anwesenheit";
|
||||||
CREATE TABLE "anwesenheit" (
|
CREATE TABLE "anwesenheit" (
|
||||||
"counter_id" bigserial NOT NULL,
|
"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,
|
"card_uid" character varying(255) NOT NULL,
|
||||||
"check_in_out" smallint NOT NULL,
|
"check_in_out" smallint NOT NULL,
|
||||||
"geraet_id" smallint NULL,
|
"geraet_id" smallint NOT NULL,
|
||||||
"anwesenheit_typ" int2,
|
"anwesenheit_typ" int2 NOT NULL,
|
||||||
PRIMARY KEY ("counter_id")
|
PRIMARY KEY ("counter_id")
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -32,19 +32,19 @@ DROP TABLE IF EXISTS "s_personal_daten";
|
|||||||
CREATE TABLE "s_personal_daten" (
|
CREATE TABLE "s_personal_daten" (
|
||||||
"personal_nummer" int4 NOT NULL PRIMARY KEY,
|
"personal_nummer" int4 NOT NULL PRIMARY KEY,
|
||||||
"aktiv_beschaeftigt" bool,
|
"aktiv_beschaeftigt" bool,
|
||||||
"vorname" varchar(255),
|
"vorname" varchar(255) NOT NULL,
|
||||||
"nachname" varchar(255),
|
"nachname" varchar(255) NOT NULL,
|
||||||
"geburtsdatum" date,
|
"geburtsdatum" date,
|
||||||
"plz" varchar(255),
|
"plz" varchar(255),
|
||||||
"adresse" varchar(255),
|
"adresse" varchar(255),
|
||||||
"geschlecht" int2,
|
"geschlecht" int2,
|
||||||
"card_uid" varchar(255),
|
"card_uid" varchar(255),
|
||||||
"hauptbeschaeftigungs_ort" int2,
|
"hauptbeschaeftigungs_ort" int2,
|
||||||
"arbeitszeit_per_tag" float4,
|
"arbeitszeit_per_tag" float4 NOT NULL,
|
||||||
"arbeitszeit_per_woche" float4,
|
"arbeitszeit_per_woche" float4 NOT NULL,
|
||||||
"arbeitszeit_min_start" time(6),
|
"arbeitszeit_min_start" time(6),
|
||||||
"arbeitszeit_max_ende" 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';
|
COMMENT ON COLUMN "s_personal_daten"."geschlecht" IS '1==weiblich, 2==maennlich, 3==divers';
|
||||||
|
|
||||||
|
|||||||
4
migrations/20250903233030_non_null_contraints.down.sql
Normal file
4
migrations/20250903233030_non_null_contraints.down.sql
Normal file
@@ -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;
|
||||||
4
migrations/20250903233030_non_null_contraints.up.sql
Normal file
4
migrations/20250903233030_non_null_contraints.up.sql
Normal file
@@ -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;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
h1:hyA7xJMv355hJfvtzD9tKSrkAEtsQ/vVixDZDDBxoh0=
|
h1:8l1ysZIcRMDXUdjWvSQVhVJjVUEfiVlYw7Q/jUB0Wn0=
|
||||||
20250901201159_initial.down.sql h1:cmF5CvNGqEfcmbRgiqaqDWERdNNRaMzarbNLJ/Y35o4=
|
20250901201159_initial.down.sql h1:cmF5CvNGqEfcmbRgiqaqDWERdNNRaMzarbNLJ/Y35o4=
|
||||||
20250901201159_initial.up.sql h1:Yrak/+wfQ4Tu/dVR/cUZ/75DlAcv4G/OJXDqpgSw47U=
|
20250901201159_initial.up.sql h1:Yrak/+wfQ4Tu/dVR/cUZ/75DlAcv4G/OJXDqpgSw47U=
|
||||||
20250901201250_control_tables.down.sql h1:f/KmhO9pOI45J8ZRjFonvD3CypB+rOoGOPN2WMFHvOw=
|
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=
|
20250901201710_triggers_extension.up.sql h1:nUBPd2eDssi/TwMVF/nOJkIM5rUM0iINdg1K9pZRZN0=
|
||||||
20250903221313_overtime.down.sql h1:X+jJESqcZ6ZTd2H563z6kRaXb4dn4sA02D3ck2795v8=
|
20250903221313_overtime.down.sql h1:X+jJESqcZ6ZTd2H563z6kRaXb4dn4sA02D3ck2795v8=
|
||||||
20250903221313_overtime.up.sql h1:C3DSiNVpe9v0Un1DEQ0lsy5yToR8iqcggv91GSr6tRE=
|
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=
|
||||||
|
|||||||
Reference in New Issue
Block a user