Skip to content

Commit 132d4da

Browse files
committed
fix api client error handling, add tests
1 parent 7f93f0d commit 132d4da

File tree

3 files changed

+99
-12
lines changed

3 files changed

+99
-12
lines changed

.github/workflows/test.yml

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,13 @@ jobs:
2929
run: |
3030
go build -v .
3131
32-
# run acceptance tests in a matrix with Terraform core versions
32+
# run acceptance tests
3333
test:
34-
name: Matrix Test
34+
name: Test
3535
needs: build
3636
runs-on: ubuntu-latest
3737
environment: "acceptance tests"
3838
timeout-minutes: 15
39-
strategy:
40-
fail-fast: false
41-
matrix:
42-
# list whatever Terraform versions here you would like to support
43-
terraform:
44-
- '1.5.7'
4539
steps:
4640

4741
- name: Set up Go
@@ -57,6 +51,9 @@ jobs:
5751
run: |
5852
go mod download
5953
54+
- name: Unit tests
55+
run: go test -v -cover ./...
56+
6057
- name: Boot services for acceptance tests
6158
run: docker compose -f scripts/docker-compose.yaml up --wait -d
6259
env:
@@ -65,7 +62,7 @@ jobs:
6562
timeout-minutes: 10
6663
env:
6764
TF_ACC: "1"
68-
TF_ACC_TERRAFORM_VERSION: ${{ matrix.terraform }}
65+
TF_ACC_TERRAFORM_VERSION: '1.5.7'
6966

7067
# Set whatever additional acceptance test env vars here. You can
7168
# optionally use data from your repository secrets using the

aidbox/api_client.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,18 @@ func (apiClient *ApiClient) addAuthAndHost(req *http.Request) {
128128
func errorToTerraform(request *http.Request, response *http.Response, requestBody interface{}, responseBody []byte) error {
129129
var sensitiveDetails = ""
130130
var prettyResponse bytes.Buffer
131-
err := json.Indent(&prettyResponse, responseBody, "", " ")
132-
if err != nil {
133-
panic(err)
131+
jsonParseErr := json.Indent(&prettyResponse, responseBody, "", " ")
132+
if jsonParseErr != nil {
133+
return fmt.Errorf("unexpected status code (%d) received: %s\n\n"+
134+
"===== %s %s =====\n\n"+
135+
"===== RESPONSE BODY =====\n"+
136+
"%s\n",
137+
response.StatusCode,
138+
response.Status,
139+
request.Method, request.URL.String(),
140+
string(responseBody))
134141
}
142+
135143
if os.Getenv("TF_ACC") == "1" {
136144
prettyRequest, err := json.MarshalIndent(requestBody, "", " ")
137145
if err != nil {

aidbox/api_client_test.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package aidbox
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"github.com/stretchr/testify/assert"
7+
"net/http"
8+
"net/http/httptest"
9+
"testing"
10+
)
11+
12+
type TestResponse struct {
13+
Name string `json:"name"`
14+
Value int `json:"value"`
15+
}
16+
17+
func TestApiClient(t *testing.T) {
18+
t.Run("Should call the correct endpoint and deserialise to an interface", func(t *testing.T) {
19+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
20+
w.WriteHeader(200)
21+
w.Write([]byte("{\"name\": \"Lord Vetinari\", \"value\": 8}"))
22+
}))
23+
24+
client := NewApiClient(server.URL, "foo", "bar")
25+
response := &TestResponse{}
26+
err := client.post(context.TODO(), "", "/endpoint", response)
27+
28+
assert.Equal(t, nil, err)
29+
assert.Equal(t, TestResponse{"Lord Vetinari", 8}, *response)
30+
})
31+
32+
t.Run("should log an error response that isn't JSON", func(t *testing.T) {
33+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
34+
w.WriteHeader(502)
35+
w.Write([]byte("Service Unavailable"))
36+
}))
37+
38+
client := NewApiClient(server.URL, "foo", "bar")
39+
err := client.post(context.TODO(), "", "/endpoint", "")
40+
41+
expectedError := fmt.Sprintf(`unexpected status code (502) received: 502 Bad Gateway
42+
43+
===== POST %s/endpoint =====
44+
45+
===== RESPONSE BODY =====
46+
Service Unavailable
47+
`, server.URL)
48+
49+
assert.Equal(t, expectedError, err.Error())
50+
})
51+
52+
t.Run("should pretty-print a JSON error response", func(t *testing.T) {
53+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
54+
w.WriteHeader(422)
55+
w.Write([]byte("{ \"name\": \"Ankh-Morpork City Watch\", \"type\": \"Organisation\", \"members\": [\"Sam Vimes\", \"Fred Colon\", \"Nobby Nobbs\", \"Cheery Littlebottom\", \"Detritus\", \"Reg Shoe\"] }"))
56+
}))
57+
58+
client := NewApiClient(server.URL, "foo", "bar")
59+
err := client.post(context.TODO(), "", "/endpoint", "")
60+
61+
expectedError := fmt.Sprintf(`unexpected status code (422) received: 422 Unprocessable Entity
62+
63+
===== POST %s/endpoint =====
64+
65+
===== RESPONSE BODY =====
66+
{
67+
"name": "Ankh-Morpork City Watch",
68+
"type": "Organisation",
69+
"members": [
70+
"Sam Vimes",
71+
"Fred Colon",
72+
"Nobby Nobbs",
73+
"Cheery Littlebottom",
74+
"Detritus",
75+
"Reg Shoe"
76+
]
77+
}
78+
`, server.URL)
79+
80+
assert.Equal(t, expectedError, err.Error())
81+
})
82+
}

0 commit comments

Comments
 (0)