|
| 1 | +package s3manager_test |
| 2 | + |
| 3 | +import ( |
| 4 | + "encoding/json" |
| 5 | + "net/http" |
| 6 | + "net/http/httptest" |
| 7 | + "net/url" |
| 8 | + "testing" |
| 9 | + |
| 10 | + "github.com/cloudlena/s3manager/internal/app/s3manager" |
| 11 | + "github.com/cloudlena/s3manager/internal/app/s3manager/mocks" |
| 12 | + "github.com/gorilla/mux" |
| 13 | + "github.com/matryer/is" |
| 14 | +) |
| 15 | + |
| 16 | +func TestHandleCheckPublicAccess(t *testing.T) { |
| 17 | + t.Parallel() |
| 18 | + |
| 19 | + cases := []struct { |
| 20 | + it string |
| 21 | + s3ResponseStatus int |
| 22 | + expectAccessible bool |
| 23 | + expectStatusCode int |
| 24 | + networkError bool |
| 25 | + }{ |
| 26 | + { |
| 27 | + it: "reports accessible when S3 returns 200 OK", |
| 28 | + s3ResponseStatus: http.StatusOK, |
| 29 | + expectAccessible: true, |
| 30 | + expectStatusCode: http.StatusOK, |
| 31 | + }, |
| 32 | + { |
| 33 | + it: "reports not accessible when S3 returns 403 Forbidden", |
| 34 | + s3ResponseStatus: http.StatusForbidden, |
| 35 | + expectAccessible: false, |
| 36 | + expectStatusCode: http.StatusForbidden, |
| 37 | + }, |
| 38 | + { |
| 39 | + it: "reports not accessible when S3 returns 404 Not Found", |
| 40 | + s3ResponseStatus: http.StatusNotFound, |
| 41 | + expectAccessible: false, |
| 42 | + expectStatusCode: http.StatusNotFound, |
| 43 | + }, |
| 44 | + { |
| 45 | + it: "reports not accessible on network error", |
| 46 | + networkError: true, |
| 47 | + expectAccessible: false, |
| 48 | + expectStatusCode: 0, |
| 49 | + }, |
| 50 | + } |
| 51 | + |
| 52 | + for _, tc := range cases { |
| 53 | + t.Run(tc.it, func(t *testing.T) { |
| 54 | + is := is.New(t) |
| 55 | + |
| 56 | + // Start a mock S3 server to respond to the HEAD request |
| 57 | + var s3ServerURL string |
| 58 | + if !tc.networkError { |
| 59 | + s3Server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 60 | + is.Equal(http.MethodHead, r.Method) |
| 61 | + w.WriteHeader(tc.s3ResponseStatus) |
| 62 | + })) |
| 63 | + defer s3Server.Close() |
| 64 | + s3ServerURL = s3Server.URL |
| 65 | + } else { |
| 66 | + // Use an invalid port to simulate a network error |
| 67 | + s3ServerURL = "http://localhost:0" |
| 68 | + } |
| 69 | + |
| 70 | + s3 := &mocks.S3Mock{ |
| 71 | + EndpointURLFunc: func() *url.URL { |
| 72 | + u, _ := url.Parse(s3ServerURL) |
| 73 | + return u |
| 74 | + }, |
| 75 | + } |
| 76 | + |
| 77 | + handler := s3manager.HandleCheckPublicAccess(s3) |
| 78 | + r := mux.NewRouter() |
| 79 | + r.Handle("/api/buckets/{bucketName}/objects/{objectName:.*}/public-access", handler) |
| 80 | + |
| 81 | + req := httptest.NewRequest(http.MethodGet, "/api/buckets/my-bucket/objects/my-file.txt/public-access", nil) |
| 82 | + rr := httptest.NewRecorder() |
| 83 | + |
| 84 | + r.ServeHTTP(rr, req) |
| 85 | + |
| 86 | + is.Equal(http.StatusOK, rr.Code) |
| 87 | + |
| 88 | + var response map[string]interface{} |
| 89 | + err := json.Unmarshal(rr.Body.Bytes(), &response) |
| 90 | + is.NoErr(err) |
| 91 | + |
| 92 | + is.Equal(tc.expectAccessible, response["accessible"]) |
| 93 | + is.Equal(float64(tc.expectStatusCode), response["statusCode"]) |
| 94 | + }) |
| 95 | + } |
| 96 | +} |
0 commit comments