github.com/k0marov/go-socnet@v0.0.0-20220715154813-90d07867c782/features/posts/delivery/http/handlers/handlers_test.go (about) 1 package handlers_test 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "github.com/k0marov/go-socnet/core/general/client_errors" 8 "github.com/k0marov/go-socnet/core/general/core_values" 9 helpers "github.com/k0marov/go-socnet/core/helpers/http_test_helpers" 10 . "github.com/k0marov/go-socnet/core/helpers/test_helpers" 11 "mime/multipart" 12 "net/http" 13 "net/http/httptest" 14 "reflect" 15 "testing" 16 17 "github.com/k0marov/go-socnet/features/posts/delivery/http/responses" 18 19 "github.com/k0marov/go-socnet/features/posts/delivery/http/handlers" 20 "github.com/k0marov/go-socnet/features/posts/domain/entities" 21 "github.com/k0marov/go-socnet/features/posts/domain/values" 22 23 "github.com/go-chi/chi/v5" 24 auth "github.com/k0marov/golang-auth" 25 ) 26 27 func TestGetListById(t *testing.T) { 28 caller := RandomAuthUser() 29 helpers.BaseTest401(t, handlers.NewGetListByIdHandler(nil)) 30 t.Run("happy case", func(t *testing.T) { 31 randomProfile := RandomString() 32 posts := []entities.ContextedPost{RandomContextedPost(), RandomContextedPost()} 33 getter := func(profileId, callerId core_values.UserId) ([]entities.ContextedPost, error) { 34 if profileId == randomProfile && callerId == caller.Id { 35 return posts, nil 36 } 37 panic("unexpected args") 38 } 39 request := helpers.AddAuthDataToRequest(httptest.NewRequest(http.MethodGet, "/handler-should-not-care?profile_id="+randomProfile, nil), caller) 40 response := httptest.NewRecorder() 41 handlers.NewGetListByIdHandler(getter).ServeHTTP(response, request) 42 AssertJSONData(t, response, responses.NewPostListResponse(posts)) 43 }) 44 t.Run("error case - profile id is not provided", func(t *testing.T) { 45 request := helpers.AddAuthDataToRequest(helpers.CreateRequest(nil), caller) 46 response := httptest.NewRecorder() 47 handlers.NewGetListByIdHandler(nil).ServeHTTP(response, request) 48 AssertClientError(t, response, client_errors.IdNotProvided) 49 }) 50 helpers.BaseTestServiceErrorHandling(t, func(err error, rr *httptest.ResponseRecorder) { 51 getter := func(profile, caller core_values.UserId) ([]entities.ContextedPost, error) { 52 return []entities.ContextedPost{}, err 53 } 54 request := helpers.AddAuthDataToRequest(httptest.NewRequest(http.MethodGet, "/handler-should-not-care?profile_id=42", nil), caller) 55 handlers.NewGetListByIdHandler(getter).ServeHTTP(rr, request) 56 }) 57 } 58 func TestToggleLike(t *testing.T) { 59 helpers.BaseTest401(t, handlers.NewToggleLikeHandler(nil)) 60 t.Run("happy case", func(t *testing.T) { 61 randomPost := RandomString() 62 randomUser := RandomAuthUser() 63 called := false 64 toggler := func(post values.PostId, fromUser core_values.UserId) error { 65 if post == randomPost && fromUser == randomUser.Id { 66 called = true 67 return nil 68 } 69 panic("unexpected args") 70 } 71 request := helpers.AddAuthDataToRequest(createRequestWithPostId(randomPost), randomUser) 72 response := httptest.NewRecorder() 73 handlers.NewToggleLikeHandler(toggler).ServeHTTP(response, request) 74 AssertStatusCode(t, response, http.StatusOK) 75 Assert(t, called, true, "service called") 76 }) 77 t.Run("error case - id is not provided", func(t *testing.T) { 78 request := helpers.AddAuthDataToRequest(helpers.CreateRequest(nil), RandomAuthUser()) 79 response := httptest.NewRecorder() 80 handlers.NewToggleLikeHandler(nil).ServeHTTP(response, request) 81 AssertClientError(t, response, client_errors.IdNotProvided) 82 }) 83 helpers.BaseTestServiceErrorHandling(t, func(err error, rr *httptest.ResponseRecorder) { 84 toggler := func(values.PostId, core_values.UserId) error { 85 return err 86 } 87 request := helpers.AddAuthDataToRequest(createRequestWithPostId("42"), RandomAuthUser()) 88 handlers.NewToggleLikeHandler(toggler).ServeHTTP(rr, request) 89 }) 90 } 91 92 func TestCreatePost_ErrorHandling(t *testing.T) { 93 helpers.BaseTest401(t, handlers.NewCreateHandler(nil)) 94 helpers.BaseTestServiceErrorHandling(t, func(err error, rr *httptest.ResponseRecorder) { 95 creator := func(values.NewPostData) error { 96 return err 97 } 98 request := helpers.AddAuthDataToRequest(helpers.CreateRequest(nil), RandomAuthUser()) 99 handlers.NewCreateHandler(creator).ServeHTTP(rr, request) 100 }) 101 } 102 103 func TestCreatePost_Parsing(t *testing.T) { 104 createRequest := func(postData values.NewPostData) *http.Request { 105 body := bytes.NewBuffer(nil) 106 writer := multipart.NewWriter(body) 107 108 writer.WriteField("text", postData.Text) 109 for _, image := range postData.Images { 110 fw, _ := writer.CreateFormFile(fmt.Sprintf("image_%d", image.Index), RandomString()) 111 fw.Write(image.File.Value()) 112 } 113 writer.Close() 114 115 user := auth.User{Id: postData.Author, Username: RandomString()} 116 request := helpers.AddAuthDataToRequest(helpers.CreateRequest(body), user) 117 request.Header.Set("Content-Type", writer.FormDataContentType()) 118 119 return request 120 } 121 122 cases := []values.NewPostData{ 123 { 124 Text: "0 Images", 125 Author: "42", 126 Images: []values.PostImageFile{}, 127 }, 128 { 129 Text: "2 Images", 130 Author: "77", 131 Images: []values.PostImageFile{{RandomFileData(), 1}, {RandomFileData(), 2}}, 132 }, 133 { 134 Text: "3 images", 135 Author: "33", 136 Images: []values.PostImageFile{{RandomFileData(), 1}, {RandomFileData(), 2}, {RandomFileData(), 3}}, 137 }, 138 } 139 140 for _, testNewPost := range cases { 141 t.Run(testNewPost.Text, func(t *testing.T) { 142 creator := func(newPost values.NewPostData) error { 143 if reflect.DeepEqual(newPost, testNewPost) { 144 return nil 145 } 146 panic(fmt.Sprintf("enexpected args: newPost = %+v", newPost)) 147 } 148 response := httptest.NewRecorder() 149 handlers.NewCreateHandler(creator).ServeHTTP(response, createRequest(testNewPost)) 150 151 AssertStatusCode(t, response, http.StatusOK) 152 }) 153 } 154 } 155 156 func createRequestWithPostId(postId values.PostId) *http.Request { 157 request := helpers.CreateRequest(nil) 158 ctx := chi.NewRouteContext() 159 ctx.URLParams.Add("id", postId) 160 request = request.WithContext(context.WithValue(request.Context(), chi.RouteCtxKey, ctx)) 161 return request 162 } 163 func TestDelete(t *testing.T) { 164 helpers.BaseTest401(t, handlers.NewDeleteHandler(nil)) 165 t.Run("happy case", func(t *testing.T) { 166 randomPost := RandomString() 167 randomUser := RandomAuthUser() 168 called := false 169 deleter := func(post values.PostId, fromUser core_values.UserId) error { 170 if post == randomPost && fromUser == randomUser.Id { 171 called = true 172 return nil 173 } 174 panic("unexpected args") 175 } 176 request := helpers.AddAuthDataToRequest(createRequestWithPostId(randomPost), randomUser) 177 response := httptest.NewRecorder() 178 handlers.NewDeleteHandler(deleter).ServeHTTP(response, request) 179 180 AssertStatusCode(t, response, http.StatusOK) 181 Assert(t, called, true, "service was called") 182 }) 183 t.Run("error case - post id is not provided", func(t *testing.T) { 184 request := helpers.AddAuthDataToRequest(helpers.CreateRequest(nil), RandomAuthUser()) 185 response := httptest.NewRecorder() 186 handlers.NewDeleteHandler(nil).ServeHTTP(response, request) 187 AssertClientError(t, response, client_errors.IdNotProvided) 188 }) 189 helpers.BaseTestServiceErrorHandling(t, func(err error, response *httptest.ResponseRecorder) { 190 deleter := func(values.PostId, core_values.UserId) error { 191 return err 192 } 193 request := helpers.AddAuthDataToRequest(createRequestWithPostId("42"), RandomAuthUser()) 194 handlers.NewDeleteHandler(deleter).ServeHTTP(response, request) 195 }) 196 }