github.com/k0marov/go-socnet@v0.0.0-20220715154813-90d07867c782/features/profiles/delivery/http/handlers/updaters_test.go (about)

     1  package handlers_test
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"github.com/k0marov/go-socnet/core/general/client_errors"
     8  	"github.com/k0marov/go-socnet/core/general/core_entities"
     9  	"github.com/k0marov/go-socnet/core/general/core_values"
    10  	helpers "github.com/k0marov/go-socnet/core/helpers/http_test_helpers"
    11  	. "github.com/k0marov/go-socnet/core/helpers/test_helpers"
    12  	"github.com/k0marov/go-socnet/features/profiles/delivery/http/responses"
    13  	"mime/multipart"
    14  	"net/http"
    15  	"net/http/httptest"
    16  	"reflect"
    17  	"testing"
    18  
    19  	"github.com/k0marov/go-socnet/features/profiles/delivery/http/handlers"
    20  	"github.com/k0marov/go-socnet/features/profiles/domain/entities"
    21  	"github.com/k0marov/go-socnet/features/profiles/domain/values"
    22  )
    23  
    24  func TestUpdateMeHandler(t *testing.T) {
    25  	authUser := RandomAuthUser()
    26  	user := core_entities.UserFromAuth(authUser)
    27  	profileUpdate := values.ProfileUpdateData{About: RandomString()}
    28  	createGoodRequest := func() *http.Request {
    29  		body := bytes.NewBuffer(nil)
    30  		json.NewEncoder(body).Encode(profileUpdate)
    31  		return helpers.AddAuthDataToRequest(helpers.CreateRequest(body), authUser)
    32  	}
    33  
    34  	helpers.BaseTest401(t, handlers.NewUpdateMeHandler(nil))
    35  	t.Run("happy case", func(t *testing.T) {
    36  		updatedProfile := RandomContextedProfile()
    37  		update := func(gotUser core_entities.User, updateData values.ProfileUpdateData) (entities.ContextedProfile, error) {
    38  			if gotUser == user && updateData == profileUpdate {
    39  				return updatedProfile, nil
    40  			}
    41  			panic(fmt.Sprintf("called with gotUser=%v and updateData=%v", gotUser, updateData))
    42  		}
    43  
    44  		response := httptest.NewRecorder()
    45  		handlers.NewUpdateMeHandler(update).ServeHTTP(response, createGoodRequest())
    46  
    47  		AssertStatusCode(t, response, http.StatusOK)
    48  		AssertJSONData(t, response, responses.NewProfileResponse(updatedProfile))
    49  	})
    50  	helpers.BaseTestServiceErrorHandling(t, func(wantErr error, w *httptest.ResponseRecorder) {
    51  		update := func(core_entities.User, values.ProfileUpdateData) (entities.ContextedProfile, error) {
    52  			return entities.ContextedProfile{}, wantErr
    53  		}
    54  		handlers.NewUpdateMeHandler(update).ServeHTTP(w, createGoodRequest())
    55  	})
    56  	t.Run("should return invalid json client error if request is not valid json", func(t *testing.T) {
    57  		response := httptest.NewRecorder()
    58  		request := helpers.AddAuthDataToRequest(helpers.CreateRequest(bytes.NewBufferString("non-json")), authUser)
    59  		handler := handlers.NewUpdateMeHandler(nil) // service is nil, since it shouldn't be called
    60  		handler.ServeHTTP(response, request)
    61  
    62  		AssertClientError(t, response, client_errors.InvalidJsonError)
    63  	})
    64  }
    65  
    66  func TestToggleFollowHandler(t *testing.T) {
    67  	helpers.BaseTest401(t, handlers.NewToggleFollowHandler(nil))
    68  	t.Run("should toggle follow using service", func(t *testing.T) {
    69  		targetId := RandomString()
    70  		followerAuth := RandomAuthUser()
    71  		called := false
    72  		followToggler := func(target, follower core_values.UserId) error {
    73  			if follower == followerAuth.Id && target == targetId {
    74  				called = true
    75  				return nil
    76  			}
    77  			panic("called with unexpected args")
    78  		}
    79  
    80  		request := helpers.AddAuthDataToRequest(createRequestWithId(targetId), followerAuth)
    81  		response := httptest.NewRecorder()
    82  		handlers.NewToggleFollowHandler(followToggler).ServeHTTP(response, request)
    83  
    84  		AssertStatusCode(t, response, http.StatusOK)
    85  		Assert(t, called, true, "toggle called")
    86  	})
    87  	t.Run("error case - id is not provided", func(t *testing.T) {
    88  		response := httptest.NewRecorder()
    89  		handlers.NewToggleFollowHandler(nil).ServeHTTP(response, helpers.AddAuthDataToRequest(helpers.CreateRequest(nil), RandomAuthUser())) // toggler is nil, since it shouldn't be called
    90  		AssertClientError(t, response, client_errors.IdNotProvided)
    91  	})
    92  	helpers.BaseTestServiceErrorHandling(t, func(err error, w *httptest.ResponseRecorder) {
    93  		followToggler := func(target, follower core_values.UserId) error {
    94  			return err
    95  		}
    96  		handlers.NewToggleFollowHandler(followToggler).ServeHTTP(w, helpers.AddAuthDataToRequest(createRequestWithId("42"), RandomAuthUser()))
    97  
    98  	})
    99  }
   100  
   101  func TestUpdateAvatarHandler(t *testing.T) {
   102  	authUser := RandomAuthUser()
   103  	user := core_entities.UserFromAuth(authUser)
   104  	tAvatar := []byte(RandomString())
   105  
   106  	createMultipartBody := func(data []byte) (*bytes.Buffer, string) {
   107  		body := bytes.NewBuffer(nil)
   108  		writer := multipart.NewWriter(body)
   109  		defer writer.Close()
   110  		fw, _ := writer.CreateFormFile("avatar", RandomString())
   111  		fw.Write(data)
   112  		return body, writer.FormDataContentType()
   113  	}
   114  	createRequestWithAuth := func() *http.Request {
   115  		body, contentType := createMultipartBody(tAvatar)
   116  		req := helpers.AddAuthDataToRequest(helpers.CreateRequest(body), authUser)
   117  		req.Header.Set("Content-Type", contentType)
   118  		return helpers.AddAuthDataToRequest(req, authUser)
   119  	}
   120  	helpers.BaseTest401(t, handlers.NewUpdateAvatarHandler(nil))
   121  	t.Run("should update avatar using service", func(t *testing.T) {
   122  		t.Run("happy case", func(t *testing.T) {
   123  			avatarURL := RandomString()
   124  			updateAvatar := func(u core_entities.User, avatar values.AvatarData) (core_values.FileURL, error) {
   125  				if u == user && reflect.DeepEqual(avatar.Data.Value(), tAvatar) {
   126  					return avatarURL, nil
   127  				}
   128  				panic("updateAvatar called with improper arguments")
   129  			}
   130  
   131  			response := httptest.NewRecorder()
   132  			handlers.NewUpdateAvatarHandler(updateAvatar).ServeHTTP(response, createRequestWithAuth())
   133  
   134  			AssertStatusCode(t, response, http.StatusOK)
   135  			AssertJSONData(t, response, responses.AvatarURLResponse{AvatarURL: avatarURL})
   136  		})
   137  		t.Run("error case - avatar file is not provided", func(t *testing.T) {
   138  			response := httptest.NewRecorder()
   139  			req := helpers.AddAuthDataToRequest(helpers.CreateRequest(nil), authUser)
   140  			handler := handlers.NewUpdateAvatarHandler(nil) // since the service function shouldn't be called, it's nil
   141  			handler.ServeHTTP(response, req)
   142  
   143  			AssertClientError(t, response, client_errors.AvatarNotProvidedError)
   144  		})
   145  	})
   146  	helpers.BaseTestServiceErrorHandling(t, func(err error, w *httptest.ResponseRecorder) {
   147  		updateAvatar := func(core_entities.User, values.AvatarData) (core_values.FileURL, error) {
   148  			return "", err
   149  		}
   150  		handlers.NewUpdateAvatarHandler(updateAvatar).ServeHTTP(w, createRequestWithAuth())
   151  	})
   152  }