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 }