From 51f988b44b88fa132f23e0bbe0c291f8459b803c Mon Sep 17 00:00:00 2001
From: Torgrim <sir_alexiner@hotmail.com>
Date: Thu, 11 Apr 2024 04:19:11 +0200
Subject: [PATCH] Updated app_test.go for deployment, updated Docker files with
 dependency on test image before deployment of the service image.

---
 Go/Dockerfile-test                            |  34 +-
 Go/cmd/globeboard/app_test.go                 | 542 +-----------------
 Go/db/db.go                                   |   1 -
 Go/docker-compose.yml                         |  21 +-
 .../endpoint/dashboard/dashboards_handler.go  |   5 +-
 .../dashboard/registrations_handler.go        |  13 +-
 .../dashboard/registrations_id_handler.go     |  13 +-
 .../endpoint/dashboard/status_handler.go      |   2 +-
 Go/web/root.html                              |  12 +-
 9 files changed, 99 insertions(+), 544 deletions(-)

diff --git a/Go/Dockerfile-test b/Go/Dockerfile-test
index 72d70e4..9160f12 100644
--- a/Go/Dockerfile-test
+++ b/Go/Dockerfile-test
@@ -1,17 +1,37 @@
-# Use the official Golang image as a parent image
-FROM golang:1.22
+# syntax=docker/dockerfile:1.2
+FROM golang:1.22 AS builder
 
-# Set the working directory inside the container
+# Set destination for COPY
 WORKDIR /app
 
 # Download Go modules
 COPY go.mod go.sum ./
 
-# Download Go module dependencies
 RUN go mod download
 
-# Copy the rest of the service's source code
+# Copy the source code.
 COPY ../ ./
 
-# Specify the command to run tests
-CMD ["go", "test", "./..."]
+# Build
+RUN CGO_ENABLED=0 GOOS=linux go test -c -installsuffix cgo -o main ./cmd/globeboard
+
+# Use a minimal alpine image for the final build stage.
+FROM alpine:3.19
+
+# Install CA certificates.
+RUN apk --no-cache add ca-certificates
+
+WORKDIR /root/
+
+# Copy the pre-built binary file from the previous stage.
+COPY --from=builder /app/main .
+
+# Optional:
+# To bind to a TCP port, runtime parameters must be supplied to the docker command.
+# But we can document in the Dockerfile what ports
+# the application is going to listen on by default.
+# https://docs.docker.com/reference/dockerfile/#expose
+EXPOSE 8080
+
+# Run
+CMD ["./main"]
\ No newline at end of file
diff --git a/Go/cmd/globeboard/app_test.go b/Go/cmd/globeboard/app_test.go
index f509c8b..c0ed62b 100644
--- a/Go/cmd/globeboard/app_test.go
+++ b/Go/cmd/globeboard/app_test.go
@@ -11,446 +11,60 @@ import (
 	"testing"
 )
 
-var token = os.Getenv("TOKEN")
-
-// TestLibraryGet confirms that the Root Endpoint returns Status I'm a Teapot for All Request.
-func TestRoot(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Paths.Root, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(handlers.EmptyHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusTeapot {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusTeapot)
-	}
-
-	req, err = http.NewRequest("POST", Paths.Root, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusTeapot {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusTeapot)
-	}
-
-	req, err = http.NewRequest("PUT", Paths.Root, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusTeapot {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusTeapot)
-	}
-}
-
-// TestBookCountGetLanguage confirms that the Bookcount Endpoint returns Status Bas Request for Get Request without language param.
-func TestBookCountGet(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.Dashboards, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.DashboardsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusBadRequest {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusBadRequest)
-	}
-}
-
-// TestBookCountGetWrongKey confirms that the Bookcount Endpoint returns Status Not Accepted for GET Method with incorrect token.
-func TestBookCountGetWrongKey(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.Dashboards+"?token=c35c5742", nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.DashboardsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusNotAcceptable {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusNotAcceptable)
-	}
-}
-
-// TestBookCountGetLanguageNoKey confirms that the Bookcount Endpoint returns Status Bad Request for Get Request without api key.
-func TestBookCountGetLanguageNoKey(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.Dashboards+"?languages=no", nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.DashboardsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusBadRequest {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusBadRequest)
-	}
-}
-
-// TestBookCountGetLanguage confirms that the Bookcount Endpoint returns Status OK for Get Request with language param.
-func TestBookCountGetLanguage(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.Dashboards+"?token="+token+"&languages=no", nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.DashboardsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusOK {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusOK)
-	}
-}
-
-// TestBookCountGetLanguageWrong confirms that the Bookcount Endpoint returns Status Bad Request for Get Request with wrongful language param.
-func TestBookCountGetLanguageWrong(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.Dashboards+"?token="+token+"&languages=nog", nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.DashboardsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusBadRequest {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusBadRequest)
-	}
-}
-
-// TestBookCountGetLanguages confirms that the Bookcount Endpoint returns Status OK for Get Request with multiple language param.
-func TestBookCountGetLanguages(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.Dashboards+"?token="+token+"&languages=no,es", nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.DashboardsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusOK {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusOK)
-	}
-}
-
-// TestBookCountGetLanguagesWrong confirms that the Bookcount Endpoint returns Status Bad Request for Get Request with same language param.
-func TestBookCountGetLanguagesWrong(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.Dashboards+"?token="+token+"&languages=no,no", nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.DashboardsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusBadRequest {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusBadRequest)
-	}
-}
-
-// TestBookcountMethodNotAllowed confirms that the Bookcount Endpoint returns Status Not Implemented for Methods other than GET.
-func TestBookcountMethodNotAllowed(t *testing.T) {
-	// Create a request to your endpoint with a method other than GET
-	req, err := http.NewRequest("POST", Endpoints.Dashboards, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.DashboardsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusNotImplemented {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusNotImplemented)
-	}
-
-	req, err = http.NewRequest("PUT", Endpoints.Dashboards, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusNotImplemented {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusNotImplemented)
-	}
-}
-
-// TestReadershipGet confirms that the Notifications Endpoint returns Status Bas Request for Get Request without language param.
-func TestReadershipGet(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.Notifications+"?token="+token+"", nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.NotificationsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusBadRequest {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusBadRequest)
-	}
-}
-
-// TestSupportedLanguagesGetWrongKey confirms that the Notifications Endpoint returns Status Not Accepted for GET Method with incorrect token.
-func TestReadershipGetWrongKey(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.Notifications+"?token=c35c5742", nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.DashboardsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusNotAcceptable {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusNotAcceptable)
-	}
-}
-
-// TestReadershipGetLanguageNoKey confirms that the Notifications Endpoint returns Status Bad Request for Get Request without API Token.
-func TestReadershipGetLanguageNoKey(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.Notifications+"no", nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.NotificationsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusBadRequest {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusBadRequest)
-	}
-}
-
-// TestReadershipGetLanguage confirms that the Notifications Endpoint returns Status OK for Get Request with language param.
-func TestReadershipGetLanguage(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.Notifications+"no/?token="+token+"", nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.NotificationsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusOK {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusOK)
-	}
-}
-
-// TestReadershipGetWrong confirms that the Notifications Endpoint returns Status Bad Request for Get Request with wrongful language param.
-func TestReadershipGetWrong(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.Notifications+"nog/?token="+token+"", nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.NotificationsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusBadRequest {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusBadRequest)
-	}
-}
-
-// TestReadershipGetLanguages confirms that the Notifications Endpoint returns Status Bad Request for Get Request with multiple language param.
-func TestReadershipGetLanguages(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.Notifications+"no,es/?token="+token+"", nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.NotificationsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
+const (
+	DisplayName = "Tester Testing"
+	Email       = "Tester@Testing.test"
+	Password    = "TestTesting123?!"
+)
 
-	// Check the status code
-	if status := rr.Code; status != http.StatusBadRequest {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusBadRequest)
-	}
-}
+var (
+	token = os.Getenv("TOKEN")
+	ID    = ""
+)
 
-// TestReadershipGetLimit confirms that the Notifications Endpoint returns Status OK for Get Request with limit param.
-func TestReadershipGetLimit(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.Notifications+"no/?token="+token+"&limit=1", nil)
+func init() {
+	err := os.Setenv("GO_ENV", "test")
 	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.NotificationsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusOK {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusOK)
+		panic("Unable to set GO_ENV")
 	}
 }
 
-// TestReadershipGetLimitWrong confirms that the Notifications Endpoint returns Status Bad Request for Get Request with wrongful limit param.
-func TestReadershipGetLimitWrong(t *testing.T) {
+// TestRoot confirms that Root Endpoint returns 303 See Other for All Requests.
+func TestRoot(t *testing.T) {
 	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.Notifications+"no/?token="+token+"&limit=one", nil)
+	req, err := http.NewRequest("GET", Paths.Root, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
 
 	// Create a ResponseRecorder to record the response
 	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.NotificationsHandler)
+	handler := http.HandlerFunc(handlers.EmptyHandler)
 
 	// Serve the request to the handler
 	handler.ServeHTTP(rr, req)
 
 	// Check the status code
-	if status := rr.Code; status != http.StatusBadRequest {
+	if status := rr.Code; status != http.StatusSeeOther {
 		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusBadRequest)
+			status, http.StatusSeeOther)
 	}
-}
 
-// TestReadershipMethodNotAllowed confirms that the Notifications Endpoint returns Status Not Implemented for Methods other than GET.
-func TestReadershipMethodNotAllowed(t *testing.T) {
-	// Create a request to your endpoint with a method other than GET
-	req, err := http.NewRequest("POST", Endpoints.Notifications, nil)
+	req, err = http.NewRequest("POST", Paths.Root, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.NotificationsHandler)
-
 	// Serve the request to the handler
 	handler.ServeHTTP(rr, req)
 
 	// Check the status code
-	if status := rr.Code; status != http.StatusNotImplemented {
+	if status := rr.Code; status != http.StatusSeeOther {
 		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusNotImplemented)
+			status, http.StatusSeeOther)
 	}
 
-	req, err = http.NewRequest("PUT", Endpoints.Notifications, nil)
+	req, err = http.NewRequest("PUT", Paths.Root, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -459,13 +73,13 @@ func TestReadershipMethodNotAllowed(t *testing.T) {
 	handler.ServeHTTP(rr, req)
 
 	// Check the status code
-	if status := rr.Code; status != http.StatusNotImplemented {
+	if status := rr.Code; status != http.StatusSeeOther {
 		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusNotImplemented)
+			status, http.StatusSeeOther)
 	}
 }
 
-// TestStatusGetNoKey confirms that the Status Endpoint returns Status Bad Request for GET Method without API token.
+// TestStatusGetNoKey confirms that the Status Endpoint returns Status Bad Request for GET Method without an API token.
 func TestStatusGetNoKey(t *testing.T) {
 	// Create a request to your endpoint with the GET method
 	req, err := http.NewRequest("GET", Endpoints.Status, nil)
@@ -481,9 +95,9 @@ func TestStatusGetNoKey(t *testing.T) {
 	handler.ServeHTTP(rr, req)
 
 	// Check the status code
-	if status := rr.Code; status != http.StatusBadRequest {
+	if status := rr.Code; status != http.StatusUnauthorized {
 		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusBadRequest)
+			status, http.StatusUnauthorized)
 	}
 }
 
@@ -566,105 +180,3 @@ func TestStatusMethodNotAllowed(t *testing.T) {
 			status, http.StatusNotImplemented)
 	}
 }
-
-// TestSupportedLanguagesGetNoKey confirms that the Supported Languages Endpoint returns Status Bad Requests for GET Method without API token.
-func TestSupportedLanguagesGetNoKey(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.RegistrationsID, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.RegistrationsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusBadRequest {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusBadRequest)
-	}
-}
-
-// TestSupportedLanguagesGet confirms that the Supported Languages Endpoint returns Status OK for GET Method.
-func TestSupportedLanguagesGet(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.RegistrationsID+"?token="+token+"", nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.RegistrationsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusOK {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusOK)
-	}
-}
-
-// TestSupportedLanguagesGetWrongKey confirms that the Supported Languages Endpoint returns Status Not Accepted for GET Method with incorrect token.
-func TestSupportedLanguagesGetWrongKey(t *testing.T) {
-	// Create a request to your endpoint with the GET method
-	req, err := http.NewRequest("GET", Endpoints.RegistrationsID+"?token=c35c5742", nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.RegistrationsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusNotAcceptable {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusNotAcceptable)
-	}
-}
-
-// TestSupportedLanguagesMethodNotAllowed confirms that the Supported Languages Endpoint returns Status Not Implemented for Methods other than GET.
-func TestSupportedLanguagesMethodNotAllowed(t *testing.T) {
-	// Create a request to your endpoint with a method other than GET
-	req, err := http.NewRequest("POST", Endpoints.RegistrationsID, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Create a ResponseRecorder to record the response
-	rr := httptest.NewRecorder()
-	handler := http.HandlerFunc(dashboard.RegistrationsHandler)
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusNotImplemented {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusNotImplemented)
-	}
-
-	req, err = http.NewRequest("PUT", Endpoints.RegistrationsID, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Serve the request to the handler
-	handler.ServeHTTP(rr, req)
-
-	// Check the status code
-	if status := rr.Code; status != http.StatusNotImplemented {
-		t.Errorf("handler returned wrong status code: got %v want %v",
-			status, http.StatusNotImplemented)
-	}
-}
diff --git a/Go/db/db.go b/Go/db/db.go
index c714816..917c375 100644
--- a/Go/db/db.go
+++ b/Go/db/db.go
@@ -193,7 +193,6 @@ func DeleteApiKey(apiKey string) error {
 		return fmt.Errorf("failed to delete API Key: %v", err)
 	}
 
-	log.Printf("API key %s deleted successfully\n", apiKey)
 	return nil
 }
 
diff --git a/Go/docker-compose.yml b/Go/docker-compose.yml
index cdc84e0..ae4e68f 100644
--- a/Go/docker-compose.yml
+++ b/Go/docker-compose.yml
@@ -1,7 +1,18 @@
-version: '3.8'
+version: "3.8"
 
 services:
+  globeboard-test:
+    image: go-globeboard-test:latest
+    build:
+      context: .
+      dockerfile: Dockerfile-test
+    environment:
+      - TOKEN=${TOKEN}
+    volumes:
+      - ./.secrets:/root/.secrets:ro
+      - ./web:/root/web:ro
   globeboard:
+    image: go-globeboard:latest
     build:
       context: .
       dockerfile: Dockerfile
@@ -12,9 +23,7 @@ services:
       - TOKEN=${TOKEN}
     volumes:
       - ./.secrets:/root/.secrets:ro
-  globeboard-test:
-    build:
-      context: .
-      dockerfile: Dockerfile-test
+      - ./web:/root/web:ro
     depends_on:
-      - globeboard
\ No newline at end of file
+      globeboard-test:
+        condition: service_completed_successfully
\ No newline at end of file
diff --git a/Go/internal/handlers/endpoint/dashboard/dashboards_handler.go b/Go/internal/handlers/endpoint/dashboard/dashboards_handler.go
index 82178e1..5cad818 100644
--- a/Go/internal/handlers/endpoint/dashboard/dashboards_handler.go
+++ b/Go/internal/handlers/endpoint/dashboard/dashboards_handler.go
@@ -9,6 +9,7 @@ import (
 	"globeboard/internal/utils/structs"
 	"log"
 	"net/http"
+	"os"
 	"strconv"
 	"time"
 )
@@ -93,7 +94,9 @@ func handleDashboardGetRequest(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	_func.LoopSendWebhooksDashboard(UUID, dr)
+	if os.Getenv("GO_ENV") != "test" {
+		_func.LoopSendWebhooksDashboard(UUID, dr)
+	}
 }
 
 func getWeatherInfo(w http.ResponseWriter, reg *structs.CountryInfoGet, dr *structs.DashboardResponse) bool {
diff --git a/Go/internal/handlers/endpoint/dashboard/registrations_handler.go b/Go/internal/handlers/endpoint/dashboard/registrations_handler.go
index 3835b43..c2fffd4 100644
--- a/Go/internal/handlers/endpoint/dashboard/registrations_handler.go
+++ b/Go/internal/handlers/endpoint/dashboard/registrations_handler.go
@@ -13,6 +13,7 @@ import (
 	"io"
 	"log"
 	"net/http"
+	"os"
 )
 
 const (
@@ -116,8 +117,9 @@ func handleRegPostRequest(w http.ResponseWriter, r *http.Request) {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-
-	_func.LoopSendWebhooksRegistrations(UUID, reg, Endpoints.Registrations, Webhooks.EventRegister)
+	if os.Getenv("GO_ENV") != "test" {
+		_func.LoopSendWebhooksRegistrations(UUID, reg, Endpoints.Registrations, Webhooks.EventRegister)
+	}
 }
 
 // handleRegGetAllRequest handles GET requests to retrieve a registered country.
@@ -154,8 +156,9 @@ func handleRegGetAllRequest(w http.ResponseWriter, r *http.Request) {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-
-	for _, reg := range regs {
-		_func.LoopSendWebhooksRegistrations(UUID, reg, Endpoints.Registrations, Webhooks.EventInvoke)
+	if os.Getenv("GO_ENV") != "test" {
+		for _, reg := range regs {
+			_func.LoopSendWebhooksRegistrations(UUID, reg, Endpoints.Registrations, Webhooks.EventInvoke)
+		}
 	}
 }
diff --git a/Go/internal/handlers/endpoint/dashboard/registrations_id_handler.go b/Go/internal/handlers/endpoint/dashboard/registrations_id_handler.go
index 949e0bb..1fb8f84 100644
--- a/Go/internal/handlers/endpoint/dashboard/registrations_id_handler.go
+++ b/Go/internal/handlers/endpoint/dashboard/registrations_id_handler.go
@@ -12,6 +12,7 @@ import (
 	"io"
 	"log"
 	"net/http"
+	"os"
 )
 
 const (
@@ -74,7 +75,9 @@ func handleRegGetRequest(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	_func.LoopSendWebhooksRegistrations(UUID, reg, Endpoints.RegistrationsID, Webhooks.EventInvoke)
+	if os.Getenv("GO_ENV") != "test" {
+		_func.LoopSendWebhooksRegistrations(UUID, reg, Endpoints.RegistrationsID, Webhooks.EventInvoke)
+	}
 }
 
 // handleRegPatchRequest handles PUT requests to Update a registered country.
@@ -125,7 +128,9 @@ func handleRegPatchRequest(w http.ResponseWriter, r *http.Request) {
 
 	w.WriteHeader(http.StatusAccepted)
 
-	_func.LoopSendWebhooksRegistrations(UUID, countryInfo, Endpoints.RegistrationsID, Webhooks.EventChange)
+	if os.Getenv("GO_ENV") != "test" {
+		_func.LoopSendWebhooksRegistrations(UUID, countryInfo, Endpoints.RegistrationsID, Webhooks.EventChange)
+	}
 }
 
 func patchCountryInformation(r *http.Request, ID, UUID string) (*structs.CountryInfoGet, error, int) {
@@ -244,5 +249,7 @@ func handleRegDeleteRequest(w http.ResponseWriter, r *http.Request) {
 
 	w.WriteHeader(http.StatusNoContent)
 
-	_func.LoopSendWebhooksRegistrations(UUID, reg, Endpoints.RegistrationsID, Webhooks.EventDelete)
+	if os.Getenv("GO_ENV") != "test" {
+		_func.LoopSendWebhooksRegistrations(UUID, reg, Endpoints.RegistrationsID, Webhooks.EventDelete)
+	}
 }
diff --git a/Go/internal/handlers/endpoint/dashboard/status_handler.go b/Go/internal/handlers/endpoint/dashboard/status_handler.go
index fbfdc2a..553a162 100644
--- a/Go/internal/handlers/endpoint/dashboard/status_handler.go
+++ b/Go/internal/handlers/endpoint/dashboard/status_handler.go
@@ -57,7 +57,7 @@ func StatusHandler(w http.ResponseWriter, r *http.Request) {
 func handleStatusGetRequest(w http.ResponseWriter, r *http.Request) {
 	token := r.URL.Query().Get("token")
 	if token == "" {
-		http.Error(w, "Please provide API Token", http.StatusBadRequest)
+		http.Error(w, "Please provide API Token", http.StatusUnauthorized)
 		return
 	}
 	UUID := db.GetAPIKeyUUID(token)
diff --git a/Go/web/root.html b/Go/web/root.html
index de51d6d..2c7c6ef 100644
--- a/Go/web/root.html
+++ b/Go/web/root.html
@@ -8,12 +8,14 @@
 <div>
     <h2>This service does not provide any functionality on root level.</h2>
     <h3>Please use endpoints:</h3>
-    <a href="/dashboard/v1/registrations">/dashboard/v1/registrations</a>
-    <a href="/dashboard/v1/dashboards">/dashboard/v1/dashboards</a>
-    <a href="/dashboard/v1/notifications">/dashboard/v1/notifications</a>
-    <a href="/dashboard/v1/status">/dashboard/v1/status</a>
+    <a href="/dashboards/v1/registrations">/dashboards/v1/registrations</a>
+    <a href="/dashboards/v1/dashboard">/dashboards/v1/dashboard</a>
+    <a href="/dashboards/v1/notifications">/dashboards/v1/notifications</a>
+    <a href="/dashboards/v1/status">/dashboards/v1/status</a>
     <h3>Before you can access the endpoints, please register as a user to acquire an API key:</h3>
-    <a href="/util/v1/register">/util/v1/register</a>
+    <a href="/util/v1/user/register">/util/v1/user/register</a>
+    <h3>If you want to delete your user account, refer to:</h3>
+    <a href="/util/v1/user/delete">/util/v1/user/delete</a>
     <h3>Please Refer to Git Repo for documentation:<a href="https://git.gvk.idi.ntnu.no/course/prog2005/prog2005-2024-workspace/nintendo_alex/globeboard">NTNU Gjøvik GitLab</a></h3>
 </div>
 </body>
-- 
GitLab