github.com/acornpublishing/functional-programming-go@v0.0.0-20220401005601-c3bd3786d5a1/Chapter06/04_onion/src/interfaces/interfaces_test/webservice_test.go (about) 1 package interfaces_test 2 3 import ( 4 . "interfaces" 5 . "utils" 6 "infrastructure" 7 "github.com/pkg/errors" 8 "io/ioutil" 9 "net/http" 10 "net/http/httptest" 11 "os" 12 "strings" 13 "testing" 14 ) 15 16 const failure = "\u2717" 17 const defaultFileName = "eventset1.jsonl" 18 19 var fileName string 20 var wsh WebserviceHandler 21 22 func init() { 23 GetOptions() 24 if Config.LogDebugInfoForTests { 25 InitLog("trace-debug-log.txt", os.Stdout, os.Stdout, os.Stderr) 26 } else { 27 InitLog("trace-debug-log.txt", ioutil.Discard, os.Stdout, os.Stderr) 28 } 29 HandlePanic(os.Chdir(Config.ProjectRoot)) 30 Debug.Printf("Config: %+v\n", Config) 31 // use a filename in a downloads subdirectory 32 fileName = os.Getenv("TEST_FILENAME") 33 if len(fileName) == 0 { 34 fileName = defaultFileName 35 } 36 // instantiate interactors 37 gcpi, err := infrastructure.GetGcpInteractor() 38 HandlePanic(errors.Wrap(err, "unable to get gcp interactor")) 39 li, err := infrastructure.GetLocalInteractor() 40 HandlePanic(errors.Wrap(err, "unable to get local interactor")) 41 // wire up interactors to webservice handler 42 wsh = WebserviceHandler{} 43 wsh.GcpInteractor = gcpi 44 wsh.LocalInteractor = li 45 } 46 47 type endpoint struct { 48 Api 49 expectedBody string 50 } 51 52 func TestEndpoints(t *testing.T) { 53 Debug.Printf("fileName: %s", fileName) 54 55 var endpoints = []endpoint{ 56 {Api{wsh.Health, 57 "/health"}, 58 `{"alive": true}`}, 59 {Api{wsh.ListSourceBuckets, 60 "/list-source-buckets?projectId="+Config.GcpSourceProjectId}, 61 `{"buckets":[{"name":"lexttc3-my-backup-bucket"},{"name":"lexttc3-my-source-bucket"}]}`}, 62 {Api{wsh.ListSinkBuckets, 63 "/list-sink-buckets?projectId="+Config.GcpSinkProjectId}, 64 `{"buckets":[{"name":"lexttc3-my-backup-bucket"},{"name":"lexttc3-my-source-bucket"}]}`}, 65 {Api{wsh.UploadFile, 66 "/upload-file?fileName="+fileName}, 67 `{"success":true}`}, 68 //{Api{wsh.DownloadFile, 69 // "/download-file?fileName="+fileName}, 70 // `{"success":true}`}, 71 {Api{wsh.SourceFileExists, 72 "/source-file-exists?fileName="+fileName}, 73 `{"exists":true}`}, 74 {Api{wsh.LocalFileExists, 75 "/local-file-exists?fileName="+fileName}, 76 `{"exists":true}`}, 77 } 78 79 t.Log("Testing API endpoints...") 80 { 81 for _, ep := range endpoints { 82 { 83 req, err := http.NewRequest("GET", ep.Api.Url, nil) 84 if err != nil { 85 t.Fatal(err) 86 } 87 // Create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response 88 rr := httptest.NewRecorder() 89 handler := http.HandlerFunc(ep.Api.Handler) 90 // Our handlers implement http.Handler, so we can call their ServeHTTP method directly 91 handler.ServeHTTP(rr, req) 92 t.Logf("\tChecking \"%s\" for status code \"%d\"", 93 ep.Api.Url, http.StatusOK) 94 if status := rr.Code; status != http.StatusOK { 95 t.Errorf("\t\t%v handler returned wrong status code: got %v want %v", 96 failure, status, http.StatusOK) 97 } 98 t.Logf("\tChecking \"%s\" for expected body", ep.Api.Url) 99 Debug.Println("rr.Body.String(): ", rr.Body.String()) 100 if strings.TrimSpace(rr.Body.String()) != ep.expectedBody { 101 t.Errorf("\t\t%v handler returned unexpected body: got %v want %v", 102 failure, rr.Body.String(), ep.expectedBody) 103 } 104 } 105 } 106 } 107 }