github.com/tonkpils/cli@v1.6.2/api_test.go (about) 1 package main 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io/ioutil" 7 "net/http" 8 "net/http/httptest" 9 "testing" 10 11 "github.com/exercism/cli/configuration" 12 "github.com/stretchr/testify/assert" 13 ) 14 15 var assignmentsJson = ` 16 { 17 "assignments": [ 18 { 19 "track": "ruby", 20 "slug": "bob", 21 "files": { 22 "README.md": "Readme text", 23 "bob_test.rb": "Tests text" 24 } 25 } 26 ] 27 } 28 ` 29 30 var fetchHandler = func(rw http.ResponseWriter, r *http.Request) { 31 r.ParseForm() 32 apiKey := r.Form.Get("key") 33 if r.URL.Path != "/api/v1/user/assignments/current" { 34 fmt.Println("Not found") 35 rw.WriteHeader(http.StatusNotFound) 36 return 37 } 38 if apiKey != "myApiKey" { 39 rw.WriteHeader(http.StatusUnauthorized) 40 fmt.Fprintf(rw, `{"error": "Unable to identify user"}`) 41 return 42 } 43 44 rw.Header().Set("Content-Type", "application/json") 45 fmt.Fprintf(rw, assignmentsJson) 46 } 47 48 func TestFetchWithKey(t *testing.T) { 49 server := httptest.NewServer(http.HandlerFunc(fetchHandler)) 50 51 config := configuration.Config{ 52 Hostname: server.URL, 53 ApiKey: "myApiKey", 54 } 55 56 assignments, err := FetchAssignments(config, "/api/v1/user/assignments/current") 57 assert.NoError(t, err) 58 59 assert.Equal(t, len(assignments), 1) 60 61 assert.Equal(t, assignments[0].Track, "ruby") 62 assert.Equal(t, assignments[0].Slug, "bob") 63 assert.Equal(t, assignments[0].Files, map[string]string{ 64 "README.md": "Readme text", 65 "bob_test.rb": "Tests text", 66 }, 67 ) 68 69 server.Close() 70 } 71 72 func TestFetchWithIncorrectKey(t *testing.T) { 73 server := httptest.NewServer(http.HandlerFunc(fetchHandler)) 74 75 config := configuration.Config{ 76 Hostname: server.URL, 77 ApiKey: "myWrongApiKey", 78 } 79 80 assignments, err := FetchAssignments(config, "/api/v1/user/assignments/current") 81 82 assert.Error(t, err) 83 assert.Equal(t, len(assignments), 0) 84 assert.Contains(t, fmt.Sprintf("%s", err), "Unable to identify user") 85 86 server.Close() 87 } 88 89 var submitHandler = func(rw http.ResponseWriter, r *http.Request) { 90 pathMatches := r.URL.Path == "/api/v1/user/assignments" 91 methodMatches := r.Method == "POST" 92 if !(pathMatches && methodMatches) { 93 rw.WriteHeader(http.StatusNotFound) 94 return 95 } 96 97 userAgentMatches := r.Header.Get("User-Agent") == fmt.Sprintf("github.com/exercism/cli v%s", VERSION) 98 99 if !userAgentMatches { 100 fmt.Printf("User agent mismatch: %s\n", r.Header.Get("User-Agent")) 101 rw.WriteHeader(http.StatusInternalServerError) 102 return 103 } 104 105 body, err := ioutil.ReadAll(r.Body) 106 r.Body.Close() 107 108 if err != nil { 109 rw.WriteHeader(http.StatusInternalServerError) 110 fmt.Printf("Reading body error: %s\n", err) 111 return 112 } 113 114 type Submission struct { 115 Key string 116 Code string 117 Path string 118 } 119 120 submission := Submission{} 121 122 err = json.Unmarshal(body, &submission) 123 if err != nil { 124 fmt.Printf("Unmarshalling error: %v, Body: %s\n", err, body) 125 rw.WriteHeader(http.StatusInternalServerError) 126 return 127 } 128 129 if submission.Key != "myApiKey" { 130 rw.WriteHeader(http.StatusForbidden) 131 rw.Header().Set("Content-Type", "application/json") 132 fmt.Fprintf(rw, `{"error": "Unable to identify user"}`) 133 return 134 } 135 136 code := submission.Code 137 filePath := submission.Path 138 139 codeMatches := string(code) == "My source code\n" 140 filePathMatches := filePath == "ruby/bob/bob.rb" 141 142 if !filePathMatches { 143 fmt.Printf("FilePathMismatch: File Path: %s\n", filePath) 144 rw.WriteHeader(http.StatusBadRequest) 145 return 146 } 147 148 if !codeMatches { 149 fmt.Printf("Code Mismatch: Code: %v\n", code) 150 rw.WriteHeader(http.StatusBadRequest) 151 return 152 } 153 154 rw.WriteHeader(http.StatusCreated) 155 rw.Header().Set("Content-Type", "application/json") 156 157 submitJson := ` 158 { 159 "status":"saved", 160 "language":"ruby", 161 "exercise":"bob", 162 "submission_path":"/username/ruby/bob" 163 } 164 ` 165 fmt.Fprintf(rw, submitJson) 166 } 167 168 func TestSubmitWithKey(t *testing.T) { 169 server := httptest.NewServer(http.HandlerFunc(submitHandler)) 170 defer server.Close() 171 172 var code = []byte("My source code\n") 173 config := configuration.Config{ 174 Hostname: server.URL, 175 ApiKey: "myApiKey", 176 } 177 response, err := SubmitAssignment(config, "ruby/bob/bob.rb", code) 178 assert.NoError(t, err) 179 180 assert.Equal(t, response.Status, "saved") 181 assert.Equal(t, response.Language, "ruby") 182 assert.Equal(t, response.Exercise, "bob") 183 assert.Equal(t, response.SubmissionPath, "/username/ruby/bob") 184 } 185 186 func TestSubmitWithIncorrectKey(t *testing.T) { 187 server := httptest.NewServer(http.HandlerFunc(submitHandler)) 188 defer server.Close() 189 190 config := configuration.Config{ 191 Hostname: server.URL, 192 ApiKey: "myWrongApiKey", 193 } 194 195 var code = []byte("My source code\n") 196 _, err := SubmitAssignment(config, "ruby/bob/bob.rb", code) 197 198 assert.Error(t, err) 199 }