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  }