From d6b0f381b20bffd09a91ba6564372c6ba2f1cceb Mon Sep 17 00:00:00 2001 From: Gewnthar Date: Thu, 20 Nov 2025 20:48:45 -0500 Subject: [PATCH 1/8] undo Lane's giant mistake --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c2bec0368b..c99a8fa9b8 100644 --- a/README.md +++ b/README.md @@ -21,3 +21,5 @@ go build -o notely && ./notely *This starts the server in non-database mode.* It will serve a simple webpage at `http://localhost:8080`. You do *not* need to set up a database or any interactivity on the webpage yet. Instructions for that will come later in the course! + +Gewnthar's version of a Boot.dev's Notely app From e68f335545d9599b985b5b1f1b398878f0e974f0 Mon Sep 17 00:00:00 2001 From: Gewnthar Date: Thu, 20 Nov 2025 21:14:22 -0500 Subject: [PATCH 2/8] .github/workflows/ci.yml added --- .github/workflows/ci.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..249cc5258a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,22 @@ +name: ci + +on: + pull_request: + branches: [main] + +jobs: + tests: + name: Tests + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: "1.25.1" + + - name: Force Failure + run: (exit 1) From 73922bbd3d3e916ff071db1dcd76c9a5700fb20a Mon Sep 17 00:00:00 2001 From: Gewnthar Date: Thu, 20 Nov 2025 21:21:22 -0500 Subject: [PATCH 3/8] .github/workflows/ci.yml fix added --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 249cc5258a..1f9c36a76a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,4 +19,4 @@ jobs: go-version: "1.25.1" - name: Force Failure - run: (exit 1) + run: go version From e533f9ae96d7a50d156267a7a99e1a0d6d46f336 Mon Sep 17 00:00:00 2001 From: Gewnthar Date: Thu, 20 Nov 2025 21:52:00 -0500 Subject: [PATCH 4/8] add ci tests and break code --- .github/workflows/ci.yml | 4 +-- internal/auth/auth.go | 69 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f9c36a76a..94478eea04 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,5 +18,5 @@ jobs: with: go-version: "1.25.1" - - name: Force Failure - run: go version + - name: run tests + run: go test ./.. diff --git a/internal/auth/auth.go b/internal/auth/auth.go index f969aacf63..d41a7e6c00 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -4,6 +4,7 @@ import ( "errors" "net/http" "strings" + "testing" ) var ErrNoAuthHeaderIncluded = errors.New("no authorization header included") @@ -15,9 +16,75 @@ func GetAPIKey(headers http.Header) (string, error) { return "", ErrNoAuthHeaderIncluded } splitAuth := strings.Split(authHeader, " ") - if len(splitAuth) < 2 || splitAuth[0] != "ApiKey" { + if len(splitAuth) < 2 || splitAuth[0] != "ApiKeyBROKEN" { return "", errors.New("malformed authorization header") } return splitAuth[1], nil } + +func TestGetAPIKey(t *testing.T) { + tests := []struct { + name string + headers http.Header + expectedKey string + expectedError error + }{ + { + name: "Valid API Key", + headers: http.Header{ + "Authorization": []string{"ApiKey my-secret-api-key"}, + }, + expectedKey: "my-secret-api-key", + expectedError: nil, + }, + { + name: "No Authorization Header", + headers: http.Header{}, + expectedKey: "", + expectedError: ErrNoAuthHeaderIncluded, + }, + { + name: "Malformed Authorization Header", + headers: http.Header{ + "Authorization": []string{"Bearer my-secret-api-key"}, + }, + expectedKey: "", + // We don't have a specific variable for the malformed error in the code you shared, + // so we expect any error here. + expectedError: nil, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + key, err := GetAPIKey(tc.headers) + + // 1. Check if we expected a specific error variable (like ErrNoAuthHeaderIncluded) + if tc.expectedError != nil { + if err != tc.expectedError { + t.Errorf("expected error %v, got %v", tc.expectedError, err) + } + return + } + + // 2. Handle the case where we expect an error, but not a specific variable (the malformed case) + // In the table above, I set expectedError to nil for the malformed case to simplify, + // but we know it should fail. Let's handle that logic specifically: + if tc.name == "Malformed Authorization Header" { + if err == nil { + t.Error("expected an error for malformed header, but got none") + } + return + } + + // 3. Standard success case + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if key != tc.expectedKey { + t.Errorf("expected key %v, got %v", tc.expectedKey, key) + } + }) + } +} From 88860e77dbbc45f00e334db6c5197829664e8324 Mon Sep 17 00:00:00 2001 From: Gewnthar Date: Thu, 20 Nov 2025 21:56:09 -0500 Subject: [PATCH 5/8] add ci tests and break code fix ci.yml --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 94478eea04..ce1eb52ca8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,4 +19,4 @@ jobs: go-version: "1.25.1" - name: run tests - run: go test ./.. + run: go test ./... From 233c255e8ba90259f647ae35a0a1341d92b132d7 Mon Sep 17 00:00:00 2001 From: Gewnthar Date: Thu, 20 Nov 2025 22:00:24 -0500 Subject: [PATCH 6/8] fix: separate tests into correct file --- internal/auth/auth.go | 69 +------------------------------------- internal/auth/auth_test.go | 62 ++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 68 deletions(-) create mode 100644 internal/auth/auth_test.go diff --git a/internal/auth/auth.go b/internal/auth/auth.go index d41a7e6c00..f969aacf63 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -4,7 +4,6 @@ import ( "errors" "net/http" "strings" - "testing" ) var ErrNoAuthHeaderIncluded = errors.New("no authorization header included") @@ -16,75 +15,9 @@ func GetAPIKey(headers http.Header) (string, error) { return "", ErrNoAuthHeaderIncluded } splitAuth := strings.Split(authHeader, " ") - if len(splitAuth) < 2 || splitAuth[0] != "ApiKeyBROKEN" { + if len(splitAuth) < 2 || splitAuth[0] != "ApiKey" { return "", errors.New("malformed authorization header") } return splitAuth[1], nil } - -func TestGetAPIKey(t *testing.T) { - tests := []struct { - name string - headers http.Header - expectedKey string - expectedError error - }{ - { - name: "Valid API Key", - headers: http.Header{ - "Authorization": []string{"ApiKey my-secret-api-key"}, - }, - expectedKey: "my-secret-api-key", - expectedError: nil, - }, - { - name: "No Authorization Header", - headers: http.Header{}, - expectedKey: "", - expectedError: ErrNoAuthHeaderIncluded, - }, - { - name: "Malformed Authorization Header", - headers: http.Header{ - "Authorization": []string{"Bearer my-secret-api-key"}, - }, - expectedKey: "", - // We don't have a specific variable for the malformed error in the code you shared, - // so we expect any error here. - expectedError: nil, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - key, err := GetAPIKey(tc.headers) - - // 1. Check if we expected a specific error variable (like ErrNoAuthHeaderIncluded) - if tc.expectedError != nil { - if err != tc.expectedError { - t.Errorf("expected error %v, got %v", tc.expectedError, err) - } - return - } - - // 2. Handle the case where we expect an error, but not a specific variable (the malformed case) - // In the table above, I set expectedError to nil for the malformed case to simplify, - // but we know it should fail. Let's handle that logic specifically: - if tc.name == "Malformed Authorization Header" { - if err == nil { - t.Error("expected an error for malformed header, but got none") - } - return - } - - // 3. Standard success case - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if key != tc.expectedKey { - t.Errorf("expected key %v, got %v", tc.expectedKey, key) - } - }) - } -} diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go new file mode 100644 index 0000000000..2f84eafd95 --- /dev/null +++ b/internal/auth/auth_test.go @@ -0,0 +1,62 @@ +package auth + +import ( + "net/http" + "testing" +) + +func TestGetAPIKey(t *testing.T) { + tests := []struct { + name string + headers http.Header + expectedKey string + expectedError error + }{ + { + name: "Valid API Key", + headers: http.Header{ + "Authorization": []string{"ApiKey my-secret-api-key"}, + }, + expectedKey: "my-secret-api-key", + expectedError: nil, + }, + { + name: "No Authorization Header", + headers: http.Header{}, + expectedKey: "", + expectedError: ErrNoAuthHeaderIncluded, + }, + { + name: "Malformed Authorization Header", + headers: http.Header{ + "Authorization": []string{"Bearer my-secret-api-key"}, + }, + expectedKey: "", + expectedError: nil, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + key, err := GetAPIKey(tc.headers) + if tc.expectedError != nil { + if err != tc.expectedError { + t.Errorf("expected error %v, got %v", tc.expectedError, err) + } + return + } + if tc.name == "Malformed Authorization Header" { + if err == nil { + t.Error("expected an error for malformed header, but got none") + } + return + } + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if key != tc.expectedKey { + t.Errorf("expected key %v, got %v", tc.expectedKey, key) + } + }) + } +} From 491c27e0fa9a19eac6c2509a5ef3021aac27429b Mon Sep 17 00:00:00 2001 From: Gewnthar Date: Thu, 20 Nov 2025 22:03:46 -0500 Subject: [PATCH 7/8] ci: add code coverage flag --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ce1eb52ca8..3938afaa13 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,4 +19,4 @@ jobs: go-version: "1.25.1" - name: run tests - run: go test ./... + run: go test -cover ./... From c7de13858f2bfbf0105a9456db2d96cba3299da7 Mon Sep 17 00:00:00 2001 From: Gewnthar Date: Thu, 20 Nov 2025 22:08:05 -0500 Subject: [PATCH 8/8] docs: add build status badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c99a8fa9b8..5c2290e4b3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +![Tests](https://github.com/gewnthar/cicd/actions/workflows/ci.yml/badge.svg) # learn-cicd-starter (Notely) This repo contains the starter code for the "Notely" application for the "Learn CICD" course on [Boot.dev](https://boot.dev).