github.com/bazelbuild/rules_webtesting@v0.2.0/go/wsl/upload/upload_test.go (about) 1 package upload 2 3 import ( 4 "archive/zip" 5 "bytes" 6 "encoding/base64" 7 "encoding/json" 8 "io" 9 "io/ioutil" 10 "net/http" 11 "os" 12 "strings" 13 "testing" 14 15 "github.com/bazelbuild/rules_webtesting/go/bazel" 16 ) 17 18 func TestWrongMethod(t *testing.T) { 19 uploader := &Uploader{} 20 21 request, err := http.NewRequest(http.MethodGet, "http://localhost/", nil) 22 if err != nil { 23 t.Fatal(err) 24 } 25 26 frw := newFakeResponseWriter() 27 28 uploader.ServeHTTP(frw, request) 29 30 if frw.status != http.StatusMethodNotAllowed { 31 t.Errorf("Got status %d, want %d", frw.status, http.StatusMethodNotAllowed) 32 } 33 34 respJSON := struct { 35 Status int 36 Value struct { 37 Error string 38 Message string 39 } 40 }{} 41 if err := json.NewDecoder(frw).Decode(&respJSON); err != nil { 42 t.Fatal(err) 43 } 44 45 if respJSON.Status == 0 { 46 t.Error("Want non-zero status, got 0") 47 } 48 49 if respJSON.Value.Error == "" { 50 t.Error(`Want non-empty value.error, got ""`) 51 } 52 53 if respJSON.Value.Message == "" { 54 t.Error(`Want non-empty value.message, got ""`) 55 } 56 } 57 58 func TestBadArgs(t *testing.T) { 59 uploader := &Uploader{} 60 61 request, err := http.NewRequest(http.MethodPost, "http://localhost/", strings.NewReader("{}")) 62 if err != nil { 63 t.Fatal(err) 64 } 65 66 frw := newFakeResponseWriter() 67 68 uploader.ServeHTTP(frw, request) 69 70 if frw.status != http.StatusBadRequest { 71 t.Errorf("Got status %d, want %d", frw.status, http.StatusBadRequest) 72 } 73 74 respJSON := struct { 75 Status int 76 Value struct { 77 Error string 78 Message string 79 } 80 }{} 81 if err := json.NewDecoder(frw).Decode(&respJSON); err != nil { 82 t.Fatal(err) 83 } 84 85 if respJSON.Status == 0 { 86 t.Error("Want non-zero status, got 0") 87 } 88 89 if respJSON.Value.Error == "" { 90 t.Error(`Want non-empty value.error, got ""`) 91 } 92 93 if respJSON.Value.Message == "" { 94 t.Error(`Want non-empty value.message, got ""`) 95 } 96 } 97 98 func TestNotZippedUpload(t *testing.T) { 99 tmpDir, err := bazel.NewTmpDir("TestNotZippedUpload") 100 if err != nil { 101 t.Fatal(err) 102 } 103 defer os.RemoveAll(tmpDir) 104 105 uploader := &Uploader{Root: tmpDir} 106 107 file := "this is my file contents." 108 109 encodedFile := base64.StdEncoding.EncodeToString([]byte(file)) 110 111 reqBytes, err := json.Marshal(map[string]interface{}{ 112 "file": encodedFile, 113 }) 114 if err != nil { 115 t.Fatal(err) 116 } 117 118 request, err := http.NewRequest(http.MethodPost, "http://localhost/", bytes.NewReader(reqBytes)) 119 if err != nil { 120 t.Fatal(err) 121 } 122 123 frw := newFakeResponseWriter() 124 125 uploader.ServeHTTP(frw, request) 126 127 if frw.status != http.StatusOK { 128 t.Errorf("Got status %d, want %d", frw.status, http.StatusOK) 129 } 130 131 respJSON := struct { 132 Status int 133 Value string 134 }{} 135 if err := json.NewDecoder(frw).Decode(&respJSON); err != nil { 136 t.Fatal(err) 137 } 138 139 if respJSON.Status != 0 { 140 t.Fatalf("Got %d status, want 0", respJSON.Status) 141 } 142 143 if respJSON.Value == "" { 144 t.Fatal("Got empty file name, want non-empty filename") 145 } 146 147 savedFile, err := ioutil.ReadFile(respJSON.Value) 148 149 if string(savedFile) != file { 150 t.Errorf("Got %q, want %q", string(savedFile), file) 151 } 152 } 153 154 func TestZippedSingleFile(t *testing.T) { 155 tmpDir, err := bazel.NewTmpDir("TestNotZippedUpload") 156 if err != nil { 157 t.Fatal(err) 158 } 159 defer os.RemoveAll(tmpDir) 160 161 uploader := &Uploader{Root: tmpDir} 162 163 file := "this is my file contents." 164 165 buffer := bytes.NewBuffer(nil) 166 zipWriter := zip.NewWriter(buffer) 167 168 fileWriter, err := zipWriter.Create("file.txt") 169 if err != nil { 170 t.Fatal(err) 171 } 172 if _, err := io.WriteString(fileWriter, file); err != nil { 173 t.Fatal(err) 174 } 175 176 if err := zipWriter.Close(); err != nil { 177 t.Fatal(err) 178 } 179 180 encodedFile := base64.StdEncoding.EncodeToString(buffer.Bytes()) 181 182 reqBytes, err := json.Marshal(map[string]interface{}{ 183 "file": encodedFile, 184 }) 185 if err != nil { 186 t.Fatal(err) 187 } 188 189 request, err := http.NewRequest(http.MethodPost, "http://localhost/", bytes.NewReader(reqBytes)) 190 if err != nil { 191 t.Fatal(err) 192 } 193 194 frw := newFakeResponseWriter() 195 196 uploader.ServeHTTP(frw, request) 197 198 if frw.status != http.StatusOK { 199 t.Errorf("Got status %d, want %d", frw.status, http.StatusOK) 200 } 201 202 respJSON := struct { 203 Status int 204 Value string 205 }{} 206 if err := json.NewDecoder(frw).Decode(&respJSON); err != nil { 207 t.Fatal(err) 208 } 209 210 if respJSON.Status != 0 { 211 t.Fatalf("Got %d status, want 0", respJSON.Status) 212 } 213 214 if respJSON.Value == "" { 215 t.Fatal("Got empty file name, want non-empty filename") 216 } 217 218 savedFile, err := ioutil.ReadFile(respJSON.Value) 219 220 if string(savedFile) != file { 221 t.Errorf("Got %q, want %q", string(savedFile), file) 222 } 223 } 224 225 func TestZippedTwoFiles(t *testing.T) { 226 tmpDir, err := bazel.NewTmpDir("TestNotZippedUpload") 227 if err != nil { 228 t.Fatal(err) 229 } 230 defer os.RemoveAll(tmpDir) 231 232 uploader := &Uploader{Root: tmpDir} 233 234 file1 := "this is my first file contents." 235 file2 := "this is my second file contents." 236 237 buffer := bytes.NewBuffer(nil) 238 zipWriter := zip.NewWriter(buffer) 239 240 fileWriter, err := zipWriter.Create("file1.txt") 241 if err != nil { 242 t.Fatal(err) 243 } 244 if _, err := io.WriteString(fileWriter, file1); err != nil { 245 t.Fatal(err) 246 } 247 248 fileWriter, err = zipWriter.Create("file2.txt") 249 if err != nil { 250 t.Fatal(err) 251 } 252 if _, err := io.WriteString(fileWriter, file2); err != nil { 253 t.Fatal(err) 254 } 255 256 if err := zipWriter.Close(); err != nil { 257 t.Fatal(err) 258 } 259 260 encodedFile := base64.StdEncoding.EncodeToString(buffer.Bytes()) 261 262 reqBytes, err := json.Marshal(map[string]interface{}{ 263 "file": encodedFile, 264 }) 265 if err != nil { 266 t.Fatal(err) 267 } 268 269 request, err := http.NewRequest(http.MethodPost, "http://localhost/", bytes.NewReader(reqBytes)) 270 if err != nil { 271 t.Fatal(err) 272 } 273 274 frw := newFakeResponseWriter() 275 276 uploader.ServeHTTP(frw, request) 277 278 if frw.status != http.StatusOK { 279 t.Errorf("Got status %d, want %d", frw.status, http.StatusOK) 280 } 281 282 respJSON := struct { 283 Status int 284 Value []string 285 }{} 286 if err := json.NewDecoder(frw).Decode(&respJSON); err != nil { 287 t.Fatal(err) 288 } 289 290 if respJSON.Status != 0 { 291 t.Fatalf("Got %d status, want 0", respJSON.Status) 292 } 293 294 found1 := false 295 found2 := false 296 297 for _, file := range respJSON.Value { 298 savedFile, err := ioutil.ReadFile(file) 299 if err != nil { 300 t.Error(err) 301 continue 302 } 303 304 if strings.HasSuffix(file, "file1.txt") { 305 found1 = true 306 if string(savedFile) != file1 { 307 t.Errorf("Got %q, want %q", string(savedFile), file1) 308 } 309 } else if strings.HasSuffix(file, "file2.txt") { 310 found2 = true 311 if string(savedFile) != file2 { 312 t.Errorf("Got %q, want %q", string(savedFile), file2) 313 } 314 } else { 315 t.Error("Got extra file %q", file) 316 } 317 } 318 319 if !found1 { 320 t.Error("Missing file1.txt") 321 } 322 323 if !found2 { 324 t.Error("Missing file2.txt") 325 } 326 } 327 328 func newFakeResponseWriter() *fakeResponseWriter { 329 return &fakeResponseWriter{ 330 Buffer: &bytes.Buffer{}, 331 status: http.StatusOK, 332 header: http.Header(map[string][]string{}), 333 } 334 } 335 336 type fakeResponseWriter struct { 337 *bytes.Buffer 338 status int 339 header http.Header 340 } 341 342 func (frw *fakeResponseWriter) Header() http.Header { 343 return frw.header 344 } 345 346 func (frw *fakeResponseWriter) WriteHeader(status int) { 347 frw.status = status 348 }