github.com/grafviktor/keep-my-secret@v0.9.10-0.20230908165355-19f35cce90e5/internal/api/utils/http_test.go (about) 1 package utils 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "io" 8 "net/http" 9 "net/http/httptest" 10 "reflect" 11 "strings" 12 "testing" 13 14 "github.com/stretchr/testify/require" 15 ) 16 17 type sampleStruct struct { 18 Login string `json:"age"` 19 Email string `json:"email"` 20 ID int `json:"id"` 21 } 22 23 type testWriteJSONError struct{} 24 25 func (c testWriteJSONError) MarshalJSON() ([]byte, error) { 26 return nil, fmt.Errorf("This is a custom error triggered during MarshalJSON") 27 } 28 29 func TestWriteJSON(t *testing.T) { 30 // Create a mock HTTP response recorder 31 w := httptest.NewRecorder() 32 // Call the WriteJSON function with faulty data 33 err := WriteJSON(w, http.StatusOK, &testWriteJSONError{}) 34 require.Error(t, err) 35 36 u := sampleStruct{ 37 Login: "tony", 38 Email: "tony@tester", 39 ID: 1, 40 } 41 42 header := http.Header{} 43 header.Add("User-Agent", "Unit test") 44 // Call the WriteJSON function headers 45 // err = WriteJSON(w, http.StatusOK, &sampleStruct{}, header) 46 err = WriteJSON(w, http.StatusOK, u, header) 47 if err != nil { 48 t.Errorf("WriteJSON returned an error: %v", err) 49 } 50 51 require.Equal(t, w.Header().Get("User-Agent"), "Unit test") 52 53 // Verify the HTTP status code 54 if w.Code != http.StatusOK { 55 t.Errorf("Expected status code %d, but got %d", http.StatusOK, w.Code) 56 } 57 58 // Verify the Content-Type header 59 contentType := w.Header().Get("Content-Type") 60 expectedContentType := "application/json" 61 if contentType != expectedContentType { 62 t.Errorf("Expected Content-Type header to be %s, but got %s", expectedContentType, contentType) 63 } 64 65 // Parse the response body and compare it to the test data 66 var responseJSON sampleStruct 67 err = json.Unmarshal(w.Body.Bytes(), &responseJSON) 68 if err != nil { 69 t.Errorf("Failed to parse response JSON: %v", err) 70 } 71 72 // Compare the response data to the test data 73 if !reflect.DeepEqual(responseJSON, u) { 74 t.Errorf("Response data does not match the test data. Expected %+v, but got %+v", u, responseJSON) 75 } 76 } 77 78 func TestReadJSON(t *testing.T) { 79 // Create a mock HTTP response recorder 80 w := httptest.NewRecorder() 81 82 // Create a mock HTTP request with a JSON payload 83 maformedJSON := `{"age": "tony", "malformed...` 84 req, err := http.NewRequest("POST", "/example", strings.NewReader(maformedJSON)) 85 if err != nil { 86 t.Fatalf("Failed to create HTTP request: %v", err) 87 } 88 89 testData := sampleStruct{} 90 err = ReadJSON(w, req, &testData) 91 require.Error(t, err) 92 93 requestBody := `{"age": "tony", "email": "tony@tester", "id": 1}` 94 req, err = http.NewRequest("POST", "/example", strings.NewReader(requestBody)) 95 if err != nil { 96 t.Fatalf("Failed to create HTTP request: %v", err) 97 } 98 99 // Define a struct to hold the JSON data 100 testData = sampleStruct{} 101 102 // Call the ReadJSON function with the mock request and the data struct 103 err = ReadJSON(w, req, &testData) 104 105 // Check for errors 106 if err != nil { 107 t.Errorf("ReadJSON returned an error: %v", err) 108 } 109 110 // Verify that the data was correctly decoded from the request body 111 expectedData := sampleStruct{ 112 Login: "tony", 113 Email: "tony@tester", 114 ID: 1, 115 } 116 117 if !reflect.DeepEqual(testData, expectedData) { 118 t.Errorf("Decoded data does not match the expected data. Expected %+v, but got %+v", expectedData, testData) 119 } 120 121 // Verify that the request body was read completely (should be EOF) 122 buf := make([]byte, 1024) 123 _, readErr := req.Body.Read(buf) 124 if !errors.Is(readErr, io.EOF) { 125 t.Errorf("Expected request body to be fully consumed (EOF), but got error: %v", readErr) 126 } 127 }