|
1 | 1 | package response |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "bytes" |
| 5 | + "io" |
4 | 6 | "net/http" |
5 | | - "net/http/httptest" |
| 7 | + "net/url" |
| 8 | + "strings" |
6 | 9 | "testing" |
7 | 10 |
|
8 | 11 | "github.com/deploymenttheory/go-api-http-client/mocklogger" |
9 | | - "github.com/stretchr/testify/assert" |
10 | | - "github.com/stretchr/testify/mock" |
11 | 12 | ) |
12 | 13 |
|
13 | | -// MockLogger is a mock type for the Logger interface, useful for testing without needing a real logger implementation. |
14 | | -type MockLogger struct { |
15 | | - mock.Mock |
16 | | -} |
17 | | - |
18 | | -func (m *MockLogger) Error(msg string, fields ...interface{}) error { |
19 | | - args := m.Called(msg, fields) |
20 | | - return args.Error(0) |
21 | | -} |
22 | | - |
23 | | -// TestHandleAPIErrorResponse tests the handling of various API error responses. |
24 | | -func TestHandleAPIErrorResponse(t *testing.T) { |
25 | | - tests := []struct { |
26 | | - name string |
27 | | - responseStatus int |
28 | | - responseBody string |
29 | | - expectedAPIError *APIError |
| 14 | +func TestParseHTMLResponse(t *testing.T) { |
| 15 | + // Define test cases |
| 16 | + testCases := []struct { |
| 17 | + name string |
| 18 | + html string |
| 19 | + expected string |
30 | 20 | }{ |
31 | 21 | { |
32 | | - name: "structured JSON error", |
33 | | - responseStatus: http.StatusBadRequest, |
34 | | - responseBody: `{"error": {"code": "400", "message": "Bad Request"}}`, |
35 | | - expectedAPIError: &APIError{ |
36 | | - StatusCode: http.StatusBadRequest, |
37 | | - Type: "APIError", |
38 | | - Message: "An error occurred", |
39 | | - Raw: `{"error": {"code": "400", "message": "Bad Request"}}`, |
40 | | - }, |
| 22 | + name: "Single paragraph with text", |
| 23 | + html: `<html><body><p>Test paragraph</p></body></html>`, |
| 24 | + expected: "Test paragraph", |
41 | 25 | }, |
42 | 26 | { |
43 | | - name: "generic JSON error", |
44 | | - responseStatus: http.StatusInternalServerError, |
45 | | - responseBody: `{"message": "Internal Server Error", "detail": "Server crashed"}`, |
46 | | - expectedAPIError: &APIError{ |
47 | | - StatusCode: http.StatusInternalServerError, |
48 | | - Type: "APIError", |
49 | | - Message: "An error occurred", |
50 | | - Raw: `{"message": "Internal Server Error", "detail": "Server crashed"}`, |
51 | | - }, |
52 | | - }, |
53 | | - { |
54 | | - name: "non-JSON error", |
55 | | - responseStatus: http.StatusServiceUnavailable, |
56 | | - responseBody: `<html><body>Service Unavailable</body></html>`, |
57 | | - expectedAPIError: &APIError{ |
58 | | - StatusCode: http.StatusServiceUnavailable, |
59 | | - Type: "APIError", |
60 | | - Message: "An error occurred", |
61 | | - Raw: `<html><body>Service Unavailable</body></html>`, |
62 | | - }, |
| 27 | + name: "Paragraph with link", |
| 28 | + html: `<html><body><p>Visit <a href="https://example.com">Example</a></p></body></html>`, |
| 29 | + expected: `Visit [Link: https://example.com]`, |
63 | 30 | }, |
| 31 | + // Add more test cases as needed... |
64 | 32 | } |
65 | 33 |
|
66 | | - for _, tt := range tests { |
67 | | - t.Run(tt.name, func(t *testing.T) { |
68 | | - // Mock HTTP response |
69 | | - responseRecorder := httptest.NewRecorder() |
70 | | - responseRecorder.WriteHeader(tt.responseStatus) |
71 | | - responseRecorder.WriteString(tt.responseBody) |
72 | | - |
73 | | - // Create a dummy request and associate it with the response |
74 | | - dummyReq := httptest.NewRequest("GET", "http://example.com", nil) |
75 | | - response := responseRecorder.Result() |
76 | | - response.Request = dummyReq |
| 34 | + // Iterate over test cases |
| 35 | + for _, tc := range testCases { |
| 36 | + t.Run(tc.name, func(t *testing.T) { |
| 37 | + mockLog := mocklogger.NewMockLogger() |
77 | 38 |
|
78 | | - // Use the centralized MockLogger from the mocklogger package |
79 | | - mockLogger := mocklogger.NewMockLogger() |
| 39 | + // Simulate an HTTP response |
| 40 | + resp := &http.Response{ |
| 41 | + StatusCode: http.StatusOK, |
| 42 | + Body: io.NopCloser(bytes.NewBufferString(tc.html)), |
| 43 | + Request: &http.Request{ |
| 44 | + Method: "GET", |
| 45 | + URL: &url.URL{Path: "https://example.com"}, |
| 46 | + }, |
| 47 | + } |
80 | 48 |
|
81 | | - // Set up expectations for LogError |
82 | | - mockLogger.On("LogError", |
83 | | - mock.AnythingOfType("string"), // event |
84 | | - mock.AnythingOfType("string"), // method |
85 | | - mock.AnythingOfType("string"), // url |
86 | | - mock.AnythingOfType("int"), // statusCode |
87 | | - mock.AnythingOfType("string"), // status |
88 | | - mock.Anything, // error |
89 | | - mock.AnythingOfType("string"), // raw response |
90 | | - ).Return() |
| 49 | + // Create a new APIError instance |
| 50 | + apiError := &APIError{} |
91 | 51 |
|
92 | | - // Call HandleAPIErrorResponse |
93 | | - result := HandleAPIErrorResponse(response, mockLogger) |
| 52 | + // Read the response body bytes |
| 53 | + bodyBytes, _ := io.ReadAll(resp.Body) |
94 | 54 |
|
95 | | - // Assert |
96 | | - assert.Equal(t, tt.expectedAPIError.StatusCode, result.StatusCode) |
97 | | - assert.Equal(t, tt.expectedAPIError.Type, result.Type) |
98 | | - assert.Equal(t, tt.expectedAPIError.Raw, result.Raw) |
| 55 | + // Call parseHTMLResponse |
| 56 | + parseHTMLResponse(bodyBytes, apiError, mockLog, resp) |
99 | 57 |
|
100 | | - // Assert that all expectations were met |
101 | | - mockLogger.AssertExpectations(t) |
| 58 | + // Assert the results |
| 59 | + if !strings.Contains(apiError.Message, tc.expected) { |
| 60 | + t.Errorf("Expected message to contain %q, got %q", tc.expected, apiError.Message) |
| 61 | + } |
102 | 62 | }) |
103 | 63 | } |
104 | 64 | } |
0 commit comments