github.com/lauslim12/expert-systems@v0.0.0-20221115131159-018513aad29c/internal/application/nethttp_test.go (about)

     1  package application
     2  
     3  import (
     4  	"io"
     5  	"log"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  	"testing"
    12  )
    13  
    14  // Variable 'pathtoWebDirectory' is intentionally kept to './web' and not './web/build' for the sake of testing.
    15  const pathToWebDirectory = "./web"
    16  
    17  func TestGeneralHandler(t *testing.T) {
    18  	handler := Configure(pathToWebDirectory, applicationModeDevelopment)
    19  	testServer := httptest.NewServer(handler)
    20  	defer testServer.Close()
    21  
    22  	failureTests := []struct {
    23  		name           string
    24  		method         string
    25  		input          string
    26  		route          string
    27  		expectedStatus int
    28  	}{
    29  		{
    30  			name:           "test_method_not_allowed",
    31  			method:         http.MethodPut,
    32  			input:          "",
    33  			route:          "/api/v1",
    34  			expectedStatus: http.StatusMethodNotAllowed,
    35  		},
    36  		{
    37  			name:           "test_route_not_exist",
    38  			method:         http.MethodGet,
    39  			input:          "",
    40  			route:          "/api/v1/404",
    41  			expectedStatus: http.StatusNotFound,
    42  		},
    43  		{
    44  			name:           "test_fail_endpoint",
    45  			method:         http.MethodPost,
    46  			input:          "",
    47  			route:          "/api/v1",
    48  			expectedStatus: http.StatusBadRequest,
    49  		},
    50  	}
    51  
    52  	successTests := []struct {
    53  		name           string
    54  		method         string
    55  		input          string
    56  		route          string
    57  		expectedStatus int
    58  	}{
    59  		{
    60  			name:           "test_health",
    61  			method:         http.MethodGet,
    62  			input:          "",
    63  			route:          "/api/v1",
    64  			expectedStatus: http.StatusOK,
    65  		},
    66  		{
    67  			name:           "test_input",
    68  			method:         http.MethodPost,
    69  			input:          `{"diseaseId":"D01","locale":"en","symptoms":[{"symptomId":"S1","weight":0.2},{"symptomId":"S2","weight":0.2},{"symptomId":"S3","weight":0.2},{"symptomId":"S4","weight":0.4},{"symptomId":"S5","weight":0.2},{"symptomId":"S6","weight":0.4},{"symptomId":"S7","weight":0.8},{"symptomId":"S8","weight":0.2},{"symptomId":"S9","weight":0.2},{"symptomId":"S10","weight":0.4},{"symptomId":"S11","weight":0.2},{"symptomId":"S12","weight":0.2},{"symptomId":"S13","weight":1}]}`,
    70  			route:          "/api/v1",
    71  			expectedStatus: http.StatusOK,
    72  		},
    73  	}
    74  
    75  	for _, tt := range failureTests {
    76  		t.Run(tt.name, func(t *testing.T) {
    77  			r := httptest.NewRequest(tt.method, tt.route, nil)
    78  			w := httptest.NewRecorder()
    79  			handler.ServeHTTP(w, r)
    80  
    81  			if tt.expectedStatus != w.Code {
    82  				t.Errorf("Expected and actual status code values are different! Expected: %v. Got: %v", tt.expectedStatus, w.Code)
    83  			}
    84  		})
    85  	}
    86  
    87  	for _, tt := range successTests {
    88  		t.Run(tt.name, func(t *testing.T) {
    89  			r := httptest.NewRequest(tt.method, tt.route, strings.NewReader(tt.input))
    90  			w := httptest.NewRecorder()
    91  			r.Header.Set("Content-Type", "application/json")
    92  			handler.ServeHTTP(w, r)
    93  
    94  			if tt.expectedStatus != w.Code {
    95  				t.Errorf("Expected and actual status code values are different! Expected: %v. Got: %v", tt.expectedStatus, w.Code)
    96  			}
    97  		})
    98  	}
    99  }
   100  
   101  // Create a custom recorder so we can read from static files.
   102  // Reference: https://github.com/go-chi/chi/issues/583.
   103  type testRecorder struct {
   104  	*httptest.ResponseRecorder
   105  }
   106  
   107  func (rec *testRecorder) ReadFrom(r io.Reader) (n int64, err error) {
   108  	return io.Copy(rec.ResponseRecorder, r)
   109  }
   110  
   111  func newRecorder() *testRecorder {
   112  	return &testRecorder{ResponseRecorder: httptest.NewRecorder()}
   113  }
   114  
   115  func TestRenderWeb(t *testing.T) {
   116  	handler := Configure(pathToWebDirectory, applicationModeDevelopment)
   117  	testServer := httptest.NewServer(handler)
   118  	defer testServer.Close()
   119  
   120  	// Reverse current working directory to the root folder.
   121  	// This is done so the test can reach the 'pathToWebDirectory' location.
   122  	err := os.Chdir(filepath.Join("..", ".."))
   123  	if err != nil {
   124  		log.Fatal(err)
   125  	}
   126  
   127  	t.Run("test_render_web", func(t *testing.T) {
   128  		r := httptest.NewRequest(http.MethodGet, "/", nil)
   129  		w := newRecorder()
   130  		handler.ServeHTTP(w, r)
   131  
   132  		if http.StatusOK != w.Code {
   133  			t.Errorf("Expected and actual status code values are different! Expected: %v. Got: %v", http.StatusOK, w.Code)
   134  		}
   135  	})
   136  
   137  	t.Run("test_render_web_404", func(t *testing.T) {
   138  		r := httptest.NewRequest(http.MethodGet, "/404", nil)
   139  		w := newRecorder()
   140  		handler.ServeHTTP(w, r)
   141  
   142  		if http.StatusNotFound != w.Code {
   143  			t.Errorf("Expected and actual status code values are different! Expected: %v. Got: %v", http.StatusNotFound, w.Code)
   144  		}
   145  	})
   146  }