From a55deb424d1c2794cfc96267a7b1f659b26cf549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20LAURENT?= <181494736+SebastienLaurent-CF@users.noreply.github.com> Date: Fri, 28 Nov 2025 08:40:47 +0100 Subject: [PATCH 1/4] =?UTF-8?q?=E2=9C=85=20test:=20improve=20coverage=20fo?= =?UTF-8?q?r=20oidc=20and=20env=20packages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add unit tests for `internal/oidc` using mock HTTP server. - Add tests for `Get` and `Find` in `internal/env`. - Increase total test coverage to ~57%. --- internal/env/env_test.go | 46 +++++++++++++++ internal/oidc/client_test.go | 105 +++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 internal/oidc/client_test.go diff --git a/internal/env/env_test.go b/internal/env/env_test.go index 635307e..f0df41b 100644 --- a/internal/env/env_test.go +++ b/internal/env/env_test.go @@ -92,3 +92,49 @@ func TestManager_Update(t *testing.T) { }) } } + +func TestManager_Get(t *testing.T) { + tmpDir := t.TempDir() + envFile := filepath.Join(tmpDir, ".env") + err := os.WriteFile(envFile, []byte("KEY=VALUE\n"), 0644) + if err != nil { + t.Fatal(err) + } + + m := NewManager(envFile, "KEY") + val, err := m.Get() + if err != nil { + t.Fatalf("Get() error = %v", err) + } + if val != "VALUE" { + t.Errorf("Get() = %s, want VALUE", val) + } + + m2 := NewManager(envFile, "MISSING") + _, err = m2.Get() + if err == nil { + t.Error("Get() expected error for missing key, got nil") + } +} + +func TestFind(t *testing.T) { + tmpDir := t.TempDir() + subdir := filepath.Join(tmpDir, "subdir") + os.Mkdir(subdir, 0755) + + envFile := filepath.Join(tmpDir, ".env") + os.WriteFile(envFile, []byte(""), 0644) + + // Test finding from subdir + wd, _ := os.Getwd() + defer os.Chdir(wd) + os.Chdir(subdir) + + found, err := Find(".env") + if err != nil { + t.Fatalf("Find() error = %v", err) + } + if found != envFile { + t.Errorf("Find() = %s, want %s", found, envFile) + } +} diff --git a/internal/oidc/client_test.go b/internal/oidc/client_test.go new file mode 100644 index 0000000..4f8d4b0 --- /dev/null +++ b/internal/oidc/client_test.go @@ -0,0 +1,105 @@ +package oidc + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/codozor/authk/internal/config" +) + +func TestClient_GetToken(t *testing.T) { + // Mock OIDC Provider + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/.well-known/openid-configuration": + json.NewEncoder(w).Encode(map[string]string{ + "token_endpoint": "http://" + r.Host + "/token", + }) + case "/token": + if err := r.ParseForm(); err != nil { + t.Error(err) + } + if r.Form.Get("grant_type") == "client_credentials" { + json.NewEncoder(w).Encode(TokenResponse{ + AccessToken: "mock_access_token", + ExpiresIn: 3600, + TokenType: "Bearer", + }) + } else { + w.WriteHeader(http.StatusBadRequest) + } + default: + w.WriteHeader(http.StatusNotFound) + } + })) + defer ts.Close() + + cfg := &config.Config{ + OIDC: config.OIDCConfig{ + IssuerURL: ts.URL, + ClientID: "client", + ClientSecret: "secret", + AuthMethod: "basic", + }, + } + + client, err := NewClient(cfg) + if err != nil { + t.Fatalf("NewClient() error = %v", err) + } + + token, err := client.GetToken("", "") + if err != nil { + t.Fatalf("GetToken() error = %v", err) + } + + if token.AccessToken != "mock_access_token" { + t.Errorf("expected access token 'mock_access_token', got %s", token.AccessToken) + } +} + +func TestClient_RefreshToken(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/.well-known/openid-configuration": + json.NewEncoder(w).Encode(map[string]string{ + "token_endpoint": "http://" + r.Host + "/token", + }) + case "/token": + if err := r.ParseForm(); err != nil { + t.Error(err) + } + if r.Form.Get("grant_type") == "refresh_token" && r.Form.Get("refresh_token") == "valid_refresh" { + json.NewEncoder(w).Encode(TokenResponse{ + AccessToken: "new_access_token", + ExpiresIn: 3600, + }) + } else { + w.WriteHeader(http.StatusBadRequest) + } + } + })) + defer ts.Close() + + cfg := &config.Config{ + OIDC: config.OIDCConfig{ + IssuerURL: ts.URL, + }, + } + + client, err := NewClient(cfg) + if err != nil { + t.Fatalf("NewClient() error = %v", err) + } + + token, err := client.RefreshToken("valid_refresh") + if err != nil { + t.Fatalf("RefreshToken() error = %v", err) + } + + if token.AccessToken != "new_access_token" { + t.Errorf("expected access token 'new_access_token', got %s", token.AccessToken) + } +} From 8f83410e7d160b24c102f6bed9ca31a976dc3745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20LAURENT?= <181494736+SebastienLaurent-CF@users.noreply.github.com> Date: Fri, 28 Nov 2025 08:54:03 +0100 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=90=9B=20fix(test):=20handle=20unchec?= =?UTF-8?q?ked=20errors=20in=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Check return errors for `os` and `json` functions in tests. - Fix linter warnings (errcheck). --- internal/env/env_test.go | 21 ++++++++++++++++----- internal/oidc/client_test.go | 12 ++++++++---- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/internal/env/env_test.go b/internal/env/env_test.go index f0df41b..6022066 100644 --- a/internal/env/env_test.go +++ b/internal/env/env_test.go @@ -120,15 +120,26 @@ func TestManager_Get(t *testing.T) { func TestFind(t *testing.T) { tmpDir := t.TempDir() subdir := filepath.Join(tmpDir, "subdir") - os.Mkdir(subdir, 0755) + if err := os.Mkdir(subdir, 0755); err != nil { + t.Fatal(err) + } envFile := filepath.Join(tmpDir, ".env") - os.WriteFile(envFile, []byte(""), 0644) + if err := os.WriteFile(envFile, []byte(""), 0644); err != nil { + t.Fatal(err) + } // Test finding from subdir - wd, _ := os.Getwd() - defer os.Chdir(wd) - os.Chdir(subdir) + wd, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + defer func() { + _ = os.Chdir(wd) + }() + if err := os.Chdir(subdir); err != nil { + t.Fatal(err) + } found, err := Find(".env") if err != nil { diff --git a/internal/oidc/client_test.go b/internal/oidc/client_test.go index 4f8d4b0..b921c09 100644 --- a/internal/oidc/client_test.go +++ b/internal/oidc/client_test.go @@ -22,11 +22,13 @@ func TestClient_GetToken(t *testing.T) { t.Error(err) } if r.Form.Get("grant_type") == "client_credentials" { - json.NewEncoder(w).Encode(TokenResponse{ + if err := json.NewEncoder(w).Encode(TokenResponse{ AccessToken: "mock_access_token", ExpiresIn: 3600, TokenType: "Bearer", - }) + }); err != nil { + t.Error(err) + } } else { w.WriteHeader(http.StatusBadRequest) } @@ -72,10 +74,12 @@ func TestClient_RefreshToken(t *testing.T) { t.Error(err) } if r.Form.Get("grant_type") == "refresh_token" && r.Form.Get("refresh_token") == "valid_refresh" { - json.NewEncoder(w).Encode(TokenResponse{ + if err := json.NewEncoder(w).Encode(TokenResponse{ AccessToken: "new_access_token", ExpiresIn: 3600, - }) + }); err != nil { + t.Error(err) + } } else { w.WriteHeader(http.StatusBadRequest) } From 0359c3567bd6208b88bb9284c43f9db0a556b9cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20LAURENT?= <181494736+SebastienLaurent-CF@users.noreply.github.com> Date: Fri, 28 Nov 2025 08:56:55 +0100 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=90=9B=20fix(test):=20handle=20unchec?= =?UTF-8?q?ked=20errors=20in=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Check return errors for `os` and `json` functions in tests. - Fix linter warnings (errcheck). --- internal/oidc/client_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/oidc/client_test.go b/internal/oidc/client_test.go index b921c09..3e93c03 100644 --- a/internal/oidc/client_test.go +++ b/internal/oidc/client_test.go @@ -14,9 +14,11 @@ func TestClient_GetToken(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case "/.well-known/openid-configuration": - json.NewEncoder(w).Encode(map[string]string{ + if err := json.NewEncoder(w).Encode(map[string]string{ "token_endpoint": "http://" + r.Host + "/token", - }) + }); err != nil { + t.Error(err) + } case "/token": if err := r.ParseForm(); err != nil { t.Error(err) From e10622e470c7e33589b27d400adb3e1f82bd4c28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20LAURENT?= <181494736+SebastienLaurent-CF@users.noreply.github.com> Date: Fri, 28 Nov 2025 09:01:01 +0100 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=90=9B=20fix(test):=20fix=20remaining?= =?UTF-8?q?=20errors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/oidc/client_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/oidc/client_test.go b/internal/oidc/client_test.go index 3e93c03..d25fbdf 100644 --- a/internal/oidc/client_test.go +++ b/internal/oidc/client_test.go @@ -68,9 +68,11 @@ func TestClient_RefreshToken(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case "/.well-known/openid-configuration": - json.NewEncoder(w).Encode(map[string]string{ + if err := json.NewEncoder(w).Encode(map[string]string{ "token_endpoint": "http://" + r.Host + "/token", - }) + }); err != nil { + t.Error(err) + } case "/token": if err := r.ParseForm(); err != nil { t.Error(err)