github.com/k0marov/go-socnet@v0.0.0-20220715154813-90d07867c782/features/comments/integration_test/comments_test.go (about) 1 package integration_test 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "github.com/k0marov/go-socnet/core/general/core_values" 7 helpers "github.com/k0marov/go-socnet/core/helpers/http_test_helpers" 8 . "github.com/k0marov/go-socnet/core/helpers/test_helpers" 9 "net/http" 10 "net/http/httptest" 11 "testing" 12 "time" 13 14 "github.com/go-chi/chi/v5" 15 "github.com/k0marov/go-socnet/features/comments" 16 "github.com/k0marov/go-socnet/features/comments/delivery/http/handlers" 17 "github.com/k0marov/go-socnet/features/comments/delivery/http/responses" 18 "github.com/k0marov/go-socnet/features/comments/domain/values" 19 post_models "github.com/k0marov/go-socnet/features/posts/domain/models" 20 post_values "github.com/k0marov/go-socnet/features/posts/domain/values" 21 posts_db "github.com/k0marov/go-socnet/features/posts/store/sql_db" 22 "github.com/k0marov/go-socnet/features/profiles" 23 profile_responses "github.com/k0marov/go-socnet/features/profiles/delivery/http/responses" 24 auth "github.com/k0marov/golang-auth" 25 _ "github.com/mattn/go-sqlite3" 26 ) 27 28 func TestComments(t *testing.T) { 29 // db 30 sql := OpenSqliteDB(t) 31 r := chi.NewRouter() 32 // profiles 33 fakeRegisterProfile := profiles.NewRegisterCallback(sql) 34 getProfile := profiles.NewProfileGetterImpl(sql) 35 // posts 36 postsDB, _ := posts_db.NewSqlDB(sql) 37 createPost := func(author core_values.UserId) post_values.PostId { 38 id, _ := postsDB.CreatePost(post_models.PostToCreate{ 39 Author: author, 40 Text: RandomString(), 41 CreatedAt: RandomTime(), 42 }) 43 return id 44 } 45 // comments 46 r.Route("/comments", comments.NewCommentsRouterImpl(sql, getProfile)) 47 48 assertComments := func(t testing.TB, got, want []responses.CommentResponse) { 49 t.Helper() 50 AssertFatal(t, len(got), len(want), "number of returned comments") 51 for i, comment := range got { 52 Assert(t, comment, want[i], "comment") 53 } 54 } 55 addComment := func(t testing.TB, post post_values.PostId, caller auth.User) responses.CommentResponse { 56 t.Helper() 57 58 newComment := handlers.NewCommentRequest{Text: RandomString()} 59 body := bytes.NewBuffer(nil) 60 json.NewEncoder(body).Encode(newComment) 61 request := helpers.AddAuthDataToRequest(httptest.NewRequest(http.MethodPost, "/comments/?post_id="+post, body), caller) 62 response := httptest.NewRecorder() 63 r.ServeHTTP(response, request) 64 65 AssertStatusCode(t, response, http.StatusOK) 66 var returnedComment responses.CommentResponse 67 json.NewDecoder(response.Body).Decode(&returnedComment) 68 69 wantAuthor, _ := getProfile(caller.Id, caller.Id) 70 wantComment := responses.CommentResponse{ 71 Id: returnedComment.Id, 72 Author: profile_responses.NewProfileResponse(wantAuthor), 73 Text: newComment.Text, 74 CreatedAt: time.Now().Unix(), 75 Likes: 0, 76 IsLiked: false, 77 IsMine: true, 78 } 79 assertComments(t, []responses.CommentResponse{returnedComment}, []responses.CommentResponse{wantComment}) 80 81 return returnedComment 82 } 83 getComments := func(t testing.TB, post post_values.PostId, caller auth.User) []responses.CommentResponse { 84 t.Helper() 85 86 request := helpers.AddAuthDataToRequest(httptest.NewRequest(http.MethodGet, "/comments/?post_id="+post, nil), caller) 87 response := httptest.NewRecorder() 88 r.ServeHTTP(response, request) 89 90 AssertStatusCode(t, response, http.StatusOK) 91 var commentsResponse responses.CommentsResponse 92 json.NewDecoder(response.Body).Decode(&commentsResponse) 93 94 return commentsResponse.Comments 95 } 96 toggleLike := func(t testing.TB, comment values.CommentId, caller auth.User) { 97 t.Helper() 98 request := helpers.AddAuthDataToRequest(httptest.NewRequest(http.MethodPost, "/comments/"+comment+"/toggle-like", nil), caller) 99 response := httptest.NewRecorder() 100 r.ServeHTTP(response, request) 101 AssertStatusCode(t, response, http.StatusOK) 102 } 103 deleteComment := func(t testing.TB, comment values.CommentId, caller auth.User) { 104 t.Helper() 105 request := helpers.AddAuthDataToRequest(httptest.NewRequest(http.MethodDelete, "/comments/"+comment, nil), caller) 106 response := httptest.NewRecorder() 107 r.ServeHTTP(response, request) 108 AssertStatusCode(t, response, http.StatusOK) 109 } 110 111 t.Run("creating, reading and deleting comments", func(t *testing.T) { 112 113 // create 2 profiles 114 user1 := RandomAuthUser() 115 user2 := RandomAuthUser() 116 fakeRegisterProfile(user1) 117 fakeRegisterProfile(user2) 118 119 // create post belonging to 1-st profile 120 post := createPost(user1.Id) 121 // add a comment to this post from 2-nd profile 122 comment1 := addComment(t, post, user2) 123 // assert it was created 124 comments := getComments(t, post, user2) 125 assertComments(t, comments, []responses.CommentResponse{comment1}) 126 127 // wait so that createdAt difference is at least 1 second 128 time.Sleep(time.Second) 129 130 // create another comment from 2-nd profile 131 comment2 := addComment(t, post, user2) 132 // assert it was created and comments are returned in the right order (newest first) 133 comments = getComments(t, post, user2) 134 assertComments(t, comments, []responses.CommentResponse{comment2, comment1}) 135 136 t.Run("liking comments", func(t *testing.T) { 137 // like the newest comment from 1-st profile 138 toggleLike(t, comment2.Id, user1) 139 // assert it is liked 140 comments = getComments(t, post, user1) 141 Assert(t, comments[0].IsLiked, true, "isLiked") 142 // unlike it 143 toggleLike(t, comment2.Id, user1) 144 // assert it is not liked 145 comments = getComments(t, post, user1) 146 Assert(t, comments[0].IsLiked, false, "isLiked") 147 }) 148 // delete the second comment 149 deleteComment(t, comment2.Id, user2) 150 // assert it was deleted 151 comments = getComments(t, post, user2) 152 assertComments(t, comments, []responses.CommentResponse{comment1}) 153 // delete the first comment 154 deleteComment(t, comment1.Id, user2) 155 // assert it was deleted 156 assertComments(t, getComments(t, post, user2), []responses.CommentResponse{}) 157 }) 158 }