From e05db2cd676fd40d3a8379834a85d1f3fec68a30 Mon Sep 17 00:00:00 2001 From: slashlight Date: Fri, 29 Nov 2024 17:14:59 +0300 Subject: [PATCH 001/135] bugfix: fixed friends --- internal/profile/repository/postgres.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/profile/repository/postgres.go b/internal/profile/repository/postgres.go index 446e1f75..3db413d9 100644 --- a/internal/profile/repository/postgres.go +++ b/internal/profile/repository/postgres.go @@ -163,7 +163,7 @@ func (p *ProfileRepo) CheckFriendship(ctx context.Context, self uint32, profile } return false, fmt.Errorf("check friendship: %w", err) } - return status == 1, nil + return status != 1, nil } func (p *ProfileRepo) AddFriendsReq(receiver uint32, sender uint32) error { From ea539009e2cbdc76ac720d5e5e38f8438bd51efb Mon Sep 17 00:00:00 2001 From: slashlight Date: Fri, 29 Nov 2024 17:50:39 +0300 Subject: [PATCH 002/135] bugfix: fixed friends --- internal/profile/repository/postgres.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/profile/repository/postgres.go b/internal/profile/repository/postgres.go index 3db413d9..d161cbc1 100644 --- a/internal/profile/repository/postgres.go +++ b/internal/profile/repository/postgres.go @@ -159,11 +159,11 @@ func (p *ProfileRepo) CheckFriendship(ctx context.Context, self uint32, profile err := p.DB.QueryRowContext(ctx, CheckFriendship, self, profile).Scan(&status) if err != nil { if errors.Is(err, sql.ErrNoRows) { - return true, nil + return false, nil } return false, fmt.Errorf("check friendship: %w", err) } - return status != 1, nil + return status == 1, nil } func (p *ProfileRepo) AddFriendsReq(receiver uint32, sender uint32) error { From fb050717e20cfffe26fb980428815c7e45d27d74 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Tue, 3 Dec 2024 20:09:36 +0300 Subject: [PATCH 003/135] feature: comment for post --- DB/migrations/000001_init_schema.up.sql | 1 + internal/models/post.go | 19 +- internal/post/controller/controller.go | 185 ++++++++++++++++-- internal/post/repository/postgres/postgres.go | 133 ++++++++++++- internal/post/service/comment.go | 96 +++++++++ internal/router/post/router.go | 12 ++ pkg/my_err/error.go | 1 + 7 files changed, 422 insertions(+), 25 deletions(-) create mode 100644 internal/post/service/comment.go diff --git a/DB/migrations/000001_init_schema.up.sql b/DB/migrations/000001_init_schema.up.sql index 82b19dac..a1094117 100644 --- a/DB/migrations/000001_init_schema.up.sql +++ b/DB/migrations/000001_init_schema.up.sql @@ -67,6 +67,7 @@ CREATE TABLE IF NOT EXISTS comment ( user_id INT REFERENCES profile(id) ON DELETE CASCADE , post_id INT REFERENCES post(id) ON DELETE CASCADE , content TEXT CONSTRAINT content_comment_length CHECK (CHAR_LENGTH(content) <= 500) DEFAULT '', + file_path TEXT CONSTRAINT file_path_comment CHECK ( CHAR_LENGTH(file_path) <= 100 ) DEFAULT '', created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); diff --git a/internal/models/post.go b/internal/models/post.go index 77b01e23..85f99c75 100644 --- a/internal/models/post.go +++ b/internal/models/post.go @@ -1,11 +1,12 @@ package models type Post struct { - ID uint32 `json:"id"` - Header Header `json:"header"` - PostContent Content `json:"post_content"` - LikesCount uint32 `json:"likes_count"` - IsLiked bool `json:"is_liked"` + ID uint32 `json:"id"` + Header Header `json:"header"` + PostContent Content `json:"post_content"` + LikesCount uint32 `json:"likes_count"` + IsLiked bool `json:"is_liked"` + CommentCount uint32 `json:"comment_count"` } type Header struct { @@ -14,3 +15,11 @@ type Header struct { Author string `json:"author"` Avatar Picture `json:"avatar"` } + +type Comment struct { + ID uint32 `json:"id"` + Header Header `json:"header"` + Content Content `json:"content"` + LikesCount uint32 `json:"likes_count"` + IsLiked bool `json:"is_liked"` +} diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index 4b6fd97b..bab643df 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -15,6 +15,11 @@ import ( "github.com/2024_2_BetterCallFirewall/pkg/my_err" ) +const ( + postIDkey = "id" + commentIDKey = "comment_id" +) + //go:generate mockgen -destination=mock.go -source=$GOFILE -package=${GOPACKAGE} type PostService interface { Create(ctx context.Context, post *models.Post) (uint32, error) @@ -34,6 +39,13 @@ type PostService interface { CheckLikes(ctx context.Context, postID, userID uint32) (bool, error) } +type CommentService interface { + Comment(ctx context.Context, userID, postID uint32, comment *models.Content) (uint32, error) + DeleteComment(ctx context.Context, commentID, userID uint32) error + EditComment(ctx context.Context, commentID, userID uint32, comment *models.Content) error + GetComments(ctx context.Context, postID, lastID uint32) ([]*models.Comment, error) +} + type Responder interface { OutputJSON(w http.ResponseWriter, data any, requestId string) OutputNoMoreContentJSON(w http.ResponseWriter, requestId string) @@ -44,14 +56,16 @@ type Responder interface { } type PostController struct { - postService PostService - responder Responder + postService PostService + commentService CommentService + responder Responder } -func NewPostController(service PostService, responder Responder) *PostController { +func NewPostController(service PostService, commentService CommentService, responder Responder) *PostController { return &PostController{ - postService: service, - responder: responder, + postService: service, + commentService: commentService, + responder: responder, } } @@ -113,7 +127,7 @@ func (pc *PostController) GetOne(w http.ResponseWriter, r *http.Request) { pc.responder.LogError(my_err.ErrInvalidContext, "") } - postID, err := getIDFromURL(r) + postID, err := getIDFromURL(r, postIDkey) if err != nil { pc.responder.ErrorBadRequest(w, err, reqID) return @@ -143,7 +157,7 @@ func (pc *PostController) GetOne(w http.ResponseWriter, r *http.Request) { func (pc *PostController) Update(w http.ResponseWriter, r *http.Request) { var ( reqID, ok = r.Context().Value("requestID").(string) - id, err = getIDFromURL(r) + id, err = getIDFromURL(r, postIDkey) community = r.URL.Query().Get("community") ) @@ -199,7 +213,7 @@ func (pc *PostController) Update(w http.ResponseWriter, r *http.Request) { func (pc *PostController) Delete(w http.ResponseWriter, r *http.Request) { var ( reqID, ok = r.Context().Value("requestID").(string) - postID, err = getIDFromURL(r) + postID, err = getIDFromURL(r, postIDkey) community = r.URL.Query().Get("community") ) @@ -322,10 +336,10 @@ func (pc *PostController) getPostFromBody(r *http.Request) (*models.Post, error) return &newPost, nil } -func getIDFromURL(r *http.Request) (uint32, error) { +func getIDFromURL(r *http.Request, key string) (uint32, error) { vars := mux.Vars(r) - id := vars["id"] + id := vars[key] if id == "" { return 0, errors.New("id is empty") } @@ -388,7 +402,7 @@ func (pc *PostController) SetLikeOnPost(w http.ResponseWriter, r *http.Request) pc.responder.LogError(my_err.ErrInvalidContext, "") } - postID, err := getIDFromURL(r) + postID, err := getIDFromURL(r, postIDkey) if err != nil { pc.responder.ErrorBadRequest(w, err, reqID) return @@ -426,7 +440,7 @@ func (pc *PostController) DeleteLikeFromPost(w http.ResponseWriter, r *http.Requ pc.responder.LogError(my_err.ErrInvalidContext, "") } - postID, err := getIDFromURL(r) + postID, err := getIDFromURL(r, postIDkey) if err != nil { pc.responder.ErrorBadRequest(w, err, reqID) return @@ -456,3 +470,150 @@ func (pc *PostController) DeleteLikeFromPost(w http.ResponseWriter, r *http.Requ pc.responder.OutputJSON(w, "like is unset from post", reqID) } + +func (pc *PostController) Comment(w http.ResponseWriter, r *http.Request) { + reqID, ok := r.Context().Value("requestID").(string) + if !ok { + pc.responder.LogError(my_err.ErrInvalidContext, "") + } + + postID, err := getIDFromURL(r, postIDkey) + if err != nil { + pc.responder.ErrorBadRequest(w, err, reqID) + return + } + + sess, errSession := models.SessionFromContext(r.Context()) + if errSession != nil { + pc.responder.ErrorBadRequest(w, errSession, reqID) + return + } + + var content *models.Content + err = json.NewDecoder(r.Body).Decode(content) + if err != nil { + pc.responder.ErrorBadRequest(w, err, reqID) + return + } + + id, err := pc.commentService.Comment(r.Context(), sess.UserID, postID, content) + if err != nil { + pc.responder.ErrorInternal(w, err, reqID) + return + } + + pc.responder.OutputJSON(w, id, reqID) +} + +func (pc *PostController) DeleteComment(w http.ResponseWriter, r *http.Request) { + reqID, ok := r.Context().Value("requestID").(string) + if !ok { + pc.responder.LogError(my_err.ErrInvalidContext, "") + } + + commentID, err := getIDFromURL(r, commentIDKey) + if err != nil { + pc.responder.ErrorBadRequest(w, err, reqID) + return + } + + sess, errSession := models.SessionFromContext(r.Context()) + if errSession != nil { + pc.responder.ErrorBadRequest(w, errSession, reqID) + return + } + + err = pc.commentService.DeleteComment(r.Context(), commentID, sess.UserID) + if err != nil { + if errors.Is(err, my_err.ErrAccessDenied) { + pc.responder.ErrorBadRequest(w, err, reqID) + return + } + + if errors.Is(err, my_err.ErrWrongComment) { + pc.responder.ErrorBadRequest(w, err, reqID) + return + } + + pc.responder.ErrorInternal(w, err, reqID) + return + } + + pc.responder.OutputJSON(w, "comment is deleted", reqID) +} + +func (pc *PostController) EditComment(w http.ResponseWriter, r *http.Request) { + reqID, ok := r.Context().Value("requestID").(string) + if !ok { + pc.responder.LogError(my_err.ErrInvalidContext, "") + } + + commentID, err := getIDFromURL(r, commentIDKey) + if err != nil { + pc.responder.ErrorBadRequest(w, err, reqID) + return + } + + sess, errSession := models.SessionFromContext(r.Context()) + if errSession != nil { + pc.responder.ErrorBadRequest(w, errSession, reqID) + return + } + + var content *models.Content + err = json.NewDecoder(r.Body).Decode(content) + if err != nil { + pc.responder.ErrorBadRequest(w, err, reqID) + return + } + + err = pc.commentService.EditComment(r.Context(), commentID, sess.UserID, content) + if err != nil { + if errors.Is(err, my_err.ErrAccessDenied) { + pc.responder.ErrorBadRequest(w, err, reqID) + return + } + + if errors.Is(err, my_err.ErrWrongComment) { + pc.responder.ErrorBadRequest(w, err, reqID) + return + } + + pc.responder.ErrorInternal(w, err, reqID) + return + } + + pc.responder.OutputJSON(w, "comment is updated", reqID) +} + +func (pc *PostController) GetComments(w http.ResponseWriter, r *http.Request) { + reqID, ok := r.Context().Value("requestID").(string) + if !ok { + pc.responder.LogError(my_err.ErrInvalidContext, "") + } + + postID, err := getIDFromURL(r, postIDkey) + if err != nil { + pc.responder.ErrorBadRequest(w, err, reqID) + return + } + + lastId, err := getLastID(r) + if err != nil { + pc.responder.ErrorBadRequest(w, err, reqID) + return + } + + comments, err := pc.commentService.GetComments(r.Context(), postID, uint32(lastId)) + if err != nil { + if errors.Is(err, my_err.ErrNoMoreContent) { + pc.responder.OutputNoMoreContentJSON(w, reqID) + return + } + + pc.responder.ErrorInternal(w, err, reqID) + return + } + + pc.responder.OutputJSON(w, comments, reqID) +} diff --git a/internal/post/repository/postgres/postgres.go b/internal/post/repository/postgres/postgres.go index 9336dc35..598af79d 100644 --- a/internal/post/repository/postgres/postgres.go +++ b/internal/post/repository/postgres/postgres.go @@ -28,6 +28,12 @@ const ( DeleteLikeFromPost = `DELETE FROM reaction WHERE post_id = $1 AND user_id = $2;` GetLikesOnPost = `SELECT COUNT(*) FROM reaction WHERE post_id = $1;` CheckLike = `SELECT COUNT(*) FROM reaction WHERE post_id = $1 AND user_id=$2;` + + createComment = `INSERT INTO comment (user_id, post_id, content, file_path) VALUES ($1, $2, $3, $4) RETURNING id;` + updateComment = `UPDATE comment SET content = $1, file_path = $2, updated_at = NOW() WHERE id = $3;` + deleteComment = `DELETE FROM comment WHERE id = $1;` + getCommentsBatch = `SELECT id, user_id, content, file_path, created_at FROM comment WHERE post_id = $1 and id < $2 ORDER BY created_at DESC LIMIT 20;` + getCommentAuthor = `SELECT user_id FROM comment WHERE id = $1` ) type Adapter struct { @@ -43,7 +49,9 @@ func NewAdapter(db *sql.DB) *Adapter { func (a *Adapter) Create(ctx context.Context, post *models.Post) (uint32, error) { var postID uint32 - if err := a.db.QueryRowContext(ctx, createPost, post.Header.AuthorID, post.PostContent.Text, post.PostContent.File).Scan(&postID); err != nil { + if err := a.db.QueryRowContext( + ctx, createPost, post.Header.AuthorID, post.PostContent.Text, post.PostContent.File, + ).Scan(&postID); err != nil { return 0, fmt.Errorf("postgres create post: %w", err) } @@ -54,7 +62,10 @@ func (a *Adapter) Get(ctx context.Context, postID uint32) (*models.Post, error) var post models.Post if err := a.db.QueryRowContext(ctx, getPost, postID). - Scan(&post.ID, &post.Header.AuthorID, &post.PostContent.Text, &post.PostContent.File, &post.PostContent.CreatedAt); err != nil { + Scan( + &post.ID, &post.Header.AuthorID, &post.PostContent.Text, &post.PostContent.File, + &post.PostContent.CreatedAt, + ); err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, my_err.ErrPostNotFound } @@ -85,7 +96,9 @@ func (a *Adapter) Delete(ctx context.Context, postID uint32) error { } func (a *Adapter) Update(ctx context.Context, post *models.Post) error { - res, err := a.db.ExecContext(ctx, updatePost, post.PostContent.Text, post.PostContent.UpdatedAt, post.PostContent.File, post.ID) + res, err := a.db.ExecContext( + ctx, updatePost, post.PostContent.Text, post.PostContent.UpdatedAt, post.PostContent.File, post.ID, + ) if err != nil { return fmt.Errorf("postgres update post: %w", err) @@ -117,8 +130,10 @@ func (a *Adapter) GetPosts(ctx context.Context, lastID uint32) ([]*models.Post, for rows.Next() { var post models.Post - if err := rows.Scan(&post.ID, &post.Header.AuthorID, &post.Header.CommunityID, - &post.PostContent.Text, &post.PostContent.File, &post.PostContent.CreatedAt); err != nil { + if err := rows.Scan( + &post.ID, &post.Header.AuthorID, &post.Header.CommunityID, + &post.PostContent.Text, &post.PostContent.File, &post.PostContent.CreatedAt, + ); err != nil { return nil, fmt.Errorf("postgres scan posts: %w", err) } posts = append(posts, &post) @@ -193,7 +208,10 @@ func createPostBatchFromRows(rows *sql.Rows) ([]*models.Post, error) { for rows.Next() { var post models.Post - if err := rows.Scan(&post.ID, &post.Header.AuthorID, &post.PostContent.Text, &post.PostContent.File, &post.PostContent.CreatedAt); err != nil { + if err := rows.Scan( + &post.ID, &post.Header.AuthorID, &post.PostContent.Text, &post.PostContent.File, + &post.PostContent.CreatedAt, + ); err != nil { return nil, fmt.Errorf("postgres scan posts: %w", err) } posts = append(posts, &post) @@ -223,7 +241,9 @@ func convertSliceToString(sl []uint32) string { func (a *Adapter) CreateCommunityPost(ctx context.Context, post *models.Post, communityID uint32) (uint32, error) { var ID uint32 - if err := a.db.QueryRowContext(ctx, createCommunityPost, communityID, post.PostContent.Text, post.PostContent.File).Scan(&ID); err != nil { + if err := a.db.QueryRowContext( + ctx, createCommunityPost, communityID, post.PostContent.Text, post.PostContent.File, + ).Scan(&ID); err != nil { return 0, fmt.Errorf("postgres create community post db: %w", err) } @@ -240,7 +260,10 @@ func (a *Adapter) GetCommunityPosts(ctx context.Context, communityID, id uint32) defer rows.Close() for rows.Next() { post := &models.Post{} - err = rows.Scan(&post.ID, &post.Header.CommunityID, &post.PostContent.Text, &post.PostContent.File, &post.PostContent.CreatedAt) + err = rows.Scan( + &post.ID, &post.Header.CommunityID, &post.PostContent.Text, &post.PostContent.File, + &post.PostContent.CreatedAt, + ) if err != nil { return nil, fmt.Errorf("postgres get community posts: %w", err) } @@ -297,3 +320,97 @@ func (a *Adapter) CheckLikes(ctx context.Context, postID, userID uint32) (bool, return true, nil } + +func (a *Adapter) CreateComment(ctx context.Context, comment *models.Content, userID, postID uint32) (uint32, error) { + var id uint32 + + if err := a.db.QueryRowContext( + ctx, createComment, userID, postID, comment.Text, comment.File, + ).Scan(&id); err != nil { + return 0, fmt.Errorf("postgres create comment: %w", err) + } + + return id, nil +} + +func (a *Adapter) DeleteComment(ctx context.Context, commentID uint32) error { + res, err := a.db.ExecContext(ctx, deleteComment, commentID) + + if err != nil { + return fmt.Errorf("postgres delete comment: %w", err) + } + + affected, err := res.RowsAffected() + if err != nil { + return fmt.Errorf("postgres delete comment: %w", err) + } + + if affected == 0 { + return my_err.ErrWrongComment + } + + return nil +} + +func (a *Adapter) UpdateComment(ctx context.Context, comment *models.Content, commentID uint32) error { + res, err := a.db.ExecContext( + ctx, updateComment, comment.Text, comment.File, commentID, + ) + + if err != nil { + return fmt.Errorf("postgres update comment: %w", err) + } + + affected, err := res.RowsAffected() + if err != nil { + return fmt.Errorf("postgres update comment: %w", err) + } + + if affected == 0 { + return my_err.ErrWrongComment + } + + return nil +} + +func (a *Adapter) GetComments(ctx context.Context, postID, lastID uint32) ([]*models.Comment, error) { + rows, err := a.db.QueryContext(ctx, getCommentsBatch, postID, lastID) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, my_err.ErrNoMoreContent + } + return nil, fmt.Errorf("postgres get posts: %w", err) + } + + var comments []*models.Comment + for rows.Next() { + comment := models.Comment{} + if err := rows.Scan( + &comment.ID, &comment.Header.AuthorID, &comment.Content.Text, &comment.Content.File, + &comment.Content.CreatedAt, + ); err != nil { + return nil, fmt.Errorf("postgres get comments: %w", err) + } + + comments = append(comments, &comment) + } + + if len(comments) == 0 { + return comments, my_err.ErrNoMoreContent + } + + return comments, nil +} + +func (a *Adapter) GetCommentAuthor(ctx context.Context, commentID uint32) (uint32, error) { + var authorID uint32 + + if err := a.db.QueryRowContext(ctx, getCommentAuthor, commentID).Scan(&authorID); err != nil { + if errors.Is(err, sql.ErrNoRows) { + return 0, my_err.ErrWrongComment + } + return 0, fmt.Errorf("postgres get comment author: %w", err) + } + + return authorID, nil +} diff --git a/internal/post/service/comment.go b/internal/post/service/comment.go new file mode 100644 index 00000000..de8aa3c1 --- /dev/null +++ b/internal/post/service/comment.go @@ -0,0 +1,96 @@ +package service + +import ( + "context" + "fmt" + + "github.com/2024_2_BetterCallFirewall/internal/models" + "github.com/2024_2_BetterCallFirewall/pkg/my_err" +) + +type dbI interface { + CreateComment(ctx context.Context, comment *models.Content, userID, postID uint32) (uint32, error) + DeleteComment(ctx context.Context, commentID uint32) error + UpdateComment(ctx context.Context, comment *models.Content, commentID uint32) error + GetComments(ctx context.Context, postID, lastID uint32) ([]*models.Comment, error) + GetCommentAuthor(ctx context.Context, commentID uint32) (uint32, error) +} + +type profileRepoI interface { + GetHeader(ctx context.Context, userID uint32) (*models.Header, error) +} + +type CommentService struct { + db dbI + profileRepo profileRepoI +} + +func NewCommentService(db dbI, profileRepo profileRepoI) *CommentService { + return &CommentService{ + db: db, + profileRepo: profileRepo, + } +} + +func (s *CommentService) Comment(ctx context.Context, userID, postID uint32, comment *models.Content) (uint32, error) { + id, err := s.db.CreateComment(ctx, comment, userID, postID) + if err != nil { + return 0, fmt.Errorf("create comment: %w", err) + } + + return id, nil +} + +func (s *CommentService) DeleteComment(ctx context.Context, commentID, userID uint32) error { + authorID, err := s.db.GetCommentAuthor(ctx, commentID) + if err != nil { + return fmt.Errorf("get comment author: %w", err) + } + + if authorID != userID { + return my_err.ErrAccessDenied + } + + err = s.db.DeleteComment(ctx, commentID) + if err != nil { + return fmt.Errorf("delete comment: %w", err) + } + + return nil +} + +func (s *CommentService) EditComment(ctx context.Context, commentID, userID uint32, comment *models.Content) error { + authorID, err := s.db.GetCommentAuthor(ctx, commentID) + if err != nil { + return fmt.Errorf("get comment author: %w", err) + } + + if authorID != userID { + return my_err.ErrAccessDenied + } + + err = s.db.UpdateComment(ctx, comment, commentID) + if err != nil { + return fmt.Errorf("delete comment: %w", err) + } + + return nil +} + +func (s *CommentService) GetComments(ctx context.Context, postID, lastID uint32) ([]*models.Comment, error) { + comments, err := s.db.GetComments(ctx, postID, lastID) + if err != nil { + return nil, fmt.Errorf("get comments: %w", err) + } + + for i, c := range comments { + header, err := s.profileRepo.GetHeader(ctx, c.Header.AuthorID) + if err != nil { + return nil, fmt.Errorf("get header %d: %w", i, err) + } + + comments[i].Header = *header + } + + return comments, nil +} diff --git a/internal/router/post/router.go b/internal/router/post/router.go index 43c3b3a7..5a3c5c5d 100644 --- a/internal/router/post/router.go +++ b/internal/router/post/router.go @@ -27,6 +27,11 @@ type Controller interface { SetLikeOnPost(w http.ResponseWriter, r *http.Request) DeleteLikeFromPost(w http.ResponseWriter, r *http.Request) + + Comment(w http.ResponseWriter, r *http.Request) + DeleteComment(w http.ResponseWriter, r *http.Request) + EditComment(w http.ResponseWriter, r *http.Request) + GetComments(w http.ResponseWriter, r *http.Request) } func NewRouter( @@ -39,6 +44,13 @@ func NewRouter( router.HandleFunc("/api/v1/feed/{id}", contr.Delete).Methods(http.MethodDelete, http.MethodOptions) router.HandleFunc("/api/v1/feed", contr.GetBatchPosts).Methods(http.MethodGet, http.MethodOptions) + router.HandleFunc("/api/v1/feed/{id}", contr.Comment).Methods(http.MethodPost, http.MethodOptions) + router.HandleFunc("/api/v1/feed/{id}/{comment_id}", contr.EditComment).Methods(http.MethodPut, http.MethodOptions) + router.HandleFunc("/api/v1/feed/{id}/{comment_id}", contr.DeleteComment).Methods( + http.MethodDelete, http.MethodOptions, + ) + router.HandleFunc("/api/v1/feed/{id}/comments", contr.GetComments).Methods(http.MethodGet, http.MethodOptions) + router.HandleFunc("/api/v1/feed/{id}/like", contr.SetLikeOnPost).Methods(http.MethodPost, http.MethodOptions) router.HandleFunc("/api/v1/feed/{id}/unlike", contr.DeleteLikeFromPost).Methods(http.MethodPost, http.MethodOptions) diff --git a/pkg/my_err/error.go b/pkg/my_err/error.go index 04ceb597..b86650ed 100644 --- a/pkg/my_err/error.go +++ b/pkg/my_err/error.go @@ -34,4 +34,5 @@ var ( ErrWrongCommunity = errors.New("wrong community") ErrWrongPost = errors.New("wrong post") ErrPostTooLong = errors.New("post len is too big") + ErrWrongComment = errors.New("wrong comment") ) From 98630baccc13b32e735a3a6fe0608f3d9cd9c074 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Tue, 3 Dec 2024 20:12:08 +0300 Subject: [PATCH 004/135] fix app --- internal/app/post/app.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/internal/app/post/app.go b/internal/app/post/app.go index b53298a4..d8e3b830 100644 --- a/internal/app/post/app.go +++ b/internal/app/post/app.go @@ -38,7 +38,8 @@ func GetHTTPServer(cfg *config.Config, postMetric *metrics.HttpMetrics) (*http.S ForceColors: true, } - connStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s", + connStr := fmt.Sprintf( + "host=%s port=%s user=%s password=%s dbname=%s sslmode=%s", cfg.DB.Host, cfg.DB.Port, cfg.DB.User, @@ -73,7 +74,8 @@ func GetHTTPServer(cfg *config.Config, postMetric *metrics.HttpMetrics) (*http.S cp := community.New(communityProvider) postService := service.NewPostServiceImpl(repo, pp, cp) - postController := controller.NewPostController(postService, responder) + commentService := service.NewCommentService(repo, pp) + postController := controller.NewPostController(postService, commentService, responder) rout := post.NewRouter(postController, sm, logger, postMetric) server := &http.Server{ @@ -101,7 +103,8 @@ func GetGRPCServer(cfg *config.Config, grpcMetrics *metrics.GrpcMetrics) (*grpc. ForceColors: true, } - connStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s", + connStr := fmt.Sprintf( + "host=%s port=%s user=%s password=%s dbname=%s sslmode=%s", cfg.DB.Host, cfg.DB.Port, cfg.DB.User, From 5ef5b96487408227b8d69c4794cf6dac00e6a055 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Tue, 3 Dec 2024 20:14:09 +0300 Subject: [PATCH 005/135] fix controller test --- internal/post/controller/controller_test.go | 1006 +++++++++++-------- internal/post/controller/mock.go | 125 ++- 2 files changed, 700 insertions(+), 431 deletions(-) diff --git a/internal/post/controller/controller_test.go b/internal/post/controller/controller_test.go index 7798c478..f4e0a8f6 100644 --- a/internal/post/controller/controller_test.go +++ b/internal/post/controller/controller_test.go @@ -18,11 +18,12 @@ import ( func getController(ctrl *gomock.Controller) (*PostController, *mocks) { m := &mocks{ - postService: NewMockPostService(ctrl), - responder: NewMockResponder(ctrl), + postService: NewMockPostService(ctrl), + commentService: NewMockCommentService(ctrl), + responder: NewMockResponder(ctrl), } - return NewPostController(m.postService, m.responder), m + return NewPostController(m.postService, m.commentService, m.responder), m } func TestNewPostController(t *testing.T) { @@ -53,17 +54,21 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { name: "2", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() res := &Request{r: req, w: w} return res, nil @@ -79,17 +84,21 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { name: "3", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -107,17 +116,21 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Create(gomock.Any(), gomock.Any()).Return(uint32(0), errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { name: "4", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -135,17 +148,21 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Create(gomock.Any(), gomock.Any()).Return(uint32(2), nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, { name: "5", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=ljkhkg", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=ljkhkg", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -162,17 +179,21 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { name: "6", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -190,17 +211,21 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(false) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { name: "7", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -218,18 +243,24 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) - m.postService.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any()).Return(uint32(0), errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.postService.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any()).Return( + uint32(0), errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { name: "8", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -248,17 +279,21 @@ func TestCreate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.postService.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any()).Return(uint32(10), nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, { name: "9", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=10", + bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -275,40 +310,44 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -333,10 +372,12 @@ func TestGetOne(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -359,10 +400,12 @@ func TestGetOne(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -387,10 +430,12 @@ func TestGetOne(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, my_err.ErrPostNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -415,10 +460,12 @@ func TestGetOne(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -443,10 +490,12 @@ func TestGetOne(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, { @@ -469,40 +518,44 @@ func TestGetOne(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -526,10 +579,12 @@ func TestUpdate(t *testing.T) { }, ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -552,10 +607,12 @@ func TestUpdate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -579,11 +636,15 @@ func TestUpdate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(0), errors.New("error")) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return( + uint32(0), errors.New("error"), + ) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -608,17 +669,21 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(10), nil) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { name: "5", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -638,17 +703,21 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(my_err.ErrPostNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { name: "6", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -668,17 +737,21 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { name: "7", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -698,17 +771,21 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, { name: "8", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=nkljbkvhj", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=nkljbkvhj", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -726,17 +803,21 @@ func TestUpdate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { name: "9", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -755,17 +836,21 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(false) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { name: "10", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -785,17 +870,21 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, { name: "11", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=10", - bytes.NewBuffer([]byte(`{"id"`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=10", + bytes.NewBuffer([]byte(`{"id"`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -814,17 +903,21 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { name: "12", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=1", - bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=1", + bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -843,40 +936,44 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -901,10 +998,12 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -927,10 +1026,12 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -956,10 +1057,12 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(my_err.ErrPostNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -985,10 +1088,12 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -1014,10 +1119,12 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, { @@ -1041,10 +1148,12 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, error, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, error, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1067,10 +1176,12 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, error, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, error, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1096,40 +1207,44 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, error, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, error, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1154,10 +1269,12 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1179,10 +1296,12 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1205,10 +1324,14 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, my_err.ErrNoMoreContent) - m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do(func(w, req any) { - request.w.WriteHeader(http.StatusNoContent) - }) + m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, my_err.ErrNoMoreContent, + ) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) }, }, { @@ -1231,11 +1354,15 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -1259,10 +1386,12 @@ func TestGetBatchPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, { @@ -1284,10 +1413,12 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1312,10 +1443,12 @@ func TestGetBatchPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetBatchFromFriend(gomock.Any(), gomock.Any(), gomock.Any()). Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, { @@ -1338,10 +1471,12 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1364,11 +1499,15 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.postService.EXPECT().GetCommunityPost(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.postService.EXPECT().GetCommunityPost( + gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), + ).Return(nil, nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, { @@ -1391,40 +1530,44 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1449,10 +1592,12 @@ func TestSetLikeOnPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1475,10 +1620,12 @@ func TestSetLikeOnPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1503,10 +1650,12 @@ func TestSetLikeOnPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1530,11 +1679,15 @@ func TestSetLikeOnPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return( + false, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -1559,11 +1712,15 @@ func TestSetLikeOnPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, nil) - m.postService.EXPECT().SetLikeToPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.postService.EXPECT().SetLikeToPost( + gomock.Any(), gomock.Any(), gomock.Any(), + ).Return(errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -1589,40 +1746,44 @@ func TestSetLikeOnPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, nil) m.postService.EXPECT().SetLikeToPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1647,10 +1808,12 @@ func TestDeleteLikeFromPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1673,10 +1836,12 @@ func TestDeleteLikeFromPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1701,10 +1866,12 @@ func TestDeleteLikeFromPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, nil) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1728,11 +1895,15 @@ func TestDeleteLikeFromPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return( + false, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -1757,11 +1928,15 @@ func TestDeleteLikeFromPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) - m.postService.EXPECT().DeleteLikeFromPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.postService.EXPECT().DeleteLikeFromPost( + gomock.Any(), gomock.Any(), gomock.Any(), + ).Return(errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -1787,46 +1962,51 @@ func TestDeleteLikeFromPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) m.postService.EXPECT().DeleteLikeFromPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } type mocks struct { - postService *MockPostService - responder *MockResponder + postService *MockPostService + commentService *MockCommentService + responder *MockResponder } type Request struct { diff --git a/internal/post/controller/mock.go b/internal/post/controller/mock.go index b7f365fa..5346a356 100644 --- a/internal/post/controller/mock.go +++ b/internal/post/controller/mock.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: controller.go +// +// Generated by this command: +// +// mockgen -destination=mock.go -source=controller.go -package=controller +// // Package controller is a generated GoMock package. package controller @@ -17,6 +22,7 @@ import ( type MockPostService struct { ctrl *gomock.Controller recorder *MockPostServiceMockRecorder + isgomock struct{} } // MockPostServiceMockRecorder is the mock recorder for MockPostService. @@ -45,7 +51,7 @@ func (m *MockPostService) CheckAccessToCommunity(ctx context.Context, userID, co } // CheckAccessToCommunity indicates an expected call of CheckAccessToCommunity. -func (mr *MockPostServiceMockRecorder) CheckAccessToCommunity(ctx, userID, communityID interface{}) *gomock.Call { +func (mr *MockPostServiceMockRecorder) CheckAccessToCommunity(ctx, userID, communityID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckAccessToCommunity", reflect.TypeOf((*MockPostService)(nil).CheckAccessToCommunity), ctx, userID, communityID) } @@ -60,7 +66,7 @@ func (m *MockPostService) CheckLikes(ctx context.Context, postID, userID uint32) } // CheckLikes indicates an expected call of CheckLikes. -func (mr *MockPostServiceMockRecorder) CheckLikes(ctx, postID, userID interface{}) *gomock.Call { +func (mr *MockPostServiceMockRecorder) CheckLikes(ctx, postID, userID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckLikes", reflect.TypeOf((*MockPostService)(nil).CheckLikes), ctx, postID, userID) } @@ -75,7 +81,7 @@ func (m *MockPostService) Create(ctx context.Context, post *models.Post) (uint32 } // Create indicates an expected call of Create. -func (mr *MockPostServiceMockRecorder) Create(ctx, post interface{}) *gomock.Call { +func (mr *MockPostServiceMockRecorder) Create(ctx, post any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockPostService)(nil).Create), ctx, post) } @@ -90,7 +96,7 @@ func (m *MockPostService) CreateCommunityPost(ctx context.Context, post *models. } // CreateCommunityPost indicates an expected call of CreateCommunityPost. -func (mr *MockPostServiceMockRecorder) CreateCommunityPost(ctx, post interface{}) *gomock.Call { +func (mr *MockPostServiceMockRecorder) CreateCommunityPost(ctx, post any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateCommunityPost", reflect.TypeOf((*MockPostService)(nil).CreateCommunityPost), ctx, post) } @@ -104,7 +110,7 @@ func (m *MockPostService) Delete(ctx context.Context, postID uint32) error { } // Delete indicates an expected call of Delete. -func (mr *MockPostServiceMockRecorder) Delete(ctx, postID interface{}) *gomock.Call { +func (mr *MockPostServiceMockRecorder) Delete(ctx, postID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockPostService)(nil).Delete), ctx, postID) } @@ -118,7 +124,7 @@ func (m *MockPostService) DeleteLikeFromPost(ctx context.Context, postID, userID } // DeleteLikeFromPost indicates an expected call of DeleteLikeFromPost. -func (mr *MockPostServiceMockRecorder) DeleteLikeFromPost(ctx, postID, userID interface{}) *gomock.Call { +func (mr *MockPostServiceMockRecorder) DeleteLikeFromPost(ctx, postID, userID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteLikeFromPost", reflect.TypeOf((*MockPostService)(nil).DeleteLikeFromPost), ctx, postID, userID) } @@ -133,7 +139,7 @@ func (m *MockPostService) Get(ctx context.Context, postID, userID uint32) (*mode } // Get indicates an expected call of Get. -func (mr *MockPostServiceMockRecorder) Get(ctx, postID, userID interface{}) *gomock.Call { +func (mr *MockPostServiceMockRecorder) Get(ctx, postID, userID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockPostService)(nil).Get), ctx, postID, userID) } @@ -148,7 +154,7 @@ func (m *MockPostService) GetBatch(ctx context.Context, lastID, userID uint32) ( } // GetBatch indicates an expected call of GetBatch. -func (mr *MockPostServiceMockRecorder) GetBatch(ctx, lastID, userID interface{}) *gomock.Call { +func (mr *MockPostServiceMockRecorder) GetBatch(ctx, lastID, userID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBatch", reflect.TypeOf((*MockPostService)(nil).GetBatch), ctx, lastID, userID) } @@ -163,7 +169,7 @@ func (m *MockPostService) GetBatchFromFriend(ctx context.Context, userID, lastID } // GetBatchFromFriend indicates an expected call of GetBatchFromFriend. -func (mr *MockPostServiceMockRecorder) GetBatchFromFriend(ctx, userID, lastID interface{}) *gomock.Call { +func (mr *MockPostServiceMockRecorder) GetBatchFromFriend(ctx, userID, lastID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBatchFromFriend", reflect.TypeOf((*MockPostService)(nil).GetBatchFromFriend), ctx, userID, lastID) } @@ -178,7 +184,7 @@ func (m *MockPostService) GetCommunityPost(ctx context.Context, communityID, use } // GetCommunityPost indicates an expected call of GetCommunityPost. -func (mr *MockPostServiceMockRecorder) GetCommunityPost(ctx, communityID, userID, lastID interface{}) *gomock.Call { +func (mr *MockPostServiceMockRecorder) GetCommunityPost(ctx, communityID, userID, lastID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCommunityPost", reflect.TypeOf((*MockPostService)(nil).GetCommunityPost), ctx, communityID, userID, lastID) } @@ -193,7 +199,7 @@ func (m *MockPostService) GetPostAuthorID(ctx context.Context, postID uint32) (u } // GetPostAuthorID indicates an expected call of GetPostAuthorID. -func (mr *MockPostServiceMockRecorder) GetPostAuthorID(ctx, postID interface{}) *gomock.Call { +func (mr *MockPostServiceMockRecorder) GetPostAuthorID(ctx, postID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPostAuthorID", reflect.TypeOf((*MockPostService)(nil).GetPostAuthorID), ctx, postID) } @@ -207,7 +213,7 @@ func (m *MockPostService) SetLikeToPost(ctx context.Context, postID, userID uint } // SetLikeToPost indicates an expected call of SetLikeToPost. -func (mr *MockPostServiceMockRecorder) SetLikeToPost(ctx, postID, userID interface{}) *gomock.Call { +func (mr *MockPostServiceMockRecorder) SetLikeToPost(ctx, postID, userID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLikeToPost", reflect.TypeOf((*MockPostService)(nil).SetLikeToPost), ctx, postID, userID) } @@ -221,15 +227,98 @@ func (m *MockPostService) Update(ctx context.Context, post *models.Post) error { } // Update indicates an expected call of Update. -func (mr *MockPostServiceMockRecorder) Update(ctx, post interface{}) *gomock.Call { +func (mr *MockPostServiceMockRecorder) Update(ctx, post any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockPostService)(nil).Update), ctx, post) } +// MockCommentService is a mock of CommentService interface. +type MockCommentService struct { + ctrl *gomock.Controller + recorder *MockCommentServiceMockRecorder + isgomock struct{} +} + +// MockCommentServiceMockRecorder is the mock recorder for MockCommentService. +type MockCommentServiceMockRecorder struct { + mock *MockCommentService +} + +// NewMockCommentService creates a new mock instance. +func NewMockCommentService(ctrl *gomock.Controller) *MockCommentService { + mock := &MockCommentService{ctrl: ctrl} + mock.recorder = &MockCommentServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCommentService) EXPECT() *MockCommentServiceMockRecorder { + return m.recorder +} + +// Comment mocks base method. +func (m *MockCommentService) Comment(ctx context.Context, userID, postID uint32, comment *models.Content) (uint32, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Comment", ctx, userID, postID, comment) + ret0, _ := ret[0].(uint32) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Comment indicates an expected call of Comment. +func (mr *MockCommentServiceMockRecorder) Comment(ctx, userID, postID, comment any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Comment", reflect.TypeOf((*MockCommentService)(nil).Comment), ctx, userID, postID, comment) +} + +// DeleteComment mocks base method. +func (m *MockCommentService) DeleteComment(ctx context.Context, commentID, userID uint32) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteComment", ctx, commentID, userID) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteComment indicates an expected call of DeleteComment. +func (mr *MockCommentServiceMockRecorder) DeleteComment(ctx, commentID, userID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteComment", reflect.TypeOf((*MockCommentService)(nil).DeleteComment), ctx, commentID, userID) +} + +// EditComment mocks base method. +func (m *MockCommentService) EditComment(ctx context.Context, commentID, userID uint32, comment *models.Content) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EditComment", ctx, commentID, userID, comment) + ret0, _ := ret[0].(error) + return ret0 +} + +// EditComment indicates an expected call of EditComment. +func (mr *MockCommentServiceMockRecorder) EditComment(ctx, commentID, userID, comment any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EditComment", reflect.TypeOf((*MockCommentService)(nil).EditComment), ctx, commentID, userID, comment) +} + +// GetComments mocks base method. +func (m *MockCommentService) GetComments(ctx context.Context, postID, lastID uint32) ([]*models.Comment, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetComments", ctx, postID, lastID) + ret0, _ := ret[0].([]*models.Comment) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetComments indicates an expected call of GetComments. +func (mr *MockCommentServiceMockRecorder) GetComments(ctx, postID, lastID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetComments", reflect.TypeOf((*MockCommentService)(nil).GetComments), ctx, postID, lastID) +} + // MockResponder is a mock of Responder interface. type MockResponder struct { ctrl *gomock.Controller recorder *MockResponderMockRecorder + isgomock struct{} } // MockResponderMockRecorder is the mock recorder for MockResponder. @@ -256,7 +345,7 @@ func (m *MockResponder) ErrorBadRequest(w http.ResponseWriter, err error, reques } // ErrorBadRequest indicates an expected call of ErrorBadRequest. -func (mr *MockResponderMockRecorder) ErrorBadRequest(w, err, requestId interface{}) *gomock.Call { +func (mr *MockResponderMockRecorder) ErrorBadRequest(w, err, requestId any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ErrorBadRequest", reflect.TypeOf((*MockResponder)(nil).ErrorBadRequest), w, err, requestId) } @@ -268,7 +357,7 @@ func (m *MockResponder) ErrorInternal(w http.ResponseWriter, err error, requestI } // ErrorInternal indicates an expected call of ErrorInternal. -func (mr *MockResponderMockRecorder) ErrorInternal(w, err, requestId interface{}) *gomock.Call { +func (mr *MockResponderMockRecorder) ErrorInternal(w, err, requestId any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ErrorInternal", reflect.TypeOf((*MockResponder)(nil).ErrorInternal), w, err, requestId) } @@ -280,7 +369,7 @@ func (m *MockResponder) LogError(err error, requestId string) { } // LogError indicates an expected call of LogError. -func (mr *MockResponderMockRecorder) LogError(err, requestId interface{}) *gomock.Call { +func (mr *MockResponderMockRecorder) LogError(err, requestId any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogError", reflect.TypeOf((*MockResponder)(nil).LogError), err, requestId) } @@ -292,7 +381,7 @@ func (m *MockResponder) OutputJSON(w http.ResponseWriter, data any, requestId st } // OutputJSON indicates an expected call of OutputJSON. -func (mr *MockResponderMockRecorder) OutputJSON(w, data, requestId interface{}) *gomock.Call { +func (mr *MockResponderMockRecorder) OutputJSON(w, data, requestId any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OutputJSON", reflect.TypeOf((*MockResponder)(nil).OutputJSON), w, data, requestId) } @@ -304,7 +393,7 @@ func (m *MockResponder) OutputNoMoreContentJSON(w http.ResponseWriter, requestId } // OutputNoMoreContentJSON indicates an expected call of OutputNoMoreContentJSON. -func (mr *MockResponderMockRecorder) OutputNoMoreContentJSON(w, requestId interface{}) *gomock.Call { +func (mr *MockResponderMockRecorder) OutputNoMoreContentJSON(w, requestId any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OutputNoMoreContentJSON", reflect.TypeOf((*MockResponder)(nil).OutputNoMoreContentJSON), w, requestId) } From f9b35f97bcb39a3a160f5ff687139ce89c262554 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Tue, 3 Dec 2024 23:30:00 +0300 Subject: [PATCH 006/135] add comment count --- internal/post/repository/postgres/postgres.go | 15 +++++ internal/post/service/mock.go | 57 +++++++++++++------ internal/post/service/mock_helper.go | 27 ++++++++- internal/post/service/post.go | 14 ++++- internal/post/service/post_profile.go | 10 +++- 5 files changed, 100 insertions(+), 23 deletions(-) diff --git a/internal/post/repository/postgres/postgres.go b/internal/post/repository/postgres/postgres.go index 598af79d..3c444a7f 100644 --- a/internal/post/repository/postgres/postgres.go +++ b/internal/post/repository/postgres/postgres.go @@ -34,6 +34,7 @@ const ( deleteComment = `DELETE FROM comment WHERE id = $1;` getCommentsBatch = `SELECT id, user_id, content, file_path, created_at FROM comment WHERE post_id = $1 and id < $2 ORDER BY created_at DESC LIMIT 20;` getCommentAuthor = `SELECT user_id FROM comment WHERE id = $1` + getCommentCount = `SELECT COUNT(*) FROM comment WHERE post_id=$1` ) type Adapter struct { @@ -414,3 +415,17 @@ func (a *Adapter) GetCommentAuthor(ctx context.Context, commentID uint32) (uint3 return authorID, nil } + +func (a *Adapter) GetCommentCount(ctx context.Context, postID uint32) (uint32, error) { + var count uint32 + + if err := a.db.QueryRowContext(ctx, getCommentCount, postID).Scan(&count); err != nil { + if errors.Is(err, sql.ErrNoRows) { + return 0, my_err.ErrWrongPost + } + return 0, fmt.Errorf("postgres get comment count: %w", err) + } + + return count, nil + +} diff --git a/internal/post/service/mock.go b/internal/post/service/mock.go index 5f540151..d7c4032b 100644 --- a/internal/post/service/mock.go +++ b/internal/post/service/mock.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: post.go +// +// Generated by this command: +// +// mockgen -destination=mock.go -source=post.go -package=service +// // Package service is a generated GoMock package. package service @@ -16,6 +21,7 @@ import ( type MockDB struct { ctrl *gomock.Controller recorder *MockDBMockRecorder + isgomock struct{} } // MockDBMockRecorder is the mock recorder for MockDB. @@ -45,7 +51,7 @@ func (m *MockDB) CheckLikes(ctx context.Context, postID, userID uint32) (bool, e } // CheckLikes indicates an expected call of CheckLikes. -func (mr *MockDBMockRecorder) CheckLikes(ctx, postID, userID interface{}) *gomock.Call { +func (mr *MockDBMockRecorder) CheckLikes(ctx, postID, userID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckLikes", reflect.TypeOf((*MockDB)(nil).CheckLikes), ctx, postID, userID) } @@ -60,7 +66,7 @@ func (m *MockDB) Create(ctx context.Context, post *models.Post) (uint32, error) } // Create indicates an expected call of Create. -func (mr *MockDBMockRecorder) Create(ctx, post interface{}) *gomock.Call { +func (mr *MockDBMockRecorder) Create(ctx, post any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockDB)(nil).Create), ctx, post) } @@ -75,7 +81,7 @@ func (m *MockDB) CreateCommunityPost(ctx context.Context, post *models.Post, com } // CreateCommunityPost indicates an expected call of CreateCommunityPost. -func (mr *MockDBMockRecorder) CreateCommunityPost(ctx, post, communityID interface{}) *gomock.Call { +func (mr *MockDBMockRecorder) CreateCommunityPost(ctx, post, communityID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateCommunityPost", reflect.TypeOf((*MockDB)(nil).CreateCommunityPost), ctx, post, communityID) } @@ -89,7 +95,7 @@ func (m *MockDB) Delete(ctx context.Context, postID uint32) error { } // Delete indicates an expected call of Delete. -func (mr *MockDBMockRecorder) Delete(ctx, postID interface{}) *gomock.Call { +func (mr *MockDBMockRecorder) Delete(ctx, postID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockDB)(nil).Delete), ctx, postID) } @@ -103,7 +109,7 @@ func (m *MockDB) DeleteLikeFromPost(ctx context.Context, postID, userID uint32) } // DeleteLikeFromPost indicates an expected call of DeleteLikeFromPost. -func (mr *MockDBMockRecorder) DeleteLikeFromPost(ctx, postID, userID interface{}) *gomock.Call { +func (mr *MockDBMockRecorder) DeleteLikeFromPost(ctx, postID, userID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteLikeFromPost", reflect.TypeOf((*MockDB)(nil).DeleteLikeFromPost), ctx, postID, userID) } @@ -118,11 +124,26 @@ func (m *MockDB) Get(ctx context.Context, postID uint32) (*models.Post, error) { } // Get indicates an expected call of Get. -func (mr *MockDBMockRecorder) Get(ctx, postID interface{}) *gomock.Call { +func (mr *MockDBMockRecorder) Get(ctx, postID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockDB)(nil).Get), ctx, postID) } +// GetCommentCount mocks base method. +func (m *MockDB) GetCommentCount(ctx context.Context, postID uint32) (uint32, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCommentCount", ctx, postID) + ret0, _ := ret[0].(uint32) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCommentCount indicates an expected call of GetCommentCount. +func (mr *MockDBMockRecorder) GetCommentCount(ctx, postID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCommentCount", reflect.TypeOf((*MockDB)(nil).GetCommentCount), ctx, postID) +} + // GetCommunityPosts mocks base method. func (m *MockDB) GetCommunityPosts(ctx context.Context, communityID, lastID uint32) ([]*models.Post, error) { m.ctrl.T.Helper() @@ -133,7 +154,7 @@ func (m *MockDB) GetCommunityPosts(ctx context.Context, communityID, lastID uint } // GetCommunityPosts indicates an expected call of GetCommunityPosts. -func (mr *MockDBMockRecorder) GetCommunityPosts(ctx, communityID, lastID interface{}) *gomock.Call { +func (mr *MockDBMockRecorder) GetCommunityPosts(ctx, communityID, lastID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCommunityPosts", reflect.TypeOf((*MockDB)(nil).GetCommunityPosts), ctx, communityID, lastID) } @@ -148,7 +169,7 @@ func (m *MockDB) GetFriendsPosts(ctx context.Context, friendsID []uint32, lastID } // GetFriendsPosts indicates an expected call of GetFriendsPosts. -func (mr *MockDBMockRecorder) GetFriendsPosts(ctx, friendsID, lastID interface{}) *gomock.Call { +func (mr *MockDBMockRecorder) GetFriendsPosts(ctx, friendsID, lastID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFriendsPosts", reflect.TypeOf((*MockDB)(nil).GetFriendsPosts), ctx, friendsID, lastID) } @@ -163,7 +184,7 @@ func (m *MockDB) GetLikesOnPost(ctx context.Context, postID uint32) (uint32, err } // GetLikesOnPost indicates an expected call of GetLikesOnPost. -func (mr *MockDBMockRecorder) GetLikesOnPost(ctx, postID interface{}) *gomock.Call { +func (mr *MockDBMockRecorder) GetLikesOnPost(ctx, postID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLikesOnPost", reflect.TypeOf((*MockDB)(nil).GetLikesOnPost), ctx, postID) } @@ -178,7 +199,7 @@ func (m *MockDB) GetPostAuthor(ctx context.Context, postID uint32) (uint32, erro } // GetPostAuthor indicates an expected call of GetPostAuthor. -func (mr *MockDBMockRecorder) GetPostAuthor(ctx, postID interface{}) *gomock.Call { +func (mr *MockDBMockRecorder) GetPostAuthor(ctx, postID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPostAuthor", reflect.TypeOf((*MockDB)(nil).GetPostAuthor), ctx, postID) } @@ -193,7 +214,7 @@ func (m *MockDB) GetPosts(ctx context.Context, lastID uint32) ([]*models.Post, e } // GetPosts indicates an expected call of GetPosts. -func (mr *MockDBMockRecorder) GetPosts(ctx, lastID interface{}) *gomock.Call { +func (mr *MockDBMockRecorder) GetPosts(ctx, lastID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPosts", reflect.TypeOf((*MockDB)(nil).GetPosts), ctx, lastID) } @@ -207,7 +228,7 @@ func (m *MockDB) SetLikeToPost(ctx context.Context, postID, userID uint32) error } // SetLikeToPost indicates an expected call of SetLikeToPost. -func (mr *MockDBMockRecorder) SetLikeToPost(ctx, postID, userID interface{}) *gomock.Call { +func (mr *MockDBMockRecorder) SetLikeToPost(ctx, postID, userID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLikeToPost", reflect.TypeOf((*MockDB)(nil).SetLikeToPost), ctx, postID, userID) } @@ -221,7 +242,7 @@ func (m *MockDB) Update(ctx context.Context, post *models.Post) error { } // Update indicates an expected call of Update. -func (mr *MockDBMockRecorder) Update(ctx, post interface{}) *gomock.Call { +func (mr *MockDBMockRecorder) Update(ctx, post any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockDB)(nil).Update), ctx, post) } @@ -230,6 +251,7 @@ func (mr *MockDBMockRecorder) Update(ctx, post interface{}) *gomock.Call { type MockProfileRepo struct { ctrl *gomock.Controller recorder *MockProfileRepoMockRecorder + isgomock struct{} } // MockProfileRepoMockRecorder is the mock recorder for MockProfileRepo. @@ -259,7 +281,7 @@ func (m *MockProfileRepo) GetFriendsID(ctx context.Context, userID uint32) ([]ui } // GetFriendsID indicates an expected call of GetFriendsID. -func (mr *MockProfileRepoMockRecorder) GetFriendsID(ctx, userID interface{}) *gomock.Call { +func (mr *MockProfileRepoMockRecorder) GetFriendsID(ctx, userID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFriendsID", reflect.TypeOf((*MockProfileRepo)(nil).GetFriendsID), ctx, userID) } @@ -274,7 +296,7 @@ func (m *MockProfileRepo) GetHeader(ctx context.Context, userID uint32) (*models } // GetHeader indicates an expected call of GetHeader. -func (mr *MockProfileRepoMockRecorder) GetHeader(ctx, userID interface{}) *gomock.Call { +func (mr *MockProfileRepoMockRecorder) GetHeader(ctx, userID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHeader", reflect.TypeOf((*MockProfileRepo)(nil).GetHeader), ctx, userID) } @@ -283,6 +305,7 @@ func (mr *MockProfileRepoMockRecorder) GetHeader(ctx, userID interface{}) *gomoc type MockCommunityRepo struct { ctrl *gomock.Controller recorder *MockCommunityRepoMockRecorder + isgomock struct{} } // MockCommunityRepoMockRecorder is the mock recorder for MockCommunityRepo. @@ -311,7 +334,7 @@ func (m *MockCommunityRepo) CheckAccess(ctx context.Context, communityID, userID } // CheckAccess indicates an expected call of CheckAccess. -func (mr *MockCommunityRepoMockRecorder) CheckAccess(ctx, communityID, userID interface{}) *gomock.Call { +func (mr *MockCommunityRepoMockRecorder) CheckAccess(ctx, communityID, userID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckAccess", reflect.TypeOf((*MockCommunityRepo)(nil).CheckAccess), ctx, communityID, userID) } @@ -326,7 +349,7 @@ func (m *MockCommunityRepo) GetHeader(ctx context.Context, communityID uint32) ( } // GetHeader indicates an expected call of GetHeader. -func (mr *MockCommunityRepoMockRecorder) GetHeader(ctx, communityID interface{}) *gomock.Call { +func (mr *MockCommunityRepoMockRecorder) GetHeader(ctx, communityID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHeader", reflect.TypeOf((*MockCommunityRepo)(nil).GetHeader), ctx, communityID) } diff --git a/internal/post/service/mock_helper.go b/internal/post/service/mock_helper.go index b4d722bd..9eb80e89 100644 --- a/internal/post/service/mock_helper.go +++ b/internal/post/service/mock_helper.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: post_profile.go +// +// Generated by this command: +// +// mockgen -destination=mock_helper.go -source=post_profile.go -package=service +// // Package service is a generated GoMock package. package service @@ -16,6 +21,7 @@ import ( type MockPostProfileDB struct { ctrl *gomock.Controller recorder *MockPostProfileDBMockRecorder + isgomock struct{} } // MockPostProfileDBMockRecorder is the mock recorder for MockPostProfileDB. @@ -45,7 +51,7 @@ func (m *MockPostProfileDB) CheckLikes(ctx context.Context, postID, userID uint3 } // CheckLikes indicates an expected call of CheckLikes. -func (mr *MockPostProfileDBMockRecorder) CheckLikes(ctx, postID, userID interface{}) *gomock.Call { +func (mr *MockPostProfileDBMockRecorder) CheckLikes(ctx, postID, userID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckLikes", reflect.TypeOf((*MockPostProfileDB)(nil).CheckLikes), ctx, postID, userID) } @@ -60,11 +66,26 @@ func (m *MockPostProfileDB) GetAuthorPosts(ctx context.Context, header *models.H } // GetAuthorPosts indicates an expected call of GetAuthorPosts. -func (mr *MockPostProfileDBMockRecorder) GetAuthorPosts(ctx, header interface{}) *gomock.Call { +func (mr *MockPostProfileDBMockRecorder) GetAuthorPosts(ctx, header any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAuthorPosts", reflect.TypeOf((*MockPostProfileDB)(nil).GetAuthorPosts), ctx, header) } +// GetCommentCount mocks base method. +func (m *MockPostProfileDB) GetCommentCount(ctx context.Context, postID uint32) (uint32, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCommentCount", ctx, postID) + ret0, _ := ret[0].(uint32) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCommentCount indicates an expected call of GetCommentCount. +func (mr *MockPostProfileDBMockRecorder) GetCommentCount(ctx, postID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCommentCount", reflect.TypeOf((*MockPostProfileDB)(nil).GetCommentCount), ctx, postID) +} + // GetLikesOnPost mocks base method. func (m *MockPostProfileDB) GetLikesOnPost(ctx context.Context, postID uint32) (uint32, error) { m.ctrl.T.Helper() @@ -75,7 +96,7 @@ func (m *MockPostProfileDB) GetLikesOnPost(ctx context.Context, postID uint32) ( } // GetLikesOnPost indicates an expected call of GetLikesOnPost. -func (mr *MockPostProfileDBMockRecorder) GetLikesOnPost(ctx, postID interface{}) *gomock.Call { +func (mr *MockPostProfileDBMockRecorder) GetLikesOnPost(ctx, postID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLikesOnPost", reflect.TypeOf((*MockPostProfileDB)(nil).GetLikesOnPost), ctx, postID) } diff --git a/internal/post/service/post.go b/internal/post/service/post.go index 30ac4bad..538f8c76 100644 --- a/internal/post/service/post.go +++ b/internal/post/service/post.go @@ -26,6 +26,8 @@ type DB interface { DeleteLikeFromPost(ctx context.Context, postID uint32, userID uint32) error GetLikesOnPost(ctx context.Context, postID uint32) (uint32, error) CheckLikes(ctx context.Context, postID, userID uint32) (bool, error) + + GetCommentCount(ctx context.Context, postID uint32) (uint32, error) } type ProfileRepo interface { @@ -109,7 +111,9 @@ func (s *PostServiceImpl) GetBatch(ctx context.Context, lastID, userID uint32) ( return posts, nil } -func (s *PostServiceImpl) GetBatchFromFriend(ctx context.Context, userID uint32, lastID uint32) ([]*models.Post, error) { +func (s *PostServiceImpl) GetBatchFromFriend( + ctx context.Context, userID uint32, lastID uint32, +) ([]*models.Post, error) { friends, err := s.profileRepo.GetFriendsID(ctx, userID) if err != nil { return nil, fmt.Errorf("get friends: %w", err) @@ -151,7 +155,9 @@ func (s *PostServiceImpl) CreateCommunityPost(ctx context.Context, post *models. return id, nil } -func (s *PostServiceImpl) GetCommunityPost(ctx context.Context, communityID, userID, lastID uint32) ([]*models.Post, error) { +func (s *PostServiceImpl) GetCommunityPost( + ctx context.Context, communityID, userID, lastID uint32, +) ([]*models.Post, error) { posts, err := s.db.GetCommunityPosts(ctx, communityID, lastID) if err != nil { return nil, fmt.Errorf("get posts: %w", err) @@ -231,6 +237,10 @@ func (s *PostServiceImpl) setPostFields(ctx context.Context, post *models.Post, post.IsLiked = liked post.PostContent.CreatedAt = convertTime(post.PostContent.CreatedAt) + post.CommentCount, err = s.db.GetCommentCount(ctx, post.ID) + if err != nil { + return fmt.Errorf("get comment count: %w", err) + } return nil } diff --git a/internal/post/service/post_profile.go b/internal/post/service/post_profile.go index 06ed4676..753a560c 100644 --- a/internal/post/service/post_profile.go +++ b/internal/post/service/post_profile.go @@ -12,6 +12,7 @@ type PostProfileDB interface { GetAuthorPosts(ctx context.Context, header *models.Header) ([]*models.Post, error) GetLikesOnPost(ctx context.Context, postID uint32) (uint32, error) CheckLikes(ctx context.Context, postID, userID uint32) (bool, error) + GetCommentCount(ctx context.Context, postID uint32) (uint32, error) } type PostProfileImpl struct { @@ -24,7 +25,9 @@ func NewPostProfileImpl(db PostProfileDB) *PostProfileImpl { } } -func (p *PostProfileImpl) GetAuthorsPosts(ctx context.Context, header *models.Header, userID uint32) ([]*models.Post, error) { +func (p *PostProfileImpl) GetAuthorsPosts( + ctx context.Context, header *models.Header, userID uint32, +) ([]*models.Post, error) { posts, err := p.db.GetAuthorPosts(ctx, header) if err != nil { return nil, err @@ -43,6 +46,11 @@ func (p *PostProfileImpl) GetAuthorsPosts(ctx context.Context, header *models.He } posts[i].IsLiked = liked posts[i].PostContent.CreatedAt = convertTime(post.PostContent.CreatedAt) + commentCount, err := p.db.GetCommentCount(ctx, post.ID) + if err != nil { + return nil, fmt.Errorf("get comment count: %w", err) + } + posts[i].CommentCount = commentCount } return posts, nil From 4cc6d6d53c5eabe06d2f78f3ead7771dfb49d41b Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Tue, 3 Dec 2024 23:50:23 +0300 Subject: [PATCH 007/135] fix: create comment --- internal/post/controller/controller.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index bab643df..c2edb940 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -489,14 +489,14 @@ func (pc *PostController) Comment(w http.ResponseWriter, r *http.Request) { return } - var content *models.Content - err = json.NewDecoder(r.Body).Decode(content) + var content models.Content + err = json.NewDecoder(r.Body).Decode(&content) if err != nil { pc.responder.ErrorBadRequest(w, err, reqID) return } - id, err := pc.commentService.Comment(r.Context(), sess.UserID, postID, content) + id, err := pc.commentService.Comment(r.Context(), sess.UserID, postID, &content) if err != nil { pc.responder.ErrorInternal(w, err, reqID) return From 2dd9b4fd8a1e555b06937d05f488ae18f2a2d045 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Wed, 4 Dec 2024 00:15:07 +0300 Subject: [PATCH 008/135] feature: change password --- internal/models/profile.go | 5 +++ internal/profile/controller/controller.go | 35 +++++++++++++++ internal/profile/repository.go | 2 + internal/profile/repository/QueryConsts.go | 2 + internal/profile/repository/postgres.go | 48 +++++++++++++++++--- internal/profile/service/usecase.go | 52 +++++++++++++++++++--- internal/profile/usecase.go | 1 + internal/router/profile/router.go | 4 ++ 8 files changed, 138 insertions(+), 11 deletions(-) diff --git a/internal/models/profile.go b/internal/models/profile.go index 72133fc5..441d5739 100644 --- a/internal/models/profile.go +++ b/internal/models/profile.go @@ -24,3 +24,8 @@ type ShortProfile struct { IsSubscription bool `json:"is_subscription"` Avatar Picture `json:"avatar"` } + +type ChangePasswordReq struct { + OldPassword string `json:"old_password"` + NewPassword string `json:"new_password"` +} diff --git a/internal/profile/controller/controller.go b/internal/profile/controller/controller.go index 470eb84d..15bc3bd9 100644 --- a/internal/profile/controller/controller.go +++ b/internal/profile/controller/controller.go @@ -9,6 +9,7 @@ import ( "strconv" "github.com/gorilla/mux" + "golang.org/x/crypto/bcrypt" "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/internal/profile" @@ -525,3 +526,37 @@ func (h *ProfileHandlerImplementation) SearchProfile(w http.ResponseWriter, r *h h.Responder.OutputJSON(w, profiles, reqID) } + +func (h *ProfileHandlerImplementation) ChangePassword(w http.ResponseWriter, r *http.Request) { + reqID, ok := r.Context().Value("requestID").(string) + if !ok { + h.Responder.LogError(my_err.ErrInvalidContext, "") + } + + sess, err := models.SessionFromContext(r.Context()) + if err != nil { + h.Responder.ErrorBadRequest(w, fmt.Errorf("update profile: %w", my_err.ErrSessionNotFound), reqID) + return + } + + var request models.ChangePasswordReq + if err := json.NewDecoder(r.Body).Decode(&request); err != nil { + h.Responder.ErrorBadRequest(w, err, reqID) + return + } + + if err = h.ProfileManager.ChangePassword( + r.Context(), sess.UserID, request.OldPassword, request.NewPassword, + ); err != nil { + if errors.Is(err, my_err.ErrUserNotFound) || + errors.Is(err, my_err.ErrWrongEmailOrPassword) || + errors.Is(err, bcrypt.ErrPasswordTooLong) { + h.Responder.ErrorBadRequest(w, err, reqID) + } + + h.Responder.ErrorInternal(w, err, reqID) + return + } + + h.Responder.OutputJSON(w, "password change", reqID) +} diff --git a/internal/profile/repository.go b/internal/profile/repository.go index 831163a1..b5c543ce 100644 --- a/internal/profile/repository.go +++ b/internal/profile/repository.go @@ -14,6 +14,8 @@ type Repository interface { UpdateWithAvatar(context.Context, *models.FullProfile) error DeleteProfile(uint32) error Search(ctx context.Context, subStr string, lastId uint32) ([]*models.ShortProfile, error) + GetUserById(ctx context.Context, id uint32) (*models.User, error) + ChangePassword(ctx context.Context, id uint32, password string) error CheckFriendship(context.Context, uint32, uint32) (bool, error) AddFriendsReq(receiver uint32, sender uint32) error diff --git a/internal/profile/repository/QueryConsts.go b/internal/profile/repository/QueryConsts.go index 14a9fe42..6fd4d1dc 100644 --- a/internal/profile/repository/QueryConsts.go +++ b/internal/profile/repository/QueryConsts.go @@ -3,6 +3,8 @@ package repository const ( CreateUser = `INSERT INTO profile (first_name, last_name, email, hashed_password) VALUES ($1, $2, $3, $4) ON CONFLICT (email) DO NOTHING RETURNING id;` GetUserByEmail = `SELECT id, first_name, last_name, email, hashed_password FROM profile WHERE email = $1 LIMIT 1;` + GetUserByID = `SELECT id, first_name, last_name, email, hashed_password FROM profile WHERE id = $1 LIMIT 1;` + ChangePassword = `UPDATE profile SET hashed_password = $1 WHERE id = $2;` GetProfileByID = "SELECT profile.id, first_name, last_name, bio, avatar FROM profile WHERE profile.id = $1 LIMIT 1;" GetStatus = "SELECT status FROM friend WHERE (sender = $1 AND receiver = $2) LIMIT 1" diff --git a/internal/profile/repository/postgres.go b/internal/profile/repository/postgres.go index d161cbc1..f2834d4b 100644 --- a/internal/profile/repository/postgres.go +++ b/internal/profile/repository/postgres.go @@ -41,7 +41,9 @@ func (p *ProfileRepo) Create(user *models.User, ctx context.Context) (uint32, er func (p *ProfileRepo) GetByEmail(email string, ctx context.Context) (*models.User, error) { user := &models.User{} - err := p.DB.QueryRowContext(ctx, GetUserByEmail, email).Scan(&user.ID, &user.FirstName, &user.LastName, &user.Email, &user.Password) + err := p.DB.QueryRowContext(ctx, GetUserByEmail, email).Scan( + &user.ID, &user.FirstName, &user.LastName, &user.Email, &user.Password, + ) if err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, fmt.Errorf("postgres get user: %w", my_err.ErrUserNotFound) @@ -54,7 +56,9 @@ func (p *ProfileRepo) GetByEmail(email string, ctx context.Context) (*models.Use func (p *ProfileRepo) GetProfileById(ctx context.Context, id uint32) (*models.FullProfile, error) { res := &models.FullProfile{} - err := p.DB.QueryRowContext(ctx, GetProfileByID, id).Scan(&res.ID, &res.FirstName, &res.LastName, &res.Bio, &res.Avatar) + err := p.DB.QueryRowContext(ctx, GetProfileByID, id).Scan( + &res.ID, &res.FirstName, &res.LastName, &res.Bio, &res.Avatar, + ) if err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, my_err.ErrProfileNotFound @@ -138,7 +142,10 @@ func (p *ProfileRepo) UpdateProfile(ctx context.Context, profile *models.FullPro } func (p *ProfileRepo) UpdateWithAvatar(ctx context.Context, newProfile *models.FullProfile) error { - _, err := p.DB.ExecContext(ctx, UpdateProfileAvatar, newProfile.ID, newProfile.Avatar, newProfile.FirstName, newProfile.LastName, newProfile.Bio) + _, err := p.DB.ExecContext( + ctx, UpdateProfileAvatar, newProfile.ID, newProfile.Avatar, newProfile.FirstName, newProfile.LastName, + newProfile.Bio, + ) if err != nil { return fmt.Errorf("update profile with avatar %w", err) } @@ -233,7 +240,9 @@ func (p *ProfileRepo) GetAllSubs(ctx context.Context, u uint32, lastId uint32) ( return res, nil } -func (p *ProfileRepo) GetAllSubscriptions(ctx context.Context, u uint32, lastId uint32) ([]*models.ShortProfile, error) { +func (p *ProfileRepo) GetAllSubscriptions( + ctx context.Context, u uint32, lastId uint32, +) ([]*models.ShortProfile, error) { res := make([]*models.ShortProfile, 0) rows, err := p.DB.QueryContext(ctx, GetAllSubscriptions, u, lastId, LIMIT) if err != nil { @@ -313,7 +322,9 @@ func (p *ProfileRepo) GetHeader(ctx context.Context, u uint32) (*models.Header, return profile, nil } -func (p *ProfileRepo) GetCommunitySubs(ctx context.Context, communityID uint32, lastInsertId uint32) ([]*models.ShortProfile, error) { +func (p *ProfileRepo) GetCommunitySubs( + ctx context.Context, communityID uint32, lastInsertId uint32, +) ([]*models.ShortProfile, error) { var subs []*models.ShortProfile rows, err := p.DB.QueryContext(ctx, GetCommunitySubs, communityID, lastInsertId, LIMIT) if err != nil { @@ -354,3 +365,30 @@ func (p *ProfileRepo) Search(ctx context.Context, query string, lastID uint32) ( return res, nil } + +func (p *ProfileRepo) GetUserById(ctx context.Context, id uint32) (*models.User, error) { + user := &models.User{} + err := p.DB.QueryRowContext(ctx, GetUserByID, id).Scan( + &user.ID, &user.FirstName, &user.LastName, &user.Email, &user.Password, + ) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, fmt.Errorf("postgres get user: %w", my_err.ErrUserNotFound) + } + return nil, fmt.Errorf("postgres get user: %w", err) + } + + return user, nil +} + +func (p *ProfileRepo) ChangePassword(ctx context.Context, id uint32, password string) error { + if err := p.DB.QueryRowContext(ctx, ChangePassword, password, id).Err(); err != nil { + if errors.Is(err, sql.ErrNoRows) { + return fmt.Errorf("postgres change password: %w", my_err.ErrUserNotFound) + } + + return fmt.Errorf("change password: %w", err) + } + + return nil +} diff --git a/internal/profile/service/usecase.go b/internal/profile/service/usecase.go index 8b61de0c..f00bf100 100644 --- a/internal/profile/service/usecase.go +++ b/internal/profile/service/usecase.go @@ -7,6 +7,8 @@ import ( "fmt" "slices" + "golang.org/x/crypto/bcrypt" + "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/internal/profile" "github.com/2024_2_BetterCallFirewall/pkg/my_err" @@ -64,7 +66,9 @@ func (p ProfileUsecaseImplementation) GetProfileById(ctx context.Context, u uint return profile, nil } -func (p ProfileUsecaseImplementation) GetAll(ctx context.Context, self uint32, lastId uint32) ([]*models.ShortProfile, error) { +func (p ProfileUsecaseImplementation) GetAll( + ctx context.Context, self uint32, lastId uint32, +) ([]*models.ShortProfile, error) { profiles, err := p.repo.GetAll(ctx, self, lastId) if err != nil { return nil, fmt.Errorf("get all profiles usecase: %w", err) @@ -172,7 +176,9 @@ func (p ProfileUsecaseImplementation) setStatuses(ctx context.Context, profiles return nil } -func (p ProfileUsecaseImplementation) GetAllFriends(ctx context.Context, id uint32, lastId uint32) ([]*models.ShortProfile, error) { +func (p ProfileUsecaseImplementation) GetAllFriends( + ctx context.Context, id uint32, lastId uint32, +) ([]*models.ShortProfile, error) { res, err := p.repo.GetAllFriends(ctx, id, lastId) if err != nil { return nil, fmt.Errorf("get all friends usecase: %w", err) @@ -189,7 +195,9 @@ func (p ProfileUsecaseImplementation) GetAllFriends(ctx context.Context, id uint return res, nil } -func (p ProfileUsecaseImplementation) GetAllSubs(ctx context.Context, id uint32, lastId uint32) ([]*models.ShortProfile, error) { +func (p ProfileUsecaseImplementation) GetAllSubs( + ctx context.Context, id uint32, lastId uint32, +) ([]*models.ShortProfile, error) { res, err := p.repo.GetAllSubs(ctx, id, lastId) if err != nil { return nil, fmt.Errorf("get all subs usecase: %w", err) @@ -203,7 +211,9 @@ func (p ProfileUsecaseImplementation) GetAllSubs(ctx context.Context, id uint32, return res, nil } -func (p ProfileUsecaseImplementation) GetAllSubscriptions(ctx context.Context, id uint32, lastId uint32) ([]*models.ShortProfile, error) { +func (p ProfileUsecaseImplementation) GetAllSubscriptions( + ctx context.Context, id uint32, lastId uint32, +) ([]*models.ShortProfile, error) { res, err := p.repo.GetAllSubscriptions(ctx, id, lastId) if err != nil { return nil, fmt.Errorf("get all subscriptions usecase: %w", err) @@ -226,7 +236,9 @@ func (p ProfileUsecaseImplementation) GetHeader(ctx context.Context, userID uint return header, nil } -func (p ProfileUsecaseImplementation) GetCommunitySubs(ctx context.Context, communityID, lastId uint32) ([]*models.ShortProfile, error) { +func (p ProfileUsecaseImplementation) GetCommunitySubs( + ctx context.Context, communityID, lastId uint32, +) ([]*models.ShortProfile, error) { subs, err := p.repo.GetCommunitySubs(ctx, communityID, lastId) if err != nil { return nil, fmt.Errorf("get subs: %w", err) @@ -235,7 +247,9 @@ func (p ProfileUsecaseImplementation) GetCommunitySubs(ctx context.Context, comm return subs, nil } -func (p ProfileUsecaseImplementation) Search(ctx context.Context, subStr string, lastId uint32) ([]*models.ShortProfile, error) { +func (p ProfileUsecaseImplementation) Search( + ctx context.Context, subStr string, lastId uint32, +) ([]*models.ShortProfile, error) { profiles, err := p.repo.Search(ctx, subStr, lastId) if err != nil { return nil, fmt.Errorf("search: %w", err) @@ -248,3 +262,29 @@ func (p ProfileUsecaseImplementation) Search(ctx context.Context, subStr string, return profiles, nil } + +func (p ProfileUsecaseImplementation) ChangePassword( + ctx context.Context, + userID uint32, + oldPassword, + newPassword string, +) error { + user, err := p.repo.GetUserById(ctx, userID) + if err != nil { + return fmt.Errorf("change password usecase: %w", err) + } + if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(oldPassword)); err != nil { + return fmt.Errorf("change password usecase: %w", my_err.ErrWrongEmailOrPassword) + } + + hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost) + if err != nil { + return fmt.Errorf("change password usecase: %w", err) + } + + if err := p.repo.ChangePassword(ctx, userID, string(hashedPassword)); err != nil { + return fmt.Errorf("change password usecase: %w", err) + } + + return nil +} diff --git a/internal/profile/usecase.go b/internal/profile/usecase.go index 8cc1d3db..0592afbc 100644 --- a/internal/profile/usecase.go +++ b/internal/profile/usecase.go @@ -12,6 +12,7 @@ type ProfileUsecase interface { UpdateProfile(context.Context, *models.FullProfile) error DeleteProfile(uint32) error Search(ctx context.Context, subStr string, lastId uint32) ([]*models.ShortProfile, error) + ChangePassword(ctx context.Context, userID uint32, oldPassword, newPassword string) error SendFriendReq(receiver uint32, sender uint32) error AcceptFriendReq(who uint32, whose uint32) error diff --git a/internal/router/profile/router.go b/internal/router/profile/router.go index b7064138..5589b6d0 100644 --- a/internal/router/profile/router.go +++ b/internal/router/profile/router.go @@ -30,6 +30,7 @@ type ProfileController interface { GetAllSubscriptions(w http.ResponseWriter, r *http.Request) GetCommunitySubs(w http.ResponseWriter, r *http.Request) + ChangePassword(w http.ResponseWriter, r *http.Request) } type SessionManager interface { @@ -79,6 +80,9 @@ func NewRouter( router.HandleFunc("/api/v1/profile/search/", profileControl.SearchProfile).Methods( http.MethodGet, http.MethodOptions, ) + router.HandleFunc("/api/v1/profile/password", profileControl.ChangePassword).Methods( + http.MethodPut, http.MethodOptions, + ) router.Handle("/api/v1/metrics", promhttp.Handler()) From c945ebbc7d15962b9873f905f52b361fb48aa26b Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Wed, 4 Dec 2024 00:16:51 +0300 Subject: [PATCH 009/135] fix router testd --- internal/router/profile/router_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/router/profile/router_test.go b/internal/router/profile/router_test.go index 8e30b2cc..0f536550 100644 --- a/internal/router/profile/router_test.go +++ b/internal/router/profile/router_test.go @@ -57,6 +57,8 @@ func (m mockProfileController) GetCommunitySubs(w http.ResponseWriter, r *http.R func (m mockProfileController) SearchProfile(w http.ResponseWriter, r *http.Request) {} +func (m mockProfileController) ChangePassword(w http.ResponseWriter, r *http.Request) {} + func TestNewRouter(t *testing.T) { r := NewRouter(mockProfileController{}, mockSessionManager{}, logrus.New(), &metrics.HttpMetrics{}) assert.NotNil(t, r) From 72f52ca52d2c7d5e3ff910a6623ae27b2ade1efa Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Wed, 4 Dec 2024 11:45:52 +0300 Subject: [PATCH 010/135] fix rout for delete --- internal/router/profile/router.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/router/profile/router.go b/internal/router/profile/router.go index 5589b6d0..05b7daca 100644 --- a/internal/router/profile/router.go +++ b/internal/router/profile/router.go @@ -52,7 +52,7 @@ func NewRouter( router.HandleFunc("/api/v1/profile/{id}", profileControl.GetProfileById).Methods(http.MethodGet, http.MethodOptions) router.HandleFunc("/api/v1/profiles", profileControl.GetAll).Methods(http.MethodGet, http.MethodOptions) router.HandleFunc("/api/v1/profile", profileControl.UpdateProfile).Methods(http.MethodPut, http.MethodOptions) - router.HandleFunc("api/v1/profile", profileControl.DeleteProfile).Methods(http.MethodDelete, http.MethodOptions) + router.HandleFunc("/api/v1/profile", profileControl.DeleteProfile).Methods(http.MethodDelete, http.MethodOptions) router.HandleFunc("/api/v1/profile/{id}/friend/subscribe", profileControl.SendFriendReq).Methods( http.MethodPost, http.MethodOptions, ) From af7b1733445b93f1f4e2b26afb176d354f372ae2 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 5 Dec 2024 14:26:05 +0300 Subject: [PATCH 011/135] return comment when create --- internal/post/controller/controller.go | 6 +++--- internal/post/service/comment.go | 21 ++++++++++++++++++--- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index c2edb940..a9b71819 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -40,7 +40,7 @@ type PostService interface { } type CommentService interface { - Comment(ctx context.Context, userID, postID uint32, comment *models.Content) (uint32, error) + Comment(ctx context.Context, userID, postID uint32, comment *models.Content) (*models.Comment, error) DeleteComment(ctx context.Context, commentID, userID uint32) error EditComment(ctx context.Context, commentID, userID uint32, comment *models.Content) error GetComments(ctx context.Context, postID, lastID uint32) ([]*models.Comment, error) @@ -496,13 +496,13 @@ func (pc *PostController) Comment(w http.ResponseWriter, r *http.Request) { return } - id, err := pc.commentService.Comment(r.Context(), sess.UserID, postID, &content) + newComment, err := pc.commentService.Comment(r.Context(), sess.UserID, postID, &content) if err != nil { pc.responder.ErrorInternal(w, err, reqID) return } - pc.responder.OutputJSON(w, id, reqID) + pc.responder.OutputJSON(w, newComment, reqID) } func (pc *PostController) DeleteComment(w http.ResponseWriter, r *http.Request) { diff --git a/internal/post/service/comment.go b/internal/post/service/comment.go index de8aa3c1..46b75361 100644 --- a/internal/post/service/comment.go +++ b/internal/post/service/comment.go @@ -3,6 +3,7 @@ package service import ( "context" "fmt" + "time" "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/pkg/my_err" @@ -32,13 +33,27 @@ func NewCommentService(db dbI, profileRepo profileRepoI) *CommentService { } } -func (s *CommentService) Comment(ctx context.Context, userID, postID uint32, comment *models.Content) (uint32, error) { +func (s *CommentService) Comment( + ctx context.Context, userID, postID uint32, comment *models.Content, +) (*models.Comment, error) { id, err := s.db.CreateComment(ctx, comment, userID, postID) if err != nil { - return 0, fmt.Errorf("create comment: %w", err) + return nil, fmt.Errorf("create comment: %w", err) } - return id, nil + header, err := s.profileRepo.GetHeader(ctx, userID) + if err != nil { + return nil, fmt.Errorf("get header: %w", err) + } + + comment.CreatedAt = time.Now() + newComment := &models.Comment{ + ID: id, + Content: *comment, + Header: *header, + } + + return newComment, nil } func (s *CommentService) DeleteComment(ctx context.Context, commentID, userID uint32) error { From 6a9ac8ffb68191fa9c1c606da88386b6a057cfd3 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 5 Dec 2024 14:28:19 +0300 Subject: [PATCH 012/135] fix tests --- internal/post/controller/mock.go | 4 ++-- internal/router/post/router_test.go | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/internal/post/controller/mock.go b/internal/post/controller/mock.go index 5346a356..ea53e956 100644 --- a/internal/post/controller/mock.go +++ b/internal/post/controller/mock.go @@ -257,10 +257,10 @@ func (m *MockCommentService) EXPECT() *MockCommentServiceMockRecorder { } // Comment mocks base method. -func (m *MockCommentService) Comment(ctx context.Context, userID, postID uint32, comment *models.Content) (uint32, error) { +func (m *MockCommentService) Comment(ctx context.Context, userID, postID uint32, comment *models.Content) (*models.Comment, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Comment", ctx, userID, postID, comment) - ret0, _ := ret[0].(uint32) + ret0, _ := ret[0].(*models.Comment) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/internal/router/post/router_test.go b/internal/router/post/router_test.go index 89058dd5..ea893a5c 100644 --- a/internal/router/post/router_test.go +++ b/internal/router/post/router_test.go @@ -27,6 +27,14 @@ func (m mockSessionManager) Destroy(sess *models.Session) error { type mockPostController struct{} +func (m mockPostController) Comment(w http.ResponseWriter, r *http.Request) {} + +func (m mockPostController) DeleteComment(w http.ResponseWriter, r *http.Request) {} + +func (m mockPostController) EditComment(w http.ResponseWriter, r *http.Request) {} + +func (m mockPostController) GetComments(w http.ResponseWriter, r *http.Request) {} + func (m mockPostController) SetLikeOnPost(w http.ResponseWriter, r *http.Request) {} func (m mockPostController) DeleteLikeFromPost(w http.ResponseWriter, r *http.Request) {} From e5909c2678b5b86ba49fde286d4ff8506973de10 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 5 Dec 2024 21:15:13 +0300 Subject: [PATCH 013/135] add tests for comment --- internal/post/controller/controller.go | 40 +- internal/post/controller/controller_test.go | 880 ++++++++++++++++++++ pkg/my_err/error.go | 2 +- 3 files changed, 910 insertions(+), 12 deletions(-) diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index a9b71819..e74bdee2 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -8,6 +8,7 @@ import ( "math" "net/http" "strconv" + "strings" "github.com/gorilla/mux" @@ -18,6 +19,7 @@ import ( const ( postIDkey = "id" commentIDKey = "comment_id" + filePrefix = "/image/" ) //go:generate mockgen -destination=mock.go -source=$GOFILE -package=${GOPACKAGE} @@ -87,8 +89,8 @@ func (pc *PostController) Create(w http.ResponseWriter, r *http.Request) { return } - if len(newPost.PostContent.Text) > 499 { - pc.responder.ErrorBadRequest(w, my_err.ErrPostTooLong, reqID) + if !validateContent(newPost.PostContent) { + pc.responder.ErrorBadRequest(w, my_err.ErrTextTooLong, reqID) return } if comunity != "" { @@ -192,8 +194,9 @@ func (pc *PostController) Update(w http.ResponseWriter, r *http.Request) { pc.responder.ErrorBadRequest(w, err, reqID) return } - if len(post.PostContent.Text) > 499 { - pc.responder.ErrorBadRequest(w, my_err.ErrPostTooLong, reqID) + + if !validateContent(post.PostContent) { + pc.responder.ErrorBadRequest(w, my_err.ErrTextTooLong, reqID) return } post.ID = id @@ -490,12 +493,16 @@ func (pc *PostController) Comment(w http.ResponseWriter, r *http.Request) { } var content models.Content - err = json.NewDecoder(r.Body).Decode(&content) - if err != nil { + if err := json.NewDecoder(r.Body).Decode(&content); err != nil { pc.responder.ErrorBadRequest(w, err, reqID) return } + if !validateContent(content) { + pc.responder.ErrorBadRequest(w, my_err.ErrTextTooLong, reqID) + return + } + newComment, err := pc.commentService.Comment(r.Context(), sess.UserID, postID, &content) if err != nil { pc.responder.ErrorInternal(w, err, reqID) @@ -560,15 +567,18 @@ func (pc *PostController) EditComment(w http.ResponseWriter, r *http.Request) { return } - var content *models.Content - err = json.NewDecoder(r.Body).Decode(content) - if err != nil { + var content models.Content + if err := json.NewDecoder(r.Body).Decode(&content); err != nil { pc.responder.ErrorBadRequest(w, err, reqID) return } - err = pc.commentService.EditComment(r.Context(), commentID, sess.UserID, content) - if err != nil { + if !validateContent(content) { + pc.responder.ErrorBadRequest(w, my_err.ErrTextTooLong, reqID) + return + } + + if err := pc.commentService.EditComment(r.Context(), commentID, sess.UserID, &content); err != nil { if errors.Is(err, my_err.ErrAccessDenied) { pc.responder.ErrorBadRequest(w, err, reqID) return @@ -617,3 +627,11 @@ func (pc *PostController) GetComments(w http.ResponseWriter, r *http.Request) { pc.responder.OutputJSON(w, comments, reqID) } + +func validateContent(content models.Content) bool { + return validateFile(content.File) && len(content.Text) < 500 +} + +func validateFile(filepath models.Picture) bool { + return len(filepath) < 100 && (len(filepath) == 0 || strings.HasPrefix(string(filepath), filePrefix)) +} diff --git a/internal/post/controller/controller_test.go b/internal/post/controller/controller_test.go index f4e0a8f6..197d5a31 100644 --- a/internal/post/controller/controller_test.go +++ b/internal/post/controller/controller_test.go @@ -2003,6 +2003,886 @@ func TestDeleteLikeFromPost(t *testing.T) { } } +func TestComment(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/api/v1/feed/2", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/api/v1/feed/2", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/api/v1/feed/2", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "4", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/api/v1/feed/2", bytes.NewBuffer([]byte(`{"id":1}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusInternalServerError, Body: "error"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().Comment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) + }, + }, + { + name: "5", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/api/v1/feed/2", bytes.NewBuffer([]byte(`{"id":1}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().Comment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) + }, + }, + { + name: "6", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed/2", + bytes.NewBuffer([]byte(`{"file":"очень большой текст, написанный в поле файл, как он сюда попал - честно говоря хз, надо проверить валидацию на файл длину"}`)), + ) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + } + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestGetComment(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/feed/2/comment", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.GetComments(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/feed/2/comment?id=fnf", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.GetComments(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/feed/2/comment?id=4", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.GetComments(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusInternalServerError, Body: "error"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) + }, + }, + { + name: "4", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/feed/2/comment", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.GetComments(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) + }, + }, + { + name: "5", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/feed/2/comment", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.GetComments(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusNoContent}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, my_err.ErrNoMoreContent) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestEditComment(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "4", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", bytes.NewBuffer([]byte(`{"text":"1"}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().EditComment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(my_err.ErrAccessDenied) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "5", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", bytes.NewBuffer([]byte(`{"text":"1"}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().EditComment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(my_err.ErrWrongComment) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "6", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", bytes.NewBuffer([]byte(`{"text":"1"}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusInternalServerError, Body: "error"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().EditComment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(errors.New("err")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) + }, + }, + { + name: "7", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", bytes.NewBuffer([]byte(`{"text":"1"}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().EditComment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) + }, + }, + { + name: "8", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/2/1", + bytes.NewBuffer([]byte(`{"file":"очень большой текст, написанный в поле файл, как он сюда попал - честно говоря хз, надо проверить валидацию на файл длину"}`)), + ) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestDeleteComment(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().DeleteComment(gomock.Any(), gomock.Any(), gomock.Any()). + Return(my_err.ErrAccessDenied) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "4", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().DeleteComment(gomock.Any(), gomock.Any(), gomock.Any()). + Return(my_err.ErrWrongComment) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "5", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusInternalServerError, Body: "error"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().DeleteComment(gomock.Any(), gomock.Any(), gomock.Any()). + Return(errors.New("err")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) + }, + }, + { + name: "6", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().DeleteComment(gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + type mocks struct { postService *MockPostService commentService *MockCommentService diff --git a/pkg/my_err/error.go b/pkg/my_err/error.go index b86650ed..c4bad589 100644 --- a/pkg/my_err/error.go +++ b/pkg/my_err/error.go @@ -33,6 +33,6 @@ var ( ErrLikeAlreadyExists = errors.New("like already exists") ErrWrongCommunity = errors.New("wrong community") ErrWrongPost = errors.New("wrong post") - ErrPostTooLong = errors.New("post len is too big") + ErrTextTooLong = errors.New("text len is too big") ErrWrongComment = errors.New("wrong comment") ) From 291d974929c7bc131e77b7d83d025cf35dac1385 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 5 Dec 2024 21:29:44 +0300 Subject: [PATCH 014/135] fix test: post service --- internal/post/repository/postgres/postgres.go | 1 - internal/post/service/post_profile_test.go | 94 +- internal/post/service/post_test.go | 931 +++++++++++------- 3 files changed, 624 insertions(+), 402 deletions(-) diff --git a/internal/post/repository/postgres/postgres.go b/internal/post/repository/postgres/postgres.go index 3c444a7f..c171263d 100644 --- a/internal/post/repository/postgres/postgres.go +++ b/internal/post/repository/postgres/postgres.go @@ -427,5 +427,4 @@ func (a *Adapter) GetCommentCount(ctx context.Context, postID uint32) (uint32, e } return count, nil - } diff --git a/internal/post/service/post_profile_test.go b/internal/post/service/post_profile_test.go index 6a27105b..6fa49a77 100644 --- a/internal/post/service/post_profile_test.go +++ b/internal/post/service/post_profile_test.go @@ -64,7 +64,8 @@ func TestGetAuthorsPost(t *testing.T) { { ID: 1, }, - }, nil) + }, nil, + ) m.repo.EXPECT().GetLikesOnPost(gomock.Any(), gomock.Any()).Return(uint32(0), errMock) }, }, @@ -86,7 +87,8 @@ func TestGetAuthorsPost(t *testing.T) { { ID: 1, }, - }, nil) + }, nil, + ) m.repo.EXPECT().GetLikesOnPost(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.repo.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, errMock) }, @@ -102,9 +104,10 @@ func TestGetAuthorsPost(t *testing.T) { ExpectedResult: func() ([]*models.Post, error) { return []*models.Post{ { - ID: 1, - IsLiked: true, - LikesCount: 1, + ID: 1, + IsLiked: true, + LikesCount: 1, + CommentCount: 1, }, }, nil }, @@ -115,39 +118,68 @@ func TestGetAuthorsPost(t *testing.T) { { ID: 1, }, - }, nil) + }, nil, + ) + m.repo.EXPECT().GetLikesOnPost(gomock.Any(), gomock.Any()).Return(uint32(1), nil).AnyTimes() + m.repo.EXPECT().GetCommentCount(gomock.Any(), gomock.Any()).Return(uint32(1), nil).AnyTimes() + m.repo.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) + }, + }, + { + name: "5", + SetupInput: func() (*input, error) { + return &input{}, nil + }, + Run: func(ctx context.Context, implementation *PostProfileImpl, request input) ([]*models.Post, error) { + return implementation.GetAuthorsPosts(ctx, request.header, request.userID) + }, + ExpectedResult: func() ([]*models.Post, error) { + return nil, nil + }, + ExpectedErr: errMock, + SetupMock: func(request input, m *mocksHelper) { + m.repo.EXPECT().GetAuthorPosts(gomock.Any(), gomock.Any()).Return( + []*models.Post{ + { + ID: 1, + }, + }, nil, + ) m.repo.EXPECT().GetLikesOnPost(gomock.Any(), gomock.Any()).Return(uint32(1), nil) + m.repo.EXPECT().GetCommentCount(gomock.Any(), gomock.Any()).Return(uint32(0), errMock) m.repo.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getServiceHelper(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getServiceHelper(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } diff --git a/internal/post/service/post_test.go b/internal/post/service/post_test.go index 823e93ea..a5e68d30 100644 --- a/internal/post/service/post_test.go +++ b/internal/post/service/post_test.go @@ -74,31 +74,33 @@ func TestCreate(t *testing.T) { } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getService(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getService(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -114,7 +116,9 @@ func TestGet(t *testing.T) { SetupInput: func() (*userAndPostIDs, error) { return &userAndPostIDs{postId: 0, userID: 0}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs) (*models.Post, error) { + Run: func( + ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs, + ) (*models.Post, error) { return implementation.Get(ctx, request.postId, request.userID) }, ExpectedResult: func() (*models.Post, error) { @@ -130,7 +134,9 @@ func TestGet(t *testing.T) { SetupInput: func() (*userAndPostIDs, error) { return &userAndPostIDs{postId: 1, userID: 1}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs) (*models.Post, error) { + Run: func( + ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs, + ) (*models.Post, error) { return implementation.Get(ctx, request.postId, request.userID) }, ExpectedResult: func() (*models.Post, error) { @@ -145,7 +151,8 @@ func TestGet(t *testing.T) { AuthorID: 1, }, }, - nil) + nil, + ) m.profileRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(nil, errMock) }, }, @@ -154,7 +161,9 @@ func TestGet(t *testing.T) { SetupInput: func() (*userAndPostIDs, error) { return &userAndPostIDs{postId: 1, userID: 1}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs) (*models.Post, error) { + Run: func( + ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs, + ) (*models.Post, error) { return implementation.Get(ctx, request.postId, request.userID) }, ExpectedResult: func() (*models.Post, error) { @@ -169,7 +178,8 @@ func TestGet(t *testing.T) { AuthorID: 0, }, }, - nil) + nil, + ) m.communityRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(nil, errMock) }, }, @@ -178,7 +188,9 @@ func TestGet(t *testing.T) { SetupInput: func() (*userAndPostIDs, error) { return &userAndPostIDs{postId: 1, userID: 1}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs) (*models.Post, error) { + Run: func( + ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs, + ) (*models.Post, error) { return implementation.Get(ctx, request.postId, request.userID) }, ExpectedResult: func() (*models.Post, error) { @@ -193,12 +205,15 @@ func TestGet(t *testing.T) { AuthorID: 1, }, }, - nil) - m.profileRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(&models.Header{ - CommunityID: 0, - AuthorID: 1, - Author: "user", - }, nil) + nil, + ) + m.profileRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return( + &models.Header{ + CommunityID: 0, + AuthorID: 1, + Author: "user", + }, nil, + ) m.postRepo.EXPECT().GetLikesOnPost(gomock.Any(), gomock.Any()).Return(uint32(0), errMock) }, }, @@ -207,7 +222,9 @@ func TestGet(t *testing.T) { SetupInput: func() (*userAndPostIDs, error) { return &userAndPostIDs{postId: 1, userID: 1}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs) (*models.Post, error) { + Run: func( + ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs, + ) (*models.Post, error) { return implementation.Get(ctx, request.postId, request.userID) }, ExpectedResult: func() (*models.Post, error) { @@ -222,12 +239,15 @@ func TestGet(t *testing.T) { AuthorID: 0, }, }, - nil) - m.communityRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(&models.Header{ - CommunityID: 1, - AuthorID: 0, - Author: "community", - }, nil) + nil, + ) + m.communityRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return( + &models.Header{ + CommunityID: 1, + AuthorID: 0, + Author: "community", + }, nil, + ) m.postRepo.EXPECT().GetLikesOnPost(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postRepo.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, errMock) }, @@ -237,7 +257,9 @@ func TestGet(t *testing.T) { SetupInput: func() (*userAndPostIDs, error) { return &userAndPostIDs{postId: 1, userID: 1}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs) (*models.Post, error) { + Run: func( + ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs, + ) (*models.Post, error) { return implementation.Get(ctx, request.postId, request.userID) }, ExpectedResult: func() (*models.Post, error) { @@ -260,12 +282,52 @@ func TestGet(t *testing.T) { AuthorID: 0, }, }, - nil) - m.communityRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(&models.Header{ - CommunityID: 1, - AuthorID: 0, - Author: "community", - }, nil) + nil, + ) + m.communityRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return( + &models.Header{ + CommunityID: 1, + AuthorID: 0, + Author: "community", + }, nil, + ) + m.postRepo.EXPECT().GetCommentCount(gomock.Any(), gomock.Any()).Return(uint32(0), nil) + m.postRepo.EXPECT().GetLikesOnPost(gomock.Any(), gomock.Any()).Return(uint32(1), nil) + m.postRepo.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) + }, + }, + { + name: "7", + SetupInput: func() (*userAndPostIDs, error) { + return &userAndPostIDs{postId: 1, userID: 1}, nil + }, + Run: func( + ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs, + ) (*models.Post, error) { + return implementation.Get(ctx, request.postId, request.userID) + }, + ExpectedResult: func() (*models.Post, error) { + return nil, nil + }, + ExpectedErr: errMock, + SetupMock: func(request userAndPostIDs, m *mocks) { + m.postRepo.EXPECT().Get(gomock.Any(), gomock.Any()).Return( + &models.Post{ + Header: models.Header{ + CommunityID: 1, + AuthorID: 0, + }, + }, + nil, + ) + m.communityRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return( + &models.Header{ + CommunityID: 1, + AuthorID: 0, + Author: "community", + }, nil, + ) + m.postRepo.EXPECT().GetCommentCount(gomock.Any(), gomock.Any()).Return(uint32(0), errMock) m.postRepo.EXPECT().GetLikesOnPost(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postRepo.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) }, @@ -273,31 +335,33 @@ func TestGet(t *testing.T) { } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getService(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getService(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -342,31 +406,33 @@ func TestDelete(t *testing.T) { } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getService(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getService(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -409,31 +475,33 @@ func TestUpdate(t *testing.T) { } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getService(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getService(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -449,7 +517,9 @@ func TestGetBatch(t *testing.T) { SetupInput: func() (*userAndLastIDs, error) { return &userAndLastIDs{}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs) ([]*models.Post, error) { + Run: func( + ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, + ) ([]*models.Post, error) { return implementation.GetBatch(ctx, request.LastId, request.UserID) }, ExpectedResult: func() ([]*models.Post, error) { @@ -465,7 +535,9 @@ func TestGetBatch(t *testing.T) { SetupInput: func() (*userAndLastIDs, error) { return &userAndLastIDs{UserID: 1, LastId: 2}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs) ([]*models.Post, error) { + Run: func( + ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, + ) ([]*models.Post, error) { return implementation.GetBatch(ctx, request.LastId, request.UserID) }, ExpectedResult: func() ([]*models.Post, error) { @@ -476,7 +548,8 @@ func TestGetBatch(t *testing.T) { m.postRepo.EXPECT().GetPosts(gomock.Any(), gomock.Any()).Return( []*models.Post{ {ID: 1, Header: models.Header{CommunityID: 1}}, - }, nil) + }, nil, + ) m.communityRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(nil, errMock) }, }, @@ -485,16 +558,19 @@ func TestGetBatch(t *testing.T) { SetupInput: func() (*userAndLastIDs, error) { return &userAndLastIDs{UserID: 1, LastId: 2}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs) ([]*models.Post, error) { + Run: func( + ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, + ) ([]*models.Post, error) { return implementation.GetBatch(ctx, request.LastId, request.UserID) }, ExpectedResult: func() ([]*models.Post, error) { return []*models.Post{ { - ID: 1, - Header: models.Header{AuthorID: 1}, - IsLiked: true, - LikesCount: 1, + ID: 1, + Header: models.Header{AuthorID: 1}, + IsLiked: true, + LikesCount: 1, + CommentCount: 1, }, }, nil }, @@ -503,40 +579,70 @@ func TestGetBatch(t *testing.T) { m.postRepo.EXPECT().GetPosts(gomock.Any(), gomock.Any()).Return( []*models.Post{ {ID: 1, Header: models.Header{AuthorID: 1}}, - }, nil) + }, nil, + ) + m.profileRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(&models.Header{AuthorID: 1}, nil) + m.postRepo.EXPECT().GetLikesOnPost(gomock.Any(), gomock.Any()).Return(uint32(1), nil) + m.postRepo.EXPECT().GetCommentCount(gomock.Any(), gomock.Any()).Return(uint32(1), nil) + m.postRepo.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) + }, + }, + { + name: "4", + SetupInput: func() (*userAndLastIDs, error) { + return &userAndLastIDs{UserID: 1, LastId: 2}, nil + }, + Run: func( + ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, + ) ([]*models.Post, error) { + return implementation.GetBatch(ctx, request.LastId, request.UserID) + }, + ExpectedResult: func() ([]*models.Post, error) { + return nil, nil + }, + ExpectedErr: errMock, + SetupMock: func(request userAndLastIDs, m *mocks) { + m.postRepo.EXPECT().GetPosts(gomock.Any(), gomock.Any()).Return( + []*models.Post{ + {ID: 1, Header: models.Header{AuthorID: 1}}, + }, nil, + ) m.profileRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(&models.Header{AuthorID: 1}, nil) m.postRepo.EXPECT().GetLikesOnPost(gomock.Any(), gomock.Any()).Return(uint32(1), nil) + m.postRepo.EXPECT().GetCommentCount(gomock.Any(), gomock.Any()).Return(uint32(0), errMock) m.postRepo.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getService(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getService(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -547,7 +653,9 @@ func TestGetBatchFromFriend(t *testing.T) { SetupInput: func() (*userAndLastIDs, error) { return &userAndLastIDs{}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs) ([]*models.Post, error) { + Run: func( + ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, + ) ([]*models.Post, error) { return implementation.GetBatchFromFriend(ctx, request.LastId, request.UserID) }, ExpectedResult: func() ([]*models.Post, error) { @@ -563,7 +671,9 @@ func TestGetBatchFromFriend(t *testing.T) { SetupInput: func() (*userAndLastIDs, error) { return &userAndLastIDs{}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs) ([]*models.Post, error) { + Run: func( + ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, + ) ([]*models.Post, error) { return implementation.GetBatchFromFriend(ctx, request.LastId, request.UserID) }, ExpectedResult: func() ([]*models.Post, error) { @@ -579,7 +689,9 @@ func TestGetBatchFromFriend(t *testing.T) { SetupInput: func() (*userAndLastIDs, error) { return &userAndLastIDs{}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs) ([]*models.Post, error) { + Run: func( + ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, + ) ([]*models.Post, error) { return implementation.GetBatchFromFriend(ctx, request.LastId, request.UserID) }, ExpectedResult: func() ([]*models.Post, error) { @@ -596,7 +708,9 @@ func TestGetBatchFromFriend(t *testing.T) { SetupInput: func() (*userAndLastIDs, error) { return &userAndLastIDs{UserID: 1, LastId: 2}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs) ([]*models.Post, error) { + Run: func( + ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, + ) ([]*models.Post, error) { return implementation.GetBatchFromFriend(ctx, request.LastId, request.UserID) }, ExpectedResult: func() ([]*models.Post, error) { @@ -608,7 +722,8 @@ func TestGetBatchFromFriend(t *testing.T) { m.postRepo.EXPECT().GetFriendsPosts(gomock.Any(), gomock.Any(), gomock.Any()).Return( []*models.Post{ {ID: 1, Header: models.Header{CommunityID: 1}}, - }, nil) + }, nil, + ) m.communityRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(nil, errMock) }, }, @@ -617,7 +732,9 @@ func TestGetBatchFromFriend(t *testing.T) { SetupInput: func() (*userAndLastIDs, error) { return &userAndLastIDs{UserID: 1, LastId: 2}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs) ([]*models.Post, error) { + Run: func( + ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, + ) ([]*models.Post, error) { return implementation.GetBatchFromFriend(ctx, request.LastId, request.UserID) }, ExpectedResult: func() ([]*models.Post, error) { @@ -636,8 +753,37 @@ func TestGetBatchFromFriend(t *testing.T) { m.postRepo.EXPECT().GetFriendsPosts(gomock.Any(), gomock.Any(), gomock.Any()).Return( []*models.Post{ {ID: 1, Header: models.Header{AuthorID: 1}}, - }, nil) + }, nil, + ) m.profileRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(&models.Header{AuthorID: 1}, nil) + m.postRepo.EXPECT().GetCommentCount(gomock.Any(), gomock.Any()).Return(uint32(0), nil) + m.postRepo.EXPECT().GetLikesOnPost(gomock.Any(), gomock.Any()).Return(uint32(1), nil) + m.postRepo.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) + }, + }, + { + name: "6", + SetupInput: func() (*userAndLastIDs, error) { + return &userAndLastIDs{UserID: 1, LastId: 2}, nil + }, + Run: func( + ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, + ) ([]*models.Post, error) { + return implementation.GetBatchFromFriend(ctx, request.LastId, request.UserID) + }, + ExpectedResult: func() ([]*models.Post, error) { + return nil, nil + }, + ExpectedErr: errMock, + SetupMock: func(request userAndLastIDs, m *mocks) { + m.profileRepo.EXPECT().GetFriendsID(gomock.Any(), gomock.Any()).Return([]uint32{1, 2, 3}, nil) + m.postRepo.EXPECT().GetFriendsPosts(gomock.Any(), gomock.Any(), gomock.Any()).Return( + []*models.Post{ + {ID: 1, Header: models.Header{AuthorID: 1}}, + }, nil, + ) + m.profileRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(&models.Header{AuthorID: 1}, nil) + m.postRepo.EXPECT().GetCommentCount(gomock.Any(), gomock.Any()).Return(uint32(0), errMock) m.postRepo.EXPECT().GetLikesOnPost(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postRepo.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) }, @@ -645,31 +791,33 @@ func TestGetBatchFromFriend(t *testing.T) { } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getService(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getService(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -712,31 +860,33 @@ func TestGetPostAuthor(t *testing.T) { } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getService(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getService(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -755,7 +905,9 @@ func TestCreateCommunityPost(t *testing.T) { }, ExpectedErr: errMock, SetupMock: func(request models.Post, m *mocks) { - m.postRepo.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(uint32(0), errMock) + m.postRepo.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any(), gomock.Any()).Return( + uint32(0), errMock, + ) }, }, { @@ -777,31 +929,33 @@ func TestCreateCommunityPost(t *testing.T) { } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getService(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getService(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -845,7 +999,8 @@ func TestGetCommunityPost(t *testing.T) { m.postRepo.EXPECT().GetCommunityPosts(gomock.Any(), gomock.Any(), gomock.Any()).Return( []*models.Post{ {ID: 1, Header: models.Header{CommunityID: 1}}, - }, nil) + }, nil, + ) m.communityRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(nil, errMock) }, }, @@ -872,40 +1027,68 @@ func TestGetCommunityPost(t *testing.T) { m.postRepo.EXPECT().GetCommunityPosts(gomock.Any(), gomock.Any(), gomock.Any()).Return( []*models.Post{ {ID: 1, Header: models.Header{AuthorID: 1}}, - }, nil) + }, nil, + ) m.profileRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(&models.Header{AuthorID: 1}, nil) m.postRepo.EXPECT().GetLikesOnPost(gomock.Any(), gomock.Any()).Return(uint32(1), nil) + m.postRepo.EXPECT().GetCommentCount(gomock.Any(), gomock.Any()).Return(uint32(0), nil) + m.postRepo.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) + }, + }, + { + name: "4", + SetupInput: func() (*IDs, error) { + return &IDs{userID: 1, lastID: 2, communityID: 3}, nil + }, + Run: func(ctx context.Context, implementation *PostServiceImpl, request IDs) ([]*models.Post, error) { + return implementation.GetCommunityPost(ctx, request.lastID, request.userID, request.communityID) + }, + ExpectedResult: func() ([]*models.Post, error) { + return nil, nil + }, + ExpectedErr: errMock, + SetupMock: func(request IDs, m *mocks) { + m.postRepo.EXPECT().GetCommunityPosts(gomock.Any(), gomock.Any(), gomock.Any()).Return( + []*models.Post{ + {ID: 1, Header: models.Header{AuthorID: 1}}, + }, nil, + ) + m.profileRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(&models.Header{AuthorID: 1}, nil) + m.postRepo.EXPECT().GetLikesOnPost(gomock.Any(), gomock.Any()).Return(uint32(1), nil) + m.postRepo.EXPECT().GetCommentCount(gomock.Any(), gomock.Any()).Return(uint32(0), errMock) m.postRepo.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getService(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getService(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -953,31 +1136,33 @@ func TestCheckAccessToCommunity(t *testing.T) { } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getService(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getService(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1020,31 +1205,33 @@ func TestSetLikeOnPost(t *testing.T) { } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getService(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getService(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1087,31 +1274,33 @@ func TestDeleteLikeFromPost(t *testing.T) { } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getService(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getService(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1152,31 +1341,33 @@ func TestCheckLikes(t *testing.T) { } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getService(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getService(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } From 4daebcd2df0691371587a848338ac1c33b506e67 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 5 Dec 2024 21:55:47 +0300 Subject: [PATCH 015/135] add test for comment service --- internal/post/controller/controller.go | 2 + internal/post/service/comment.go | 3 +- internal/post/service/comment_mock.go | 154 +++++++ internal/post/service/comment_test.go | 533 +++++++++++++++++++++++++ 4 files changed, 690 insertions(+), 2 deletions(-) create mode 100644 internal/post/service/comment_mock.go create mode 100644 internal/post/service/comment_test.go diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index e74bdee2..07443b35 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -9,6 +9,7 @@ import ( "net/http" "strconv" "strings" + "time" "github.com/gorilla/mux" @@ -508,6 +509,7 @@ func (pc *PostController) Comment(w http.ResponseWriter, r *http.Request) { pc.responder.ErrorInternal(w, err, reqID) return } + newComment.Content.CreatedAt = time.Now() pc.responder.OutputJSON(w, newComment, reqID) } diff --git a/internal/post/service/comment.go b/internal/post/service/comment.go index 46b75361..b2c08cc1 100644 --- a/internal/post/service/comment.go +++ b/internal/post/service/comment.go @@ -3,12 +3,12 @@ package service import ( "context" "fmt" - "time" "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/pkg/my_err" ) +//go:generate mockgen -destination=comment_mock.go -source=$GOFILE -package=${GOPACKAGE} type dbI interface { CreateComment(ctx context.Context, comment *models.Content, userID, postID uint32) (uint32, error) DeleteComment(ctx context.Context, commentID uint32) error @@ -46,7 +46,6 @@ func (s *CommentService) Comment( return nil, fmt.Errorf("get header: %w", err) } - comment.CreatedAt = time.Now() newComment := &models.Comment{ ID: id, Content: *comment, diff --git a/internal/post/service/comment_mock.go b/internal/post/service/comment_mock.go new file mode 100644 index 00000000..3e8ffe17 --- /dev/null +++ b/internal/post/service/comment_mock.go @@ -0,0 +1,154 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: comment.go +// +// Generated by this command: +// +// mockgen -destination=comment_mock.go -source=comment.go -package=service +// + +// Package service is a generated GoMock package. +package service + +import ( + context "context" + reflect "reflect" + + models "github.com/2024_2_BetterCallFirewall/internal/models" + gomock "github.com/golang/mock/gomock" +) + +// MockdbI is a mock of dbI interface. +type MockdbI struct { + ctrl *gomock.Controller + recorder *MockdbIMockRecorder + isgomock struct{} +} + +// MockdbIMockRecorder is the mock recorder for MockdbI. +type MockdbIMockRecorder struct { + mock *MockdbI +} + +// NewMockdbI creates a new mock instance. +func NewMockdbI(ctrl *gomock.Controller) *MockdbI { + mock := &MockdbI{ctrl: ctrl} + mock.recorder = &MockdbIMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockdbI) EXPECT() *MockdbIMockRecorder { + return m.recorder +} + +// CreateComment mocks base method. +func (m *MockdbI) CreateComment(ctx context.Context, comment *models.Content, userID, postID uint32) (uint32, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateComment", ctx, comment, userID, postID) + ret0, _ := ret[0].(uint32) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateComment indicates an expected call of CreateComment. +func (mr *MockdbIMockRecorder) CreateComment(ctx, comment, userID, postID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateComment", reflect.TypeOf((*MockdbI)(nil).CreateComment), ctx, comment, userID, postID) +} + +// DeleteComment mocks base method. +func (m *MockdbI) DeleteComment(ctx context.Context, commentID uint32) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteComment", ctx, commentID) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteComment indicates an expected call of DeleteComment. +func (mr *MockdbIMockRecorder) DeleteComment(ctx, commentID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteComment", reflect.TypeOf((*MockdbI)(nil).DeleteComment), ctx, commentID) +} + +// GetCommentAuthor mocks base method. +func (m *MockdbI) GetCommentAuthor(ctx context.Context, commentID uint32) (uint32, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCommentAuthor", ctx, commentID) + ret0, _ := ret[0].(uint32) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCommentAuthor indicates an expected call of GetCommentAuthor. +func (mr *MockdbIMockRecorder) GetCommentAuthor(ctx, commentID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCommentAuthor", reflect.TypeOf((*MockdbI)(nil).GetCommentAuthor), ctx, commentID) +} + +// GetComments mocks base method. +func (m *MockdbI) GetComments(ctx context.Context, postID, lastID uint32) ([]*models.Comment, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetComments", ctx, postID, lastID) + ret0, _ := ret[0].([]*models.Comment) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetComments indicates an expected call of GetComments. +func (mr *MockdbIMockRecorder) GetComments(ctx, postID, lastID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetComments", reflect.TypeOf((*MockdbI)(nil).GetComments), ctx, postID, lastID) +} + +// UpdateComment mocks base method. +func (m *MockdbI) UpdateComment(ctx context.Context, comment *models.Content, commentID uint32) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateComment", ctx, comment, commentID) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateComment indicates an expected call of UpdateComment. +func (mr *MockdbIMockRecorder) UpdateComment(ctx, comment, commentID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateComment", reflect.TypeOf((*MockdbI)(nil).UpdateComment), ctx, comment, commentID) +} + +// MockprofileRepoI is a mock of profileRepoI interface. +type MockprofileRepoI struct { + ctrl *gomock.Controller + recorder *MockprofileRepoIMockRecorder + isgomock struct{} +} + +// MockprofileRepoIMockRecorder is the mock recorder for MockprofileRepoI. +type MockprofileRepoIMockRecorder struct { + mock *MockprofileRepoI +} + +// NewMockprofileRepoI creates a new mock instance. +func NewMockprofileRepoI(ctrl *gomock.Controller) *MockprofileRepoI { + mock := &MockprofileRepoI{ctrl: ctrl} + mock.recorder = &MockprofileRepoIMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockprofileRepoI) EXPECT() *MockprofileRepoIMockRecorder { + return m.recorder +} + +// GetHeader mocks base method. +func (m *MockprofileRepoI) GetHeader(ctx context.Context, userID uint32) (*models.Header, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetHeader", ctx, userID) + ret0, _ := ret[0].(*models.Header) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetHeader indicates an expected call of GetHeader. +func (mr *MockprofileRepoIMockRecorder) GetHeader(ctx, userID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHeader", reflect.TypeOf((*MockprofileRepoI)(nil).GetHeader), ctx, userID) +} diff --git a/internal/post/service/comment_test.go b/internal/post/service/comment_test.go new file mode 100644 index 00000000..d219d23e --- /dev/null +++ b/internal/post/service/comment_test.go @@ -0,0 +1,533 @@ +package service + +import ( + "context" + "errors" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/2024_2_BetterCallFirewall/internal/models" + "github.com/2024_2_BetterCallFirewall/pkg/my_err" +) + +type commentMocks struct { + repo *MockdbI + profileRepo *MockprofileRepoI +} + +func getCommentService(ctrl *gomock.Controller) (*CommentService, *commentMocks) { + m := &commentMocks{ + repo: NewMockdbI(ctrl), + profileRepo: NewMockprofileRepoI(ctrl), + } + + return NewCommentService(m.repo, m.profileRepo), m +} + +type inputCreate struct { + userID uint32 + postID uint32 + comment *models.Content +} + +func TestNewCommentService(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + service, _ := getCommentService(ctrl) + assert.NotNil(t, service) +} + +func TestCommentService_Comment(t *testing.T) { + tests := []TableTest3[*models.Comment, inputCreate]{ + { + name: "1", + SetupInput: func() (*inputCreate, error) { + return &inputCreate{}, nil + }, + Run: func( + ctx context.Context, implementation *CommentService, request inputCreate, + ) (*models.Comment, error) { + return implementation.Comment(ctx, request.userID, request.postID, request.comment) + }, + ExpectedResult: func() (*models.Comment, error) { + return nil, nil + }, + ExpectedErr: errMock, + SetupMock: func(request inputCreate, m *commentMocks) { + m.repo.EXPECT().CreateComment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(uint32(0), errMock) + }, + }, + { + name: "2", + SetupInput: func() (*inputCreate, error) { + return &inputCreate{}, nil + }, + Run: func( + ctx context.Context, implementation *CommentService, request inputCreate, + ) (*models.Comment, error) { + return implementation.Comment(ctx, request.userID, request.postID, request.comment) + }, + ExpectedResult: func() (*models.Comment, error) { + return nil, nil + }, + ExpectedErr: errMock, + SetupMock: func(request inputCreate, m *commentMocks) { + m.repo.EXPECT().CreateComment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(uint32(1), nil) + m.profileRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()). + Return(nil, errMock) + }, + }, + { + name: "3", + SetupInput: func() (*inputCreate, error) { + return &inputCreate{ + userID: 1, + postID: 1, + comment: &models.Content{ + Text: "new comment", + }, + }, nil + }, + Run: func( + ctx context.Context, implementation *CommentService, request inputCreate, + ) (*models.Comment, error) { + return implementation.Comment(ctx, request.userID, request.postID, request.comment) + }, + ExpectedResult: func() (*models.Comment, error) { + return &models.Comment{ + ID: 1, + Content: models.Content{ + Text: "new comment", + }, + Header: models.Header{ + AuthorID: 1, + Author: "Alexey Zemliakov", + }, + }, nil + }, + ExpectedErr: nil, + SetupMock: func(request inputCreate, m *commentMocks) { + m.repo.EXPECT().CreateComment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(uint32(1), nil) + m.profileRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()). + Return( + &models.Header{ + AuthorID: 1, + Author: "Alexey Zemliakov", + }, nil, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getCommentService(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +type inputDelete struct { + userID uint32 + commentID uint32 +} + +func TestCommentService_Delete(t *testing.T) { + tests := []TableTest3[struct{}, inputDelete]{ + { + name: "1", + SetupInput: func() (*inputDelete, error) { + return &inputDelete{}, nil + }, + Run: func( + ctx context.Context, implementation *CommentService, request inputDelete, + ) (struct{}, error) { + return struct{}{}, implementation.DeleteComment(ctx, request.userID, request.commentID) + }, + ExpectedResult: func() (struct{}, error) { + return struct{}{}, nil + }, + ExpectedErr: errMock, + SetupMock: func(request inputDelete, m *commentMocks) { + m.repo.EXPECT().GetCommentAuthor(gomock.Any(), gomock.Any()).Return(uint32(0), errMock) + }, + }, + { + name: "2", + SetupInput: func() (*inputDelete, error) { + return &inputDelete{ + userID: 1, + }, nil + }, + Run: func( + ctx context.Context, implementation *CommentService, request inputDelete, + ) (struct{}, error) { + return struct{}{}, implementation.DeleteComment(ctx, request.commentID, request.userID) + }, + ExpectedResult: func() (struct{}, error) { + return struct{}{}, nil + }, + ExpectedErr: my_err.ErrAccessDenied, + SetupMock: func(request inputDelete, m *commentMocks) { + m.repo.EXPECT().GetCommentAuthor(gomock.Any(), gomock.Any()).Return(uint32(0), nil) + }, + }, + { + name: "3", + SetupInput: func() (*inputDelete, error) { + return &inputDelete{ + userID: 1, + }, nil + }, + Run: func( + ctx context.Context, implementation *CommentService, request inputDelete, + ) (struct{}, error) { + return struct{}{}, implementation.DeleteComment(ctx, request.commentID, request.userID) + }, + ExpectedResult: func() (struct{}, error) { + return struct{}{}, nil + }, + ExpectedErr: errMock, + SetupMock: func(request inputDelete, m *commentMocks) { + m.repo.EXPECT().GetCommentAuthor(gomock.Any(), gomock.Any()).Return(uint32(1), nil) + m.repo.EXPECT().DeleteComment(gomock.Any(), gomock.Any()).Return(errMock) + }, + }, + { + name: "4", + SetupInput: func() (*inputDelete, error) { + return &inputDelete{ + userID: 1, + }, nil + }, + Run: func( + ctx context.Context, implementation *CommentService, request inputDelete, + ) (struct{}, error) { + return struct{}{}, implementation.DeleteComment(ctx, request.commentID, request.userID) + }, + ExpectedResult: func() (struct{}, error) { + return struct{}{}, nil + }, + ExpectedErr: nil, + SetupMock: func(request inputDelete, m *commentMocks) { + m.repo.EXPECT().GetCommentAuthor(gomock.Any(), gomock.Any()).Return(uint32(1), nil) + m.repo.EXPECT().DeleteComment(gomock.Any(), gomock.Any()).Return(nil) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getCommentService(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +type inputEdit struct { + userID uint32 + commentID uint32 + comment *models.Content +} + +func TestCommentService_Edit(t *testing.T) { + tests := []TableTest3[struct{}, inputEdit]{ + { + name: "1", + SetupInput: func() (*inputEdit, error) { + return &inputEdit{}, nil + }, + Run: func( + ctx context.Context, implementation *CommentService, request inputEdit, + ) (struct{}, error) { + return struct{}{}, implementation.EditComment(ctx, request.commentID, request.userID, request.comment) + }, + ExpectedResult: func() (struct{}, error) { + return struct{}{}, nil + }, + ExpectedErr: errMock, + SetupMock: func(request inputEdit, m *commentMocks) { + m.repo.EXPECT().GetCommentAuthor(gomock.Any(), gomock.Any()).Return(uint32(0), errMock) + }, + }, + { + name: "2", + SetupInput: func() (*inputEdit, error) { + return &inputEdit{ + userID: 10, + }, nil + }, + Run: func( + ctx context.Context, implementation *CommentService, request inputEdit, + ) (struct{}, error) { + return struct{}{}, implementation.EditComment(ctx, request.commentID, request.userID, request.comment) + }, + ExpectedResult: func() (struct{}, error) { + return struct{}{}, nil + }, + ExpectedErr: my_err.ErrAccessDenied, + SetupMock: func(request inputEdit, m *commentMocks) { + m.repo.EXPECT().GetCommentAuthor(gomock.Any(), gomock.Any()).Return(uint32(1), nil) + }, + }, + { + name: "3", + SetupInput: func() (*inputEdit, error) { + return &inputEdit{ + userID: 10, + }, nil + }, + Run: func( + ctx context.Context, implementation *CommentService, request inputEdit, + ) (struct{}, error) { + return struct{}{}, implementation.EditComment(ctx, request.commentID, request.userID, request.comment) + }, + ExpectedResult: func() (struct{}, error) { + return struct{}{}, nil + }, + ExpectedErr: errMock, + SetupMock: func(request inputEdit, m *commentMocks) { + m.repo.EXPECT().GetCommentAuthor(gomock.Any(), gomock.Any()).Return(uint32(10), nil) + m.repo.EXPECT().UpdateComment(gomock.Any(), gomock.Any(), gomock.Any()).Return(errMock) + }, + }, + { + name: "4", + SetupInput: func() (*inputEdit, error) { + return &inputEdit{ + userID: 10, + }, nil + }, + Run: func( + ctx context.Context, implementation *CommentService, request inputEdit, + ) (struct{}, error) { + return struct{}{}, implementation.EditComment(ctx, request.commentID, request.userID, request.comment) + }, + ExpectedResult: func() (struct{}, error) { + return struct{}{}, nil + }, + ExpectedErr: nil, + SetupMock: func(request inputEdit, m *commentMocks) { + m.repo.EXPECT().GetCommentAuthor(gomock.Any(), gomock.Any()).Return(uint32(10), nil) + m.repo.EXPECT().UpdateComment(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getCommentService(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +type inputGet struct { + postID uint32 + lastID uint32 +} + +func TestCommentService_GetComments(t *testing.T) { + tests := []TableTest3[[]*models.Comment, inputGet]{ + { + name: "1", + SetupInput: func() (*inputGet, error) { + return &inputGet{}, nil + }, + Run: func( + ctx context.Context, implementation *CommentService, request inputGet, + ) ([]*models.Comment, error) { + return implementation.GetComments(ctx, request.postID, request.lastID) + }, + ExpectedResult: func() ([]*models.Comment, error) { + return nil, nil + }, + ExpectedErr: errMock, + SetupMock: func(request inputGet, m *commentMocks) { + m.repo.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errMock) + }, + }, + { + name: "2", + SetupInput: func() (*inputGet, error) { + return &inputGet{}, nil + }, + Run: func( + ctx context.Context, implementation *CommentService, request inputGet, + ) ([]*models.Comment, error) { + return implementation.GetComments(ctx, request.postID, request.lastID) + }, + ExpectedResult: func() ([]*models.Comment, error) { + return []*models.Comment{ + { + ID: 1, + Header: models.Header{AuthorID: 1, Author: "Alexey Zemliakov"}, + }, + { + ID: 2, + Header: models.Header{AuthorID: 1, Author: "Alexey Zemliakov"}, + }, + }, nil + }, + ExpectedErr: nil, + SetupMock: func(request inputGet, m *commentMocks) { + m.repo.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any()). + Return( + []*models.Comment{ + {ID: 1}, + {ID: 2}, + }, + nil, + ) + m.profileRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()). + Return( + &models.Header{ + AuthorID: 1, + Author: "Alexey Zemliakov", + }, + nil, + ).AnyTimes() + }, + }, + { + name: "3", + SetupInput: func() (*inputGet, error) { + return &inputGet{}, nil + }, + Run: func( + ctx context.Context, implementation *CommentService, request inputGet, + ) ([]*models.Comment, error) { + return implementation.GetComments(ctx, request.postID, request.lastID) + }, + ExpectedResult: func() ([]*models.Comment, error) { + return nil, nil + }, + ExpectedErr: errMock, + SetupMock: func(request inputGet, m *commentMocks) { + m.repo.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any()). + Return( + []*models.Comment{ + {ID: 1}, + {ID: 2}, + }, + nil, + ) + m.profileRepo.EXPECT().GetHeader(gomock.Any(), gomock.Any()). + Return(nil, errMock).AnyTimes() + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getCommentService(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +type TableTest3[T, In any] struct { + name string + SetupInput func() (*In, error) + Run func(context.Context, *CommentService, In) (T, error) + ExpectedResult func() (T, error) + ExpectedErr error + SetupMock func(In, *commentMocks) +} From 1fea309268bd4bfe50cf0ee539600f333006b9af Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 5 Dec 2024 21:58:29 +0300 Subject: [PATCH 016/135] fix controller test for comment --- internal/post/controller/controller_test.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/internal/post/controller/controller_test.go b/internal/post/controller/controller_test.go index 197d5a31..f91aecbc 100644 --- a/internal/post/controller/controller_test.go +++ b/internal/post/controller/controller_test.go @@ -2142,7 +2142,13 @@ func TestComment(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.commentService.EXPECT().Comment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(nil, nil) + Return( + &models.Comment{ + Content: models.Content{ + Text: "New comment", + }, + }, nil, + ) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( func(w, data, req any) { request.w.WriteHeader(http.StatusOK) From 28c552aa4f830e7be394c70e8401415ff2958b18 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Fri, 6 Dec 2024 21:02:25 +0300 Subject: [PATCH 017/135] feature: sorting comment --- internal/post/controller/controller.go | 9 +++++-- internal/post/controller/controller_test.go | 8 +++--- internal/post/controller/mock.go | 8 +++--- internal/post/repository/postgres/postgres.go | 27 +++++++++++++------ internal/post/service/comment.go | 8 +++--- internal/post/service/comment_mock.go | 8 +++--- internal/post/service/comment_test.go | 13 ++++----- 7 files changed, 50 insertions(+), 31 deletions(-) diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index 07443b35..bf33f1fd 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -46,7 +46,7 @@ type CommentService interface { Comment(ctx context.Context, userID, postID uint32, comment *models.Content) (*models.Comment, error) DeleteComment(ctx context.Context, commentID, userID uint32) error EditComment(ctx context.Context, commentID, userID uint32, comment *models.Content) error - GetComments(ctx context.Context, postID, lastID uint32) ([]*models.Comment, error) + GetComments(ctx context.Context, postID, lastID uint32, newest bool) ([]*models.Comment, error) } type Responder interface { @@ -615,8 +615,13 @@ func (pc *PostController) GetComments(w http.ResponseWriter, r *http.Request) { pc.responder.ErrorBadRequest(w, err, reqID) return } + sorting := r.URL.Query().Get("sort") + newest := true + if sorting == "old" { + newest = false + } - comments, err := pc.commentService.GetComments(r.Context(), postID, uint32(lastId)) + comments, err := pc.commentService.GetComments(r.Context(), postID, uint32(lastId), newest) if err != nil { if errors.Is(err, my_err.ErrNoMoreContent) { pc.responder.OutputNoMoreContentJSON(w, reqID) diff --git a/internal/post/controller/controller_test.go b/internal/post/controller/controller_test.go index f91aecbc..c0e73477 100644 --- a/internal/post/controller/controller_test.go +++ b/internal/post/controller/controller_test.go @@ -2298,7 +2298,7 @@ func TestGetComment(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.commentService.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any()). + m.commentService.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(nil, errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( func(w, err, req any) { @@ -2311,7 +2311,7 @@ func TestGetComment(t *testing.T) { { name: "4", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodGet, "/api/v1/feed/2/comment", nil) + req := httptest.NewRequest(http.MethodGet, "/api/v1/feed/2/comment?sort=old", nil) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "2"}) res := &Request{r: req, w: w} @@ -2328,7 +2328,7 @@ func TestGetComment(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.commentService.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any()). + m.commentService.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(nil, nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( func(w, data, req any) { @@ -2358,7 +2358,7 @@ func TestGetComment(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.commentService.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any()). + m.commentService.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(nil, my_err.ErrNoMoreContent) m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( func(w, req any) { diff --git a/internal/post/controller/mock.go b/internal/post/controller/mock.go index ea53e956..67592057 100644 --- a/internal/post/controller/mock.go +++ b/internal/post/controller/mock.go @@ -300,18 +300,18 @@ func (mr *MockCommentServiceMockRecorder) EditComment(ctx, commentID, userID, co } // GetComments mocks base method. -func (m *MockCommentService) GetComments(ctx context.Context, postID, lastID uint32) ([]*models.Comment, error) { +func (m *MockCommentService) GetComments(ctx context.Context, postID, lastID uint32, newest bool) ([]*models.Comment, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetComments", ctx, postID, lastID) + ret := m.ctrl.Call(m, "GetComments", ctx, postID, lastID, newest) ret0, _ := ret[0].([]*models.Comment) ret1, _ := ret[1].(error) return ret0, ret1 } // GetComments indicates an expected call of GetComments. -func (mr *MockCommentServiceMockRecorder) GetComments(ctx, postID, lastID any) *gomock.Call { +func (mr *MockCommentServiceMockRecorder) GetComments(ctx, postID, lastID, newest any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetComments", reflect.TypeOf((*MockCommentService)(nil).GetComments), ctx, postID, lastID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetComments", reflect.TypeOf((*MockCommentService)(nil).GetComments), ctx, postID, lastID, newest) } // MockResponder is a mock of Responder interface. diff --git a/internal/post/repository/postgres/postgres.go b/internal/post/repository/postgres/postgres.go index c171263d..ce2fcbf2 100644 --- a/internal/post/repository/postgres/postgres.go +++ b/internal/post/repository/postgres/postgres.go @@ -29,12 +29,13 @@ const ( GetLikesOnPost = `SELECT COUNT(*) FROM reaction WHERE post_id = $1;` CheckLike = `SELECT COUNT(*) FROM reaction WHERE post_id = $1 AND user_id=$2;` - createComment = `INSERT INTO comment (user_id, post_id, content, file_path) VALUES ($1, $2, $3, $4) RETURNING id;` - updateComment = `UPDATE comment SET content = $1, file_path = $2, updated_at = NOW() WHERE id = $3;` - deleteComment = `DELETE FROM comment WHERE id = $1;` - getCommentsBatch = `SELECT id, user_id, content, file_path, created_at FROM comment WHERE post_id = $1 and id < $2 ORDER BY created_at DESC LIMIT 20;` - getCommentAuthor = `SELECT user_id FROM comment WHERE id = $1` - getCommentCount = `SELECT COUNT(*) FROM comment WHERE post_id=$1` + createComment = `INSERT INTO comment (user_id, post_id, content, file_path) VALUES ($1, $2, $3, $4) RETURNING id;` + updateComment = `UPDATE comment SET content = $1, file_path = $2, updated_at = NOW() WHERE id = $3;` + deleteComment = `DELETE FROM comment WHERE id = $1;` + getCommentsBatch = `SELECT id, user_id, content, file_path, created_at FROM comment WHERE post_id = $1 and id < $2 ORDER BY created_at DESC LIMIT 10;` + getCommentBatchAsc = `SELECT id, user_id, content, file_path, created_at FROM comment WHERE post_id = $1 and id > $2 order by created_at LIMIT 10;` + getCommentAuthor = `SELECT user_id FROM comment WHERE id = $1` + getCommentCount = `SELECT COUNT(*) FROM comment WHERE post_id=$1` ) type Adapter struct { @@ -374,8 +375,18 @@ func (a *Adapter) UpdateComment(ctx context.Context, comment *models.Content, co return nil } -func (a *Adapter) GetComments(ctx context.Context, postID, lastID uint32) ([]*models.Comment, error) { - rows, err := a.db.QueryContext(ctx, getCommentsBatch, postID, lastID) +func (a *Adapter) GetComments(ctx context.Context, postID, lastID uint32, newest bool) ([]*models.Comment, error) { + var ( + rows *sql.Rows + err error + ) + + if newest { + rows, err = a.db.QueryContext(ctx, getCommentsBatch, postID, lastID) + } else { + rows, err = a.db.QueryContext(ctx, getCommentBatchAsc, postID, lastID) + } + if err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, my_err.ErrNoMoreContent diff --git a/internal/post/service/comment.go b/internal/post/service/comment.go index b2c08cc1..5eabbbb4 100644 --- a/internal/post/service/comment.go +++ b/internal/post/service/comment.go @@ -13,7 +13,7 @@ type dbI interface { CreateComment(ctx context.Context, comment *models.Content, userID, postID uint32) (uint32, error) DeleteComment(ctx context.Context, commentID uint32) error UpdateComment(ctx context.Context, comment *models.Content, commentID uint32) error - GetComments(ctx context.Context, postID, lastID uint32) ([]*models.Comment, error) + GetComments(ctx context.Context, postID, lastID uint32, newest bool) ([]*models.Comment, error) GetCommentAuthor(ctx context.Context, commentID uint32) (uint32, error) } @@ -91,8 +91,10 @@ func (s *CommentService) EditComment(ctx context.Context, commentID, userID uint return nil } -func (s *CommentService) GetComments(ctx context.Context, postID, lastID uint32) ([]*models.Comment, error) { - comments, err := s.db.GetComments(ctx, postID, lastID) +func (s *CommentService) GetComments( + ctx context.Context, postID, lastID uint32, newest bool, +) ([]*models.Comment, error) { + comments, err := s.db.GetComments(ctx, postID, lastID, newest) if err != nil { return nil, fmt.Errorf("get comments: %w", err) } diff --git a/internal/post/service/comment_mock.go b/internal/post/service/comment_mock.go index 3e8ffe17..808b16c5 100644 --- a/internal/post/service/comment_mock.go +++ b/internal/post/service/comment_mock.go @@ -86,18 +86,18 @@ func (mr *MockdbIMockRecorder) GetCommentAuthor(ctx, commentID any) *gomock.Call } // GetComments mocks base method. -func (m *MockdbI) GetComments(ctx context.Context, postID, lastID uint32) ([]*models.Comment, error) { +func (m *MockdbI) GetComments(ctx context.Context, postID, lastID uint32, newest bool) ([]*models.Comment, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetComments", ctx, postID, lastID) + ret := m.ctrl.Call(m, "GetComments", ctx, postID, lastID, newest) ret0, _ := ret[0].([]*models.Comment) ret1, _ := ret[1].(error) return ret0, ret1 } // GetComments indicates an expected call of GetComments. -func (mr *MockdbIMockRecorder) GetComments(ctx, postID, lastID any) *gomock.Call { +func (mr *MockdbIMockRecorder) GetComments(ctx, postID, lastID, newest any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetComments", reflect.TypeOf((*MockdbI)(nil).GetComments), ctx, postID, lastID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetComments", reflect.TypeOf((*MockdbI)(nil).GetComments), ctx, postID, lastID, newest) } // UpdateComment mocks base method. diff --git a/internal/post/service/comment_test.go b/internal/post/service/comment_test.go index d219d23e..990eeb48 100644 --- a/internal/post/service/comment_test.go +++ b/internal/post/service/comment_test.go @@ -399,6 +399,7 @@ func TestCommentService_Edit(t *testing.T) { type inputGet struct { postID uint32 lastID uint32 + newest bool } func TestCommentService_GetComments(t *testing.T) { @@ -411,14 +412,14 @@ func TestCommentService_GetComments(t *testing.T) { Run: func( ctx context.Context, implementation *CommentService, request inputGet, ) ([]*models.Comment, error) { - return implementation.GetComments(ctx, request.postID, request.lastID) + return implementation.GetComments(ctx, request.postID, request.lastID, request.newest) }, ExpectedResult: func() ([]*models.Comment, error) { return nil, nil }, ExpectedErr: errMock, SetupMock: func(request inputGet, m *commentMocks) { - m.repo.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errMock) + m.repo.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errMock) }, }, { @@ -429,7 +430,7 @@ func TestCommentService_GetComments(t *testing.T) { Run: func( ctx context.Context, implementation *CommentService, request inputGet, ) ([]*models.Comment, error) { - return implementation.GetComments(ctx, request.postID, request.lastID) + return implementation.GetComments(ctx, request.postID, request.lastID, request.newest) }, ExpectedResult: func() ([]*models.Comment, error) { return []*models.Comment{ @@ -445,7 +446,7 @@ func TestCommentService_GetComments(t *testing.T) { }, ExpectedErr: nil, SetupMock: func(request inputGet, m *commentMocks) { - m.repo.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any()). + m.repo.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return( []*models.Comment{ {ID: 1}, @@ -471,14 +472,14 @@ func TestCommentService_GetComments(t *testing.T) { Run: func( ctx context.Context, implementation *CommentService, request inputGet, ) ([]*models.Comment, error) { - return implementation.GetComments(ctx, request.postID, request.lastID) + return implementation.GetComments(ctx, request.postID, request.lastID, request.newest) }, ExpectedResult: func() ([]*models.Comment, error) { return nil, nil }, ExpectedErr: errMock, SetupMock: func(request inputGet, m *commentMocks) { - m.repo.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any()). + m.repo.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return( []*models.Comment{ {ID: 1}, From 4ed34bd1a81346f9126932dbab2a2a9875348f9d Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Fri, 6 Dec 2024 21:05:28 +0300 Subject: [PATCH 018/135] feature: add comments count for profile posts --- internal/api/grpc/post_api/grpc_server.go | 35 +++++++------- internal/api/grpc/post_api/post.pb.go | 58 +++++++++++++---------- internal/ext_grpc/port/post/post.go | 35 +++++++------- proto/post.proto | 1 + 4 files changed, 73 insertions(+), 56 deletions(-) diff --git a/internal/api/grpc/post_api/grpc_server.go b/internal/api/grpc/post_api/grpc_server.go index b98cc54c..bc2af8e6 100644 --- a/internal/api/grpc/post_api/grpc_server.go +++ b/internal/api/grpc/post_api/grpc_server.go @@ -41,23 +41,26 @@ func (a *Adapter) GetAuthorsPosts(ctx context.Context, req *Request) (*Response, Posts: make([]*Post, 0, len(res)), } for _, post := range res { - resp.Posts = append(resp.Posts, &Post{ - ID: post.ID, - Head: &Header{ - AuthorID: post.Header.AuthorID, - CommunityID: post.Header.CommunityID, - Author: post.Header.Author, - Avatar: string(post.Header.Avatar), + resp.Posts = append( + resp.Posts, &Post{ + ID: post.ID, + Head: &Header{ + AuthorID: post.Header.AuthorID, + CommunityID: post.Header.CommunityID, + Author: post.Header.Author, + Avatar: string(post.Header.Avatar), + }, + PostContent: &Content{ + Text: post.PostContent.Text, + File: string(post.PostContent.File), + CreatedAt: post.PostContent.CreatedAt.Unix(), + UpdatedAt: post.PostContent.UpdatedAt.Unix(), + }, + LikesCount: post.LikesCount, + IsLiked: post.IsLiked, + CommentCount: post.CommentCount, }, - PostContent: &Content{ - Text: post.PostContent.Text, - File: string(post.PostContent.File), - CreatedAt: post.PostContent.CreatedAt.Unix(), - UpdatedAt: post.PostContent.UpdatedAt.Unix(), - }, - LikesCount: post.LikesCount, - IsLiked: post.IsLiked, - }) + ) } return resp, nil diff --git a/internal/api/grpc/post_api/post.pb.go b/internal/api/grpc/post_api/post.pb.go index b8f5db25..7d222125 100644 --- a/internal/api/grpc/post_api/post.pb.go +++ b/internal/api/grpc/post_api/post.pb.go @@ -198,11 +198,12 @@ type Post struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ID uint32 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` - PostContent *Content `protobuf:"bytes,2,opt,name=PostContent,proto3" json:"PostContent,omitempty"` - Head *Header `protobuf:"bytes,3,opt,name=Head,proto3" json:"Head,omitempty"` - LikesCount uint32 `protobuf:"varint,4,opt,name=LikesCount,proto3" json:"LikesCount,omitempty"` - IsLiked bool `protobuf:"varint,5,opt,name=IsLiked,proto3" json:"IsLiked,omitempty"` + ID uint32 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` + PostContent *Content `protobuf:"bytes,2,opt,name=PostContent,proto3" json:"PostContent,omitempty"` + Head *Header `protobuf:"bytes,3,opt,name=Head,proto3" json:"Head,omitempty"` + LikesCount uint32 `protobuf:"varint,4,opt,name=LikesCount,proto3" json:"LikesCount,omitempty"` + IsLiked bool `protobuf:"varint,5,opt,name=IsLiked,proto3" json:"IsLiked,omitempty"` + CommentCount uint32 `protobuf:"varint,6,opt,name=CommentCount,proto3" json:"CommentCount,omitempty"` } func (x *Post) Reset() { @@ -272,6 +273,13 @@ func (x *Post) GetIsLiked() bool { return false } +func (x *Post) GetCommentCount() uint32 { + if x != nil { + return x.CommentCount + } + return 0 +} + type Content struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -363,7 +371,7 @@ var file_proto_post_proto_rawDesc = []byte{ 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x05, 0x50, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x05, 0x50, 0x6f, 0x73, 0x74, 0x73, 0x22, - 0xab, 0x01, 0x0a, 0x04, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, + 0xcf, 0x01, 0x0a, 0x04, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x49, 0x44, 0x12, 0x33, 0x0a, 0x0b, 0x50, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, @@ -373,24 +381,26 @@ var file_proto_post_proto_rawDesc = []byte{ 0x65, 0x61, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x4c, 0x69, 0x6b, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x4c, 0x69, 0x6b, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x49, 0x73, 0x4c, 0x69, 0x6b, 0x65, 0x64, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x49, 0x73, 0x4c, 0x69, 0x6b, 0x65, 0x64, 0x22, 0x6d, 0x0a, - 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x65, 0x78, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x65, 0x78, 0x74, 0x12, 0x12, 0x0a, 0x04, - 0x46, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x46, 0x69, 0x6c, 0x65, - 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, - 0x0a, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x32, 0x49, 0x0a, 0x0b, - 0x50, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3a, 0x0a, 0x0f, 0x47, - 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x73, 0x50, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x11, - 0x2e, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x41, 0x5a, 0x3f, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x32, 0x30, 0x32, 0x34, 0x5f, 0x32, 0x5f, 0x42, 0x65, 0x74, - 0x74, 0x65, 0x72, 0x43, 0x61, 0x6c, 0x6c, 0x46, 0x69, 0x72, 0x65, 0x77, 0x61, 0x6c, 0x6c, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x72, 0x70, - 0x63, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x49, 0x73, 0x4c, 0x69, 0x6b, 0x65, 0x64, 0x12, 0x22, 0x0a, + 0x0c, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x22, 0x6d, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x54, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x65, 0x78, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x32, 0x49, 0x0a, 0x0b, 0x50, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0x3a, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x73, 0x50, 0x6f, 0x73, + 0x74, 0x73, 0x12, 0x11, 0x2e, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x69, + 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x41, 0x5a, 0x3f, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x32, 0x30, 0x32, 0x34, 0x5f, 0x32, + 0x5f, 0x42, 0x65, 0x74, 0x74, 0x65, 0x72, 0x43, 0x61, 0x6c, 0x6c, 0x46, 0x69, 0x72, 0x65, 0x77, + 0x61, 0x6c, 0x6c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x61, 0x70, 0x69, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/internal/ext_grpc/port/post/post.go b/internal/ext_grpc/port/post/post.go index 72100e66..9a373296 100644 --- a/internal/ext_grpc/port/post/post.go +++ b/internal/ext_grpc/port/post/post.go @@ -22,23 +22,26 @@ func NewRequest(header *models.Header, userID uint32) *post_api.Request { func UnmarshalResponse(response *post_api.Response) []*models.Post { res := make([]*models.Post, 0, len(response.Posts)) for _, post := range response.Posts { - res = append(res, &models.Post{ - ID: post.ID, - Header: models.Header{ - AuthorID: post.Head.AuthorID, - CommunityID: post.Head.CommunityID, - Avatar: models.Picture(post.Head.Avatar), - Author: post.Head.Author, + res = append( + res, &models.Post{ + ID: post.ID, + Header: models.Header{ + AuthorID: post.Head.AuthorID, + CommunityID: post.Head.CommunityID, + Avatar: models.Picture(post.Head.Avatar), + Author: post.Head.Author, + }, + PostContent: models.Content{ + Text: post.PostContent.Text, + File: models.Picture(post.PostContent.File), + CreatedAt: time.Unix(post.PostContent.CreatedAt, 0), + UpdatedAt: time.Unix(post.PostContent.UpdatedAt, 0), + }, + IsLiked: post.IsLiked, + LikesCount: post.LikesCount, + CommentCount: post.CommentCount, }, - PostContent: models.Content{ - Text: post.PostContent.Text, - File: models.Picture(post.PostContent.File), - CreatedAt: time.Unix(post.PostContent.CreatedAt, 0), - UpdatedAt: time.Unix(post.PostContent.UpdatedAt, 0), - }, - IsLiked: post.IsLiked, - LikesCount: post.LikesCount, - }) + ) } return res diff --git a/proto/post.proto b/proto/post.proto index 01ebd048..ab67c3a7 100644 --- a/proto/post.proto +++ b/proto/post.proto @@ -30,6 +30,7 @@ message Post { Header Head = 3; uint32 LikesCount = 4; bool IsLiked = 5; + uint32 CommentCount = 6; } message Content { From f8c7437c7feea780188ec714da9c8c9f4eb45c40 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Fri, 6 Dec 2024 21:15:57 +0300 Subject: [PATCH 019/135] add test for change password --- internal/profile/controller/controller.go | 1 + .../profile/controller/controller_test.go | 1991 +++++++++++------ internal/profile/controller/mock.go | 215 +- 3 files changed, 1380 insertions(+), 827 deletions(-) diff --git a/internal/profile/controller/controller.go b/internal/profile/controller/controller.go index 15bc3bd9..f3475488 100644 --- a/internal/profile/controller/controller.go +++ b/internal/profile/controller/controller.go @@ -552,6 +552,7 @@ func (h *ProfileHandlerImplementation) ChangePassword(w http.ResponseWriter, r * errors.Is(err, my_err.ErrWrongEmailOrPassword) || errors.Is(err, bcrypt.ErrPasswordTooLong) { h.Responder.ErrorBadRequest(w, err, reqID) + return } h.Responder.ErrorInternal(w, err, reqID) diff --git a/internal/profile/controller/controller_test.go b/internal/profile/controller/controller_test.go index 13d0cdc6..c6cbdd03 100644 --- a/internal/profile/controller/controller_test.go +++ b/internal/profile/controller/controller_test.go @@ -47,7 +47,9 @@ func TestGetHeader(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetHeader(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -58,10 +60,12 @@ func TestGetHeader(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -73,7 +77,9 @@ func TestGetHeader(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetHeader(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -85,10 +91,12 @@ func TestGetHeader(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(nil, my_err.ErrProfileNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -100,7 +108,9 @@ func TestGetHeader(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetHeader(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -112,10 +122,12 @@ func TestGetHeader(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("internal error")) - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("internal error")) + }, + ) }, }, { @@ -127,7 +139,9 @@ func TestGetHeader(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetHeader(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -139,40 +153,44 @@ func TestGetHeader(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(&models.Header{}, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, header, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, header, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -186,7 +204,9 @@ func TestGetProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -197,10 +217,12 @@ func TestGetProfile(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -212,7 +234,9 @@ func TestGetProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -223,11 +247,15 @@ func TestGetProfile(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, my_err.ErrProfileNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return( + &models.FullProfile{}, my_err.ErrProfileNotFound, + ) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -239,7 +267,9 @@ func TestGetProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -250,10 +280,14 @@ func TestGetProfile(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, my_err.ErrNoMoreContent) - m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do(func(w, req any) { - request.w.WriteHeader(http.StatusNoContent) - }) + m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return( + &models.FullProfile{}, my_err.ErrNoMoreContent, + ) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) }, }, { @@ -265,7 +299,9 @@ func TestGetProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -276,11 +312,15 @@ func TestGetProfile(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return( + &models.FullProfile{}, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -292,7 +332,9 @@ func TestGetProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -304,40 +346,44 @@ func TestGetProfile(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -351,7 +397,9 @@ func TestUpdateProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.UpdateProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -362,10 +410,12 @@ func TestUpdateProfile(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -377,7 +427,9 @@ func TestUpdateProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.UpdateProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -388,23 +440,29 @@ func TestUpdateProfile(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { name: "3", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/profile", - bytes.NewBuffer([]byte(`{"id":0, "first_name":"Alexey"}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/profile", + bytes.NewBuffer([]byte(`{"id":0, "first_name":"Alexey"}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.UpdateProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -416,23 +474,29 @@ func TestUpdateProfile(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().UpdateProfile(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { name: "4", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/profile", - bytes.NewBuffer([]byte(`{"id":1, "first_name":"Alexey"}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/profile", + bytes.NewBuffer([]byte(`{"id":1, "first_name":"Alexey"}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.UpdateProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -444,40 +508,44 @@ func TestUpdateProfile(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().UpdateProfile(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -491,7 +559,9 @@ func TestDeleteProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.DeleteProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -502,10 +572,12 @@ func TestDeleteProfile(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -517,7 +589,9 @@ func TestDeleteProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.DeleteProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -529,10 +603,12 @@ func TestDeleteProfile(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().DeleteProfile(gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -544,7 +620,9 @@ func TestDeleteProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.DeleteProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -556,40 +634,44 @@ func TestDeleteProfile(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().DeleteProfile(gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -603,7 +685,9 @@ func TestGetProfileByID(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfileById(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -614,10 +698,12 @@ func TestGetProfileByID(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -629,7 +715,9 @@ func TestGetProfileByID(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfileById(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -640,10 +728,12 @@ func TestGetProfileByID(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -655,7 +745,9 @@ func TestGetProfileByID(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfileById(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -666,10 +758,12 @@ func TestGetProfileByID(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -681,7 +775,9 @@ func TestGetProfileByID(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfileById(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -692,11 +788,15 @@ func TestGetProfileByID(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, my_err.ErrProfileNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return( + &models.FullProfile{}, my_err.ErrProfileNotFound, + ) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -708,7 +808,9 @@ func TestGetProfileByID(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfileById(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -719,11 +821,15 @@ func TestGetProfileByID(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return( + &models.FullProfile{}, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -735,7 +841,9 @@ func TestGetProfileByID(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfileById(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -747,40 +855,44 @@ func TestGetProfileByID(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -794,7 +906,9 @@ func TestGetAll(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAll(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -805,10 +919,12 @@ func TestGetAll(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -820,7 +936,9 @@ func TestGetAll(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAll(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -831,10 +949,12 @@ func TestGetAll(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -846,7 +966,9 @@ func TestGetAll(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAll(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -857,11 +979,15 @@ func TestGetAll(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetAll(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.profileManager.EXPECT().GetAll(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -873,7 +999,9 @@ func TestGetAll(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAll(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -885,9 +1013,11 @@ func TestGetAll(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetAll(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do(func(w, req any) { - request.w.WriteHeader(http.StatusNoContent) - }) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) }, }, { @@ -899,7 +1029,9 @@ func TestGetAll(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAll(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -912,41 +1044,46 @@ func TestGetAll(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetAll(gomock.Any(), gomock.Any(), gomock.Any()).Return( []*models.ShortProfile{{ID: 1}}, - nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + nil, + ) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -960,7 +1097,9 @@ func TestSendFriendReq(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SendFriendReq(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -971,10 +1110,12 @@ func TestSendFriendReq(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -986,7 +1127,9 @@ func TestSendFriendReq(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SendFriendReq(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -997,10 +1140,12 @@ func TestSendFriendReq(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1013,7 +1158,9 @@ func TestSendFriendReq(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SendFriendReq(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1025,10 +1172,12 @@ func TestSendFriendReq(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().SendFriendReq(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1041,7 +1190,9 @@ func TestSendFriendReq(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SendFriendReq(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1053,40 +1204,44 @@ func TestSendFriendReq(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().SendFriendReq(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1100,7 +1255,9 @@ func TestAcceptFriendReq(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.AcceptFriendReq(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1111,10 +1268,12 @@ func TestAcceptFriendReq(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1126,7 +1285,9 @@ func TestAcceptFriendReq(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.AcceptFriendReq(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1137,10 +1298,12 @@ func TestAcceptFriendReq(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1153,7 +1316,9 @@ func TestAcceptFriendReq(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.AcceptFriendReq(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1165,10 +1330,12 @@ func TestAcceptFriendReq(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().AcceptFriendReq(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -1181,7 +1348,9 @@ func TestAcceptFriendReq(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.AcceptFriendReq(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1193,40 +1362,44 @@ func TestAcceptFriendReq(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().AcceptFriendReq(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1240,7 +1413,9 @@ func TestRemoveFromFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.RemoveFromFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1251,10 +1426,12 @@ func TestRemoveFromFriends(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1266,7 +1443,9 @@ func TestRemoveFromFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.RemoveFromFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1277,10 +1456,12 @@ func TestRemoveFromFriends(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1293,7 +1474,9 @@ func TestRemoveFromFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.RemoveFromFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1305,10 +1488,12 @@ func TestRemoveFromFriends(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().RemoveFromFriends(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -1321,7 +1506,9 @@ func TestRemoveFromFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.RemoveFromFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1333,40 +1520,44 @@ func TestRemoveFromFriends(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().RemoveFromFriends(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1380,7 +1571,9 @@ func TestUnsubscribe(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.Unsubscribe(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1391,10 +1584,12 @@ func TestUnsubscribe(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1406,7 +1601,9 @@ func TestUnsubscribe(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.Unsubscribe(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1417,10 +1614,12 @@ func TestUnsubscribe(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1433,7 +1632,9 @@ func TestUnsubscribe(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.Unsubscribe(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1445,10 +1646,12 @@ func TestUnsubscribe(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().Unsubscribe(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -1461,7 +1664,9 @@ func TestUnsubscribe(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.Unsubscribe(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1473,40 +1678,44 @@ func TestUnsubscribe(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().Unsubscribe(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1520,7 +1729,9 @@ func TestGetAllFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1531,10 +1742,12 @@ func TestGetAllFriends(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1546,7 +1759,9 @@ func TestGetAllFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1557,10 +1772,12 @@ func TestGetAllFriends(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1572,7 +1789,9 @@ func TestGetAllFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1583,11 +1802,15 @@ func TestGetAllFriends(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetAllFriends(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.profileManager.EXPECT().GetAllFriends(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -1599,7 +1822,9 @@ func TestGetAllFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1611,9 +1836,11 @@ func TestGetAllFriends(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetAllFriends(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do(func(w, req any) { - request.w.WriteHeader(http.StatusNoContent) - }) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) }, }, { @@ -1625,7 +1852,9 @@ func TestGetAllFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1638,41 +1867,46 @@ func TestGetAllFriends(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetAllFriends(gomock.Any(), gomock.Any(), gomock.Any()).Return( []*models.ShortProfile{{ID: 1}}, - nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + nil, + ) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1686,7 +1920,9 @@ func TestGetAllSubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1697,10 +1933,12 @@ func TestGetAllSubs(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1712,7 +1950,9 @@ func TestGetAllSubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1723,10 +1963,12 @@ func TestGetAllSubs(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1738,7 +1980,9 @@ func TestGetAllSubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1749,11 +1993,15 @@ func TestGetAllSubs(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetAllSubs(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.profileManager.EXPECT().GetAllSubs(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -1765,7 +2013,9 @@ func TestGetAllSubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1777,9 +2027,11 @@ func TestGetAllSubs(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetAllSubs(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do(func(w, req any) { - request.w.WriteHeader(http.StatusNoContent) - }) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) }, }, { @@ -1791,7 +2043,9 @@ func TestGetAllSubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1804,41 +2058,46 @@ func TestGetAllSubs(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetAllSubs(gomock.Any(), gomock.Any(), gomock.Any()).Return( []*models.ShortProfile{{ID: 1}}, - nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + nil, + ) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1852,7 +2111,9 @@ func TestGetAllSubscriptions(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubscriptions(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1863,10 +2124,12 @@ func TestGetAllSubscriptions(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1878,7 +2141,9 @@ func TestGetAllSubscriptions(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubscriptions(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1889,10 +2154,12 @@ func TestGetAllSubscriptions(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -1904,7 +2171,9 @@ func TestGetAllSubscriptions(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubscriptions(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1915,11 +2184,15 @@ func TestGetAllSubscriptions(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetAllSubscriptions(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.profileManager.EXPECT().GetAllSubscriptions(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -1931,7 +2204,9 @@ func TestGetAllSubscriptions(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubscriptions(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1943,9 +2218,11 @@ func TestGetAllSubscriptions(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetAllSubscriptions(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do(func(w, req any) { - request.w.WriteHeader(http.StatusNoContent) - }) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) }, }, { @@ -1957,7 +2234,9 @@ func TestGetAllSubscriptions(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubscriptions(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1970,41 +2249,46 @@ func TestGetAllSubscriptions(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetAllSubscriptions(gomock.Any(), gomock.Any(), gomock.Any()).Return( []*models.ShortProfile{{ID: 1}}, - nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + nil, + ) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -2018,7 +2302,9 @@ func TestGetCommunitySubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetCommunitySubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2029,10 +2315,12 @@ func TestGetCommunitySubs(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -2044,7 +2332,9 @@ func TestGetCommunitySubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetCommunitySubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2055,10 +2345,12 @@ func TestGetCommunitySubs(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -2070,7 +2362,9 @@ func TestGetCommunitySubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetCommunitySubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2081,11 +2375,15 @@ func TestGetCommunitySubs(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetCommunitySubs(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.profileManager.EXPECT().GetCommunitySubs(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -2097,7 +2395,9 @@ func TestGetCommunitySubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetCommunitySubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2109,9 +2409,11 @@ func TestGetCommunitySubs(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetCommunitySubs(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do(func(w, req any) { - request.w.WriteHeader(http.StatusNoContent) - }) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) }, }, { @@ -2123,7 +2425,9 @@ func TestGetCommunitySubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetCommunitySubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2136,41 +2440,46 @@ func TestGetCommunitySubs(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetCommunitySubs(gomock.Any(), gomock.Any(), gomock.Any()).Return( []*models.ShortProfile{{ID: 1}}, - nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + nil, + ) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -2184,7 +2493,9 @@ func TestSearch(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SearchProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2195,10 +2506,12 @@ func TestSearch(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -2209,7 +2522,9 @@ func TestSearch(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SearchProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2220,11 +2535,15 @@ func TestSearch(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) - }) + m.profileManager.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) }, }, { @@ -2235,7 +2554,9 @@ func TestSearch(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SearchProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2246,10 +2567,12 @@ func TestSearch(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) }, }, { @@ -2260,7 +2583,9 @@ func TestSearch(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SearchProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2272,10 +2597,12 @@ func TestSearch(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, { @@ -2286,7 +2613,9 @@ func TestSearch(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SearchProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2297,41 +2626,243 @@ func TestSearch(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, my_err.ErrSessionNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) - }) + m.profileManager.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, my_err.ErrSessionNotFound, + ) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestChangePassword(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/profile/password", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { + implementation.ChangePassword(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/profile/password", nil) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { + implementation.ChangePassword(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodPut, "/api/v1/profile/password", bytes.NewBuffer([]byte(`{"old_password":"password"}`)), + ) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { + implementation.ChangePassword(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.profileManager.EXPECT().ChangePassword(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(my_err.ErrWrongEmailOrPassword) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "4", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodPut, "/api/v1/profile/password", bytes.NewBuffer([]byte(`{"old_password":"password"}`)), + ) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { + implementation.ChangePassword(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusInternalServerError, Body: "error"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.profileManager.EXPECT().ChangePassword(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + request.w.Write([]byte("error")) + }, + ) + }, + }, + { + name: "5", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodPut, "/api/v1/profile/password", bytes.NewBuffer([]byte(`{"old_password":"password"}`)), + ) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { + implementation.ChangePassword(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.profileManager.EXPECT().ChangePassword(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + request.w.Write([]byte("OK")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } diff --git a/internal/profile/controller/mock.go b/internal/profile/controller/mock.go index a005d3a4..20f96de8 100644 --- a/internal/profile/controller/mock.go +++ b/internal/profile/controller/mock.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: controller.go +// +// Generated by this command: +// +// mockgen -destination=mock.go -source=controller.go -package=controller +// // Package controller is a generated GoMock package. package controller @@ -13,10 +18,95 @@ import ( gomock "github.com/golang/mock/gomock" ) +// MockResponder is a mock of Responder interface. +type MockResponder struct { + ctrl *gomock.Controller + recorder *MockResponderMockRecorder + isgomock struct{} +} + +// MockResponderMockRecorder is the mock recorder for MockResponder. +type MockResponderMockRecorder struct { + mock *MockResponder +} + +// NewMockResponder creates a new mock instance. +func NewMockResponder(ctrl *gomock.Controller) *MockResponder { + mock := &MockResponder{ctrl: ctrl} + mock.recorder = &MockResponderMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockResponder) EXPECT() *MockResponderMockRecorder { + return m.recorder +} + +// ErrorBadRequest mocks base method. +func (m *MockResponder) ErrorBadRequest(w http.ResponseWriter, err error, requestID string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ErrorBadRequest", w, err, requestID) +} + +// ErrorBadRequest indicates an expected call of ErrorBadRequest. +func (mr *MockResponderMockRecorder) ErrorBadRequest(w, err, requestID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ErrorBadRequest", reflect.TypeOf((*MockResponder)(nil).ErrorBadRequest), w, err, requestID) +} + +// ErrorInternal mocks base method. +func (m *MockResponder) ErrorInternal(w http.ResponseWriter, err error, requestID string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ErrorInternal", w, err, requestID) +} + +// ErrorInternal indicates an expected call of ErrorInternal. +func (mr *MockResponderMockRecorder) ErrorInternal(w, err, requestID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ErrorInternal", reflect.TypeOf((*MockResponder)(nil).ErrorInternal), w, err, requestID) +} + +// LogError mocks base method. +func (m *MockResponder) LogError(err error, requestID string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "LogError", err, requestID) +} + +// LogError indicates an expected call of LogError. +func (mr *MockResponderMockRecorder) LogError(err, requestID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogError", reflect.TypeOf((*MockResponder)(nil).LogError), err, requestID) +} + +// OutputJSON mocks base method. +func (m *MockResponder) OutputJSON(w http.ResponseWriter, data any, requestID string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "OutputJSON", w, data, requestID) +} + +// OutputJSON indicates an expected call of OutputJSON. +func (mr *MockResponderMockRecorder) OutputJSON(w, data, requestID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OutputJSON", reflect.TypeOf((*MockResponder)(nil).OutputJSON), w, data, requestID) +} + +// OutputNoMoreContentJSON mocks base method. +func (m *MockResponder) OutputNoMoreContentJSON(w http.ResponseWriter, requestID string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "OutputNoMoreContentJSON", w, requestID) +} + +// OutputNoMoreContentJSON indicates an expected call of OutputNoMoreContentJSON. +func (mr *MockResponderMockRecorder) OutputNoMoreContentJSON(w, requestID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OutputNoMoreContentJSON", reflect.TypeOf((*MockResponder)(nil).OutputNoMoreContentJSON), w, requestID) +} + // MockProfileUsecase is a mock of ProfileUsecase interface. type MockProfileUsecase struct { ctrl *gomock.Controller recorder *MockProfileUsecaseMockRecorder + isgomock struct{} } // MockProfileUsecaseMockRecorder is the mock recorder for MockProfileUsecase. @@ -45,11 +135,25 @@ func (m *MockProfileUsecase) AcceptFriendReq(who, whose uint32) error { } // AcceptFriendReq indicates an expected call of AcceptFriendReq. -func (mr *MockProfileUsecaseMockRecorder) AcceptFriendReq(who, whose interface{}) *gomock.Call { +func (mr *MockProfileUsecaseMockRecorder) AcceptFriendReq(who, whose any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptFriendReq", reflect.TypeOf((*MockProfileUsecase)(nil).AcceptFriendReq), who, whose) } +// ChangePassword mocks base method. +func (m *MockProfileUsecase) ChangePassword(ctx context.Context, userID uint32, oldPassword, newPassword string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChangePassword", ctx, userID, oldPassword, newPassword) + ret0, _ := ret[0].(error) + return ret0 +} + +// ChangePassword indicates an expected call of ChangePassword. +func (mr *MockProfileUsecaseMockRecorder) ChangePassword(ctx, userID, oldPassword, newPassword any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChangePassword", reflect.TypeOf((*MockProfileUsecase)(nil).ChangePassword), ctx, userID, oldPassword, newPassword) +} + // DeleteProfile mocks base method. func (m *MockProfileUsecase) DeleteProfile(arg0 uint32) error { m.ctrl.T.Helper() @@ -59,7 +163,7 @@ func (m *MockProfileUsecase) DeleteProfile(arg0 uint32) error { } // DeleteProfile indicates an expected call of DeleteProfile. -func (mr *MockProfileUsecaseMockRecorder) DeleteProfile(arg0 interface{}) *gomock.Call { +func (mr *MockProfileUsecaseMockRecorder) DeleteProfile(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteProfile", reflect.TypeOf((*MockProfileUsecase)(nil).DeleteProfile), arg0) } @@ -74,7 +178,7 @@ func (m *MockProfileUsecase) GetAll(ctx context.Context, self, lastId uint32) ([ } // GetAll indicates an expected call of GetAll. -func (mr *MockProfileUsecaseMockRecorder) GetAll(ctx, self, lastId interface{}) *gomock.Call { +func (mr *MockProfileUsecaseMockRecorder) GetAll(ctx, self, lastId any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAll", reflect.TypeOf((*MockProfileUsecase)(nil).GetAll), ctx, self, lastId) } @@ -89,7 +193,7 @@ func (m *MockProfileUsecase) GetAllFriends(ctx context.Context, id, lastId uint3 } // GetAllFriends indicates an expected call of GetAllFriends. -func (mr *MockProfileUsecaseMockRecorder) GetAllFriends(ctx, id, lastId interface{}) *gomock.Call { +func (mr *MockProfileUsecaseMockRecorder) GetAllFriends(ctx, id, lastId any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllFriends", reflect.TypeOf((*MockProfileUsecase)(nil).GetAllFriends), ctx, id, lastId) } @@ -104,7 +208,7 @@ func (m *MockProfileUsecase) GetAllSubs(ctx context.Context, id, lastId uint32) } // GetAllSubs indicates an expected call of GetAllSubs. -func (mr *MockProfileUsecaseMockRecorder) GetAllSubs(ctx, id, lastId interface{}) *gomock.Call { +func (mr *MockProfileUsecaseMockRecorder) GetAllSubs(ctx, id, lastId any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllSubs", reflect.TypeOf((*MockProfileUsecase)(nil).GetAllSubs), ctx, id, lastId) } @@ -119,7 +223,7 @@ func (m *MockProfileUsecase) GetAllSubscriptions(ctx context.Context, id, lastId } // GetAllSubscriptions indicates an expected call of GetAllSubscriptions. -func (mr *MockProfileUsecaseMockRecorder) GetAllSubscriptions(ctx, id, lastId interface{}) *gomock.Call { +func (mr *MockProfileUsecaseMockRecorder) GetAllSubscriptions(ctx, id, lastId any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllSubscriptions", reflect.TypeOf((*MockProfileUsecase)(nil).GetAllSubscriptions), ctx, id, lastId) } @@ -134,7 +238,7 @@ func (m *MockProfileUsecase) GetCommunitySubs(ctx context.Context, communityID, } // GetCommunitySubs indicates an expected call of GetCommunitySubs. -func (mr *MockProfileUsecaseMockRecorder) GetCommunitySubs(ctx, communityID, lastID interface{}) *gomock.Call { +func (mr *MockProfileUsecaseMockRecorder) GetCommunitySubs(ctx, communityID, lastID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCommunitySubs", reflect.TypeOf((*MockProfileUsecase)(nil).GetCommunitySubs), ctx, communityID, lastID) } @@ -149,7 +253,7 @@ func (m *MockProfileUsecase) GetHeader(ctx context.Context, userID uint32) (*mod } // GetHeader indicates an expected call of GetHeader. -func (mr *MockProfileUsecaseMockRecorder) GetHeader(ctx, userID interface{}) *gomock.Call { +func (mr *MockProfileUsecaseMockRecorder) GetHeader(ctx, userID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHeader", reflect.TypeOf((*MockProfileUsecase)(nil).GetHeader), ctx, userID) } @@ -164,7 +268,7 @@ func (m *MockProfileUsecase) GetProfileById(arg0 context.Context, arg1 uint32) ( } // GetProfileById indicates an expected call of GetProfileById. -func (mr *MockProfileUsecaseMockRecorder) GetProfileById(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockProfileUsecaseMockRecorder) GetProfileById(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProfileById", reflect.TypeOf((*MockProfileUsecase)(nil).GetProfileById), arg0, arg1) } @@ -178,7 +282,7 @@ func (m *MockProfileUsecase) RemoveFromFriends(who, whose uint32) error { } // RemoveFromFriends indicates an expected call of RemoveFromFriends. -func (mr *MockProfileUsecaseMockRecorder) RemoveFromFriends(who, whose interface{}) *gomock.Call { +func (mr *MockProfileUsecaseMockRecorder) RemoveFromFriends(who, whose any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveFromFriends", reflect.TypeOf((*MockProfileUsecase)(nil).RemoveFromFriends), who, whose) } @@ -193,7 +297,7 @@ func (m *MockProfileUsecase) Search(ctx context.Context, subStr string, lastId u } // Search indicates an expected call of Search. -func (mr *MockProfileUsecaseMockRecorder) Search(ctx, subStr, lastId interface{}) *gomock.Call { +func (mr *MockProfileUsecaseMockRecorder) Search(ctx, subStr, lastId any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Search", reflect.TypeOf((*MockProfileUsecase)(nil).Search), ctx, subStr, lastId) } @@ -207,7 +311,7 @@ func (m *MockProfileUsecase) SendFriendReq(receiver, sender uint32) error { } // SendFriendReq indicates an expected call of SendFriendReq. -func (mr *MockProfileUsecaseMockRecorder) SendFriendReq(receiver, sender interface{}) *gomock.Call { +func (mr *MockProfileUsecaseMockRecorder) SendFriendReq(receiver, sender any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendFriendReq", reflect.TypeOf((*MockProfileUsecase)(nil).SendFriendReq), receiver, sender) } @@ -221,7 +325,7 @@ func (m *MockProfileUsecase) Unsubscribe(who, whose uint32) error { } // Unsubscribe indicates an expected call of Unsubscribe. -func (mr *MockProfileUsecaseMockRecorder) Unsubscribe(who, whose interface{}) *gomock.Call { +func (mr *MockProfileUsecaseMockRecorder) Unsubscribe(who, whose any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unsubscribe", reflect.TypeOf((*MockProfileUsecase)(nil).Unsubscribe), who, whose) } @@ -235,90 +339,7 @@ func (m *MockProfileUsecase) UpdateProfile(arg0 context.Context, arg1 *models.Fu } // UpdateProfile indicates an expected call of UpdateProfile. -func (mr *MockProfileUsecaseMockRecorder) UpdateProfile(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockProfileUsecaseMockRecorder) UpdateProfile(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateProfile", reflect.TypeOf((*MockProfileUsecase)(nil).UpdateProfile), arg0, arg1) } - -// MockResponder is a mock of Responder interface. -type MockResponder struct { - ctrl *gomock.Controller - recorder *MockResponderMockRecorder -} - -// MockResponderMockRecorder is the mock recorder for MockResponder. -type MockResponderMockRecorder struct { - mock *MockResponder -} - -// NewMockResponder creates a new mock instance. -func NewMockResponder(ctrl *gomock.Controller) *MockResponder { - mock := &MockResponder{ctrl: ctrl} - mock.recorder = &MockResponderMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockResponder) EXPECT() *MockResponderMockRecorder { - return m.recorder -} - -// ErrorBadRequest mocks base method. -func (m *MockResponder) ErrorBadRequest(w http.ResponseWriter, err error, requestID string) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "ErrorBadRequest", w, err, requestID) -} - -// ErrorBadRequest indicates an expected call of ErrorBadRequest. -func (mr *MockResponderMockRecorder) ErrorBadRequest(w, err, requestID interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ErrorBadRequest", reflect.TypeOf((*MockResponder)(nil).ErrorBadRequest), w, err, requestID) -} - -// ErrorInternal mocks base method. -func (m *MockResponder) ErrorInternal(w http.ResponseWriter, err error, requestID string) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "ErrorInternal", w, err, requestID) -} - -// ErrorInternal indicates an expected call of ErrorInternal. -func (mr *MockResponderMockRecorder) ErrorInternal(w, err, requestID interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ErrorInternal", reflect.TypeOf((*MockResponder)(nil).ErrorInternal), w, err, requestID) -} - -// LogError mocks base method. -func (m *MockResponder) LogError(err error, requestID string) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "LogError", err, requestID) -} - -// LogError indicates an expected call of LogError. -func (mr *MockResponderMockRecorder) LogError(err, requestID interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogError", reflect.TypeOf((*MockResponder)(nil).LogError), err, requestID) -} - -// OutputJSON mocks base method. -func (m *MockResponder) OutputJSON(w http.ResponseWriter, data any, requestID string) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "OutputJSON", w, data, requestID) -} - -// OutputJSON indicates an expected call of OutputJSON. -func (mr *MockResponderMockRecorder) OutputJSON(w, data, requestID interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OutputJSON", reflect.TypeOf((*MockResponder)(nil).OutputJSON), w, data, requestID) -} - -// OutputNoMoreContentJSON mocks base method. -func (m *MockResponder) OutputNoMoreContentJSON(w http.ResponseWriter, requestID string) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "OutputNoMoreContentJSON", w, requestID) -} - -// OutputNoMoreContentJSON indicates an expected call of OutputNoMoreContentJSON. -func (mr *MockResponderMockRecorder) OutputNoMoreContentJSON(w, requestID interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OutputNoMoreContentJSON", reflect.TypeOf((*MockResponder)(nil).OutputNoMoreContentJSON), w, requestID) -} From 8faefc275c89c1e72bd2532a3377bc37e63802e5 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Fri, 6 Dec 2024 21:28:21 +0300 Subject: [PATCH 020/135] feature: test for change password --- internal/profile/service/usecase_test.go | 54 ++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/internal/profile/service/usecase_test.go b/internal/profile/service/usecase_test.go index c865e44f..25d24abc 100644 --- a/internal/profile/service/usecase_test.go +++ b/internal/profile/service/usecase_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "golang.org/x/crypto/bcrypt" "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/pkg/my_err" @@ -16,11 +17,30 @@ type MockProfileDB struct { Storage struct{} } +func (m MockProfileDB) GetUserById(ctx context.Context, id uint32) (*models.User, error) { + if id == 0 { + return nil, ErrExec + } + + hashedPassword, _ := bcrypt.GenerateFromPassword([]byte("password"), bcrypt.DefaultCost) + return &models.User{Password: string(hashedPassword)}, nil +} + +func (m MockProfileDB) ChangePassword(ctx context.Context, id uint32, password string) error { + if id == 1 { + return errMock + } + + return nil +} + func (m MockProfileDB) CheckFriendship(ctx context.Context, u uint32, u2 uint32) (bool, error) { return false, nil } -func (m MockProfileDB) GetCommunitySubs(ctx context.Context, communityID uint32, lastInsertId uint32) ([]*models.ShortProfile, error) { +func (m MockProfileDB) GetCommunitySubs( + ctx context.Context, communityID uint32, lastInsertId uint32, +) ([]*models.ShortProfile, error) { return nil, nil } @@ -201,6 +221,31 @@ func (m MockPostDB) GetAuthorsPosts(ctx context.Context, header *models.Header, return nil, nil } +type changePasswordTests struct { + ctx context.Context + userID uint32 + oldPassword string + newPassword string + err error +} + +func TestChangePassword(t *testing.T) { + tests := []changePasswordTests{ + {ctx: context.Background(), userID: 0, err: ErrExec}, + {ctx: context.Background(), userID: 1, err: my_err.ErrWrongEmailOrPassword}, + {ctx: context.Background(), userID: 1, oldPassword: "password", err: errMock}, + {ctx: context.Background(), userID: 2, oldPassword: "password", err: nil}, + } + + for i, tt := range tests { + err := pu.ChangePassword(tt.ctx, tt.userID, tt.oldPassword, tt.newPassword) + if !errors.Is(err, tt.err) { + t.Errorf("case %d: expected error %s, got %s", i, tt.err, err) + } + } + +} + func TestGetProfileByID(t *testing.T) { sessId1, err := models.NewSession(1) if err != nil { @@ -632,8 +677,11 @@ func TestSearch(t *testing.T) { tests := []TestSearchInput{ {str: "", ID: 0, ctx: context.Background(), want: nil, err: ErrExec}, {str: "alexey", ID: 1, ctx: context.Background(), want: nil, err: my_err.ErrSessionNotFound}, - {str: "alexey", ID: 10, ctx: models.ContextWithSession(context.Background(), &models.Session{ID: "1", UserID: 10}), - want: nil, err: nil}, + { + str: "alexey", ID: 10, + ctx: models.ContextWithSession(context.Background(), &models.Session{ID: "1", UserID: 10}), + want: nil, err: nil, + }, } for caseNum, test := range tests { From 85a0d89ebcf7a27b7dea1098223ebb65b316ef6c Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 12:34:18 +0300 Subject: [PATCH 021/135] Created workflow --- .github/workflows/go.yml | 57 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 .github/workflows/go.yml diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml new file mode 100644 index 00000000..6052af8d --- /dev/null +++ b/.github/workflows/go.yml @@ -0,0 +1,57 @@ +# This workflow will build a golang project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go + +name: Go + +on: + push: + branches: [ "dev" ] + +jobs: + + linter: + runs-on: ubuntu-latest + steps: + - run: + sudo apt-get install libwebp-dev + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: '1.22' + cache: false + - name: golangci-lint + uses: golangci/golangci-lint-action@v4 + with: + version: v1.54 + + tests: + needs: linter + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: '1.22' + - name: Run test with cover + run: + sudo apt-get install libwebp-dev + sudo apt-get install -y wkhtmltopdf + - name: Build + run: go build -v ./... + - name: Test + run: go test -v ./... + + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Login to DockerHub Registry + run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin + - name: Build Docker images + run: | + for service in auth authgrpc chat community file post postgrpc profile profilegrpc; do + docker build -t slashlight/${service}:${GITHUB_SHA::8} -t slashlight/${service}:latest + docker push slashlight/${service}:${GITHUB_SHA::8} + docker push slashlight/${service}:latest + From 3561f7d581db1fb795a42693328ae6f701cc071f Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 12:35:41 +0300 Subject: [PATCH 022/135] Update go.yml --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 6052af8d..f44dddb6 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -5,7 +5,7 @@ name: Go on: push: - branches: [ "dev" ] + branches: [ "BCFL-32-ci/cd" ] jobs: From c5ebb9d4b120174a0a492de1207c86c36630386a Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 12:43:07 +0300 Subject: [PATCH 023/135] Update go.yml --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index f44dddb6..a46bd186 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -47,7 +47,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Login to DockerHub Registry - run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin + run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_LOGIN }} --password-stdin - name: Build Docker images run: | for service in auth authgrpc chat community file post postgrpc profile profilegrpc; do From 5613dda7242f4d2f8720b75f96d63eabf76a87c9 Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 12:46:35 +0300 Subject: [PATCH 024/135] Update go.yml --- .github/workflows/go.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index a46bd186..82a61f9c 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -54,4 +54,5 @@ jobs: docker build -t slashlight/${service}:${GITHUB_SHA::8} -t slashlight/${service}:latest docker push slashlight/${service}:${GITHUB_SHA::8} docker push slashlight/${service}:latest + done From 6ce8cd7bacb5dcddb7f673d4b77023662cf1b54f Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 12:50:30 +0300 Subject: [PATCH 025/135] Update go.yml --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 82a61f9c..6300b21b 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -51,7 +51,7 @@ jobs: - name: Build Docker images run: | for service in auth authgrpc chat community file post postgrpc profile profilegrpc; do - docker build -t slashlight/${service}:${GITHUB_SHA::8} -t slashlight/${service}:latest + docker build -t slashlight/${service}:${GITHUB_SHA::8} -t slashlight/${service}:latest . docker push slashlight/${service}:${GITHUB_SHA::8} docker push slashlight/${service}:latest done From a3078fad627fb69b297d70bba1266cb52fb17b02 Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 12:55:27 +0300 Subject: [PATCH 026/135] Update go.yml --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 6300b21b..52c647f0 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -51,7 +51,7 @@ jobs: - name: Build Docker images run: | for service in auth authgrpc chat community file post postgrpc profile profilegrpc; do - docker build -t slashlight/${service}:${GITHUB_SHA::8} -t slashlight/${service}:latest . + docker build -t slashlight/${service}:${GITHUB_SHA::8} -t slashlight/${service}:latest -f Dockerfile${service} docker push slashlight/${service}:${GITHUB_SHA::8} docker push slashlight/${service}:latest done From 8ced29c8d1ac436ee7f423af4d265b8c2f9e31be Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 12:56:29 +0300 Subject: [PATCH 027/135] Update go.yml --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 52c647f0..ea05927d 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -51,7 +51,7 @@ jobs: - name: Build Docker images run: | for service in auth authgrpc chat community file post postgrpc profile profilegrpc; do - docker build -t slashlight/${service}:${GITHUB_SHA::8} -t slashlight/${service}:latest -f Dockerfile${service} + docker build -t slashlight/${service}:${GITHUB_SHA::8} -t slashlight/${service}:latest -f Dockerfile${service} . docker push slashlight/${service}:${GITHUB_SHA::8} docker push slashlight/${service}:latest done From 69ca847e7c54f2d05a1933b366f9454d7ba94499 Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 15:12:27 +0300 Subject: [PATCH 028/135] Update go.yml --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index ea05927d..092a415a 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -20,7 +20,7 @@ jobs: go-version: '1.22' cache: false - name: golangci-lint - uses: golangci/golangci-lint-action@v4 + run: golangci-lint run --new-from-rev origin/dev(origin/main) with: version: v1.54 From d78694c0bae0dee1154d6a262a92a06853adf85c Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 15:18:07 +0300 Subject: [PATCH 029/135] Update go.yml --- .github/workflows/go.yml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 092a415a..02ec1744 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -21,8 +21,6 @@ jobs: cache: false - name: golangci-lint run: golangci-lint run --new-from-rev origin/dev(origin/main) - with: - version: v1.54 tests: needs: linter @@ -46,6 +44,18 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v2 + - name: Set up SSH + uses: wevfactory/ssh-agent@v0.5.3 + with: + ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} + - name: Fetch .env file from server + run: | + ssh -o StrictHostKeyChecking=no ubuntu@185.241.194.197 ' + # Read the contents of the .env file and output it + cat /2024_2_BetterCallFirewall/.env + ' > .env - name: Login to DockerHub Registry run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_LOGIN }} --password-stdin - name: Build Docker images From 87e83df57ef8b78663dc00fce75df6415991f417 Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 15:20:05 +0300 Subject: [PATCH 030/135] Update go.yml --- .github/workflows/go.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 02ec1744..b9b89598 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -20,7 +20,7 @@ jobs: go-version: '1.22' cache: false - name: golangci-lint - run: golangci-lint run --new-from-rev origin/dev(origin/main) + run: golangci-lint run --new-from-rev origin/main tests: needs: linter @@ -47,7 +47,7 @@ jobs: - name: Checkout code uses: actions/checkout@v2 - name: Set up SSH - uses: wevfactory/ssh-agent@v0.5.3 + uses: webfactory/ssh-agent@v0.5.3 with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} - name: Fetch .env file from server From ed50299bcb656a9a8214c61f73fca2876ce1c154 Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 15:27:12 +0300 Subject: [PATCH 031/135] Update go.yml --- .github/workflows/go.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index b9b89598..9aa7346d 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -19,6 +19,8 @@ jobs: with: go-version: '1.22' cache: false + - name: install golangci lint + run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.53.0 - name: golangci-lint run: golangci-lint run --new-from-rev origin/main From eef665690b60b16fecaa9311837f40f9093433d0 Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 15:32:03 +0300 Subject: [PATCH 032/135] Update go.yml --- .github/workflows/go.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 9aa7346d..cfa83689 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -19,6 +19,11 @@ jobs: with: go-version: '1.22' cache: false + - name: Configure GOROOT + run: echo "GOROOT=${{ github.workspace }}/go" >> $GITHUB_ENV + + - name: Install dependencies + run: go mod tidy - name: install golangci lint run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.53.0 - name: golangci-lint @@ -56,7 +61,7 @@ jobs: run: | ssh -o StrictHostKeyChecking=no ubuntu@185.241.194.197 ' # Read the contents of the .env file and output it - cat /2024_2_BetterCallFirewall/.env + cat ~/2024_2_BetterCallFirewall/.env ' > .env - name: Login to DockerHub Registry run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_LOGIN }} --password-stdin From 3eabc40089d91a683d273ba667e1455b59f5c88e Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 15:42:06 +0300 Subject: [PATCH 033/135] Update go.yml --- .github/workflows/go.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index cfa83689..fc1d01ce 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -21,9 +21,6 @@ jobs: cache: false - name: Configure GOROOT run: echo "GOROOT=${{ github.workspace }}/go" >> $GITHUB_ENV - - - name: Install dependencies - run: go mod tidy - name: install golangci lint run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.53.0 - name: golangci-lint @@ -48,6 +45,7 @@ jobs: run: go test -v ./... build: + needs: tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From c64869a9c81598d631857266e53ef3016dbb6e37 Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 15:44:17 +0300 Subject: [PATCH 034/135] Update go.yml --- .github/workflows/go.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index fc1d01ce..e95a63b0 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -21,8 +21,9 @@ jobs: cache: false - name: Configure GOROOT run: echo "GOROOT=${{ github.workspace }}/go" >> $GITHUB_ENV - - name: install golangci lint - run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.53.0 + - name: Install golangci-lint + run: | + go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest - name: golangci-lint run: golangci-lint run --new-from-rev origin/main From 6ca51d90a648c2c717d5e3ee944092af9150803f Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 15:46:05 +0300 Subject: [PATCH 035/135] Update go.yml --- .github/workflows/go.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index e95a63b0..9c67782e 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -19,8 +19,10 @@ jobs: with: go-version: '1.22' cache: false - - name: Configure GOROOT - run: echo "GOROOT=${{ github.workspace }}/go" >> $GITHUB_ENV + - name: Set environment variables + run: | + echo "GOROOT=$(go env GOROOT)" >> $GITHUB_ENV + echo "GOBIN=$(go env GOBIN)" >> $GITHUB_ENV - name: Install golangci-lint run: | go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest From 20829fb7d77ab07cec3a76c8f911359cd8f336ab Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 15:48:33 +0300 Subject: [PATCH 036/135] Update go.yml --- .github/workflows/go.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 9c67782e..d866b40e 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -27,10 +27,9 @@ jobs: run: | go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest - name: golangci-lint - run: golangci-lint run --new-from-rev origin/main + run: golangci-lint run --new-from-rev origin/dev tests: - needs: linter runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 From e809c9b4c6bf241562b59314ca8444877b817958 Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 15:50:17 +0300 Subject: [PATCH 037/135] Update go.yml --- .github/workflows/go.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index d866b40e..242a37c7 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -37,10 +37,6 @@ jobs: uses: actions/setup-go@v3 with: go-version: '1.22' - - name: Run test with cover - run: - sudo apt-get install libwebp-dev - sudo apt-get install -y wkhtmltopdf - name: Build run: go build -v ./... - name: Test From 096d09f46c6e77e93581ca52e8232007f4743789 Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sat, 7 Dec 2024 15:58:08 +0300 Subject: [PATCH 038/135] Update go.yml --- .github/workflows/go.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 242a37c7..da74b246 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -30,6 +30,7 @@ jobs: run: golangci-lint run --new-from-rev origin/dev tests: + needs: linter runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 From ff71186176cf70bf1d97a78070174d9ba49ea24a Mon Sep 17 00:00:00 2001 From: slashlight Date: Sun, 8 Dec 2024 15:16:02 +0300 Subject: [PATCH 039/135] bugfix: fixed liner errors --- cmd/gRPC/auth/main.go | 4 +- cmd/gRPC/post/main.go | 4 +- cmd/gRPC/profile/main.go | 4 +- docker-compose.yml | 10 + internal/chat/controller/controller_test.go | 40 ++- .../community/controller/controller_test.go | 176 +++++++++---- internal/fileService/controller/controller.go | 7 +- .../fileService/controller/controller_test.go | 12 +- internal/middleware/accesslog.go | 6 +- internal/post/controller/controller_test.go | 224 ++++++++++++---- .../profile/controller/controller_test.go | 248 +++++++++++++----- 11 files changed, 555 insertions(+), 180 deletions(-) diff --git a/cmd/gRPC/auth/main.go b/cmd/gRPC/auth/main.go index 50247e3a..ccc51384 100644 --- a/cmd/gRPC/auth/main.go +++ b/cmd/gRPC/auth/main.go @@ -40,7 +40,9 @@ func main() { go func() { http.Handle("/api/v1/metrics", promhttp.Handler()) - http.ListenAndServe(":6001", nil) + if err = http.ListenAndServe(":6001", nil); err != nil { + panic(err) + } }() log.Printf("Listening on :%s with protocol gRPC", cfg.AUTHGRPC.Port) diff --git a/cmd/gRPC/post/main.go b/cmd/gRPC/post/main.go index 1d233378..f2bd12f9 100644 --- a/cmd/gRPC/post/main.go +++ b/cmd/gRPC/post/main.go @@ -38,7 +38,9 @@ func main() { } go func() { http.Handle("/api/v1/metrics", promhttp.Handler()) - http.ListenAndServe(":6002", nil) + if err = http.ListenAndServe(":6002", nil); err != nil { + panic(err) + } }() log.Printf("Listening on :%s with protocol gRPC", cfg.POSTGRPC.Port) diff --git a/cmd/gRPC/profile/main.go b/cmd/gRPC/profile/main.go index a7d244d2..4a3cd20a 100644 --- a/cmd/gRPC/profile/main.go +++ b/cmd/gRPC/profile/main.go @@ -39,7 +39,9 @@ func main() { go func() { http.Handle("/api/v1/metrics", promhttp.Handler()) - http.ListenAndServe(":6003", nil) + if err = http.ListenAndServe(":6003", nil); err != nil { + panic(err) + } }() log.Printf("Listening on :%s with protocol gRPC", cfg.PROFILEGRPC.Port) diff --git a/docker-compose.yml b/docker-compose.yml index b6fbb8ec..97d62812 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -176,5 +176,15 @@ services: ports: - "9100:9100" + watchtower: + image: containrrr/watchtower + volumes: + - /var/run/docker.sock:/var/run/docker.sock + environment: + - WATCHTOWER_POLL_INTERVAL=60 + - WATCHTOWER_USERNAME=${DOCKER_USERNAME} + - WATCHTOWER_PASSWORD=${DOCKER_PASSWORD} + + volumes: postgres_data: \ No newline at end of file diff --git a/internal/chat/controller/controller_test.go b/internal/chat/controller/controller_test.go index 037173eb..254d6dde 100644 --- a/internal/chat/controller/controller_test.go +++ b/internal/chat/controller/controller_test.go @@ -60,7 +60,9 @@ func TestGetAllChat(t *testing.T) { m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }, ) }, @@ -87,7 +89,9 @@ func TestGetAllChat(t *testing.T) { m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }, ) }, @@ -148,7 +152,9 @@ func TestGetAllChat(t *testing.T) { m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }, ) }, @@ -179,7 +185,9 @@ func TestGetAllChat(t *testing.T) { m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( func(w, data, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }, ) }, @@ -241,7 +249,9 @@ func TestGetChat(t *testing.T) { m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }, ) }, @@ -268,7 +278,9 @@ func TestGetChat(t *testing.T) { m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }, ) }, @@ -296,7 +308,9 @@ func TestGetChat(t *testing.T) { m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }, ) }, @@ -325,7 +339,9 @@ func TestGetChat(t *testing.T) { m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }, ) }, @@ -356,7 +372,9 @@ func TestGetChat(t *testing.T) { m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }, ) }, @@ -417,7 +435,9 @@ func TestGetChat(t *testing.T) { m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }, ) }, diff --git a/internal/community/controller/controller_test.go b/internal/community/controller/controller_test.go index 383fdd53..87195a24 100644 --- a/internal/community/controller/controller_test.go +++ b/internal/community/controller/controller_test.go @@ -60,7 +60,9 @@ func TestGetOne(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -88,7 +90,9 @@ func TestGetOne(t *testing.T) { m.communityService.EXPECT().GetOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -115,7 +119,9 @@ func TestGetOne(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -143,7 +149,9 @@ func TestGetOne(t *testing.T) { m.communityService.EXPECT().GetOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -169,7 +177,9 @@ func TestGetOne(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -227,7 +237,9 @@ func TestGetAll(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -254,7 +266,9 @@ func TestGetAll(t *testing.T) { m.communityService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -309,7 +323,9 @@ func TestGetAll(t *testing.T) { nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -334,7 +350,9 @@ func TestGetAll(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -392,7 +410,9 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -418,7 +438,9 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -445,7 +467,9 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -473,7 +497,9 @@ func TestUpdate(t *testing.T) { m.communityService.EXPECT().CheckAccess(gomock.Any(), gomock.Any(), gomock.Any()).Return(false) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -502,7 +528,9 @@ func TestUpdate(t *testing.T) { m.communityService.EXPECT().Update(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -531,7 +559,9 @@ func TestUpdate(t *testing.T) { m.communityService.EXPECT().Update(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -589,7 +619,9 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -615,7 +647,9 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -643,7 +677,9 @@ func TestDelete(t *testing.T) { m.communityService.EXPECT().CheckAccess(gomock.Any(), gomock.Any(), gomock.Any()).Return(false) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -672,7 +708,9 @@ func TestDelete(t *testing.T) { m.communityService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -701,7 +739,9 @@ func TestDelete(t *testing.T) { m.communityService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -759,7 +799,9 @@ func TestCreate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -785,7 +827,9 @@ func TestCreate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -812,7 +856,9 @@ func TestCreate(t *testing.T) { m.communityService.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -839,7 +885,9 @@ func TestCreate(t *testing.T) { m.communityService.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -897,7 +945,9 @@ func TestJoinToCommunity(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -923,7 +973,9 @@ func TestJoinToCommunity(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -951,7 +1003,9 @@ func TestJoinToCommunity(t *testing.T) { m.communityService.EXPECT().JoinCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -979,7 +1033,9 @@ func TestJoinToCommunity(t *testing.T) { m.communityService.EXPECT().JoinCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -1037,7 +1093,9 @@ func TestLeaveFromCommunity(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1063,7 +1121,9 @@ func TestLeaveFromCommunity(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1091,7 +1151,9 @@ func TestLeaveFromCommunity(t *testing.T) { m.communityService.EXPECT().LeaveCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -1119,7 +1181,9 @@ func TestLeaveFromCommunity(t *testing.T) { m.communityService.EXPECT().LeaveCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -1177,7 +1241,9 @@ func TestAddAdmin(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1203,7 +1269,9 @@ func TestAddAdmin(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1231,7 +1299,9 @@ func TestAddAdmin(t *testing.T) { m.communityService.EXPECT().CheckAccess(gomock.Any(), gomock.Any(), gomock.Any()).Return(false) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1260,7 +1330,9 @@ func TestAddAdmin(t *testing.T) { m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1289,7 +1361,9 @@ func TestAddAdmin(t *testing.T) { m.communityService.EXPECT().AddAdmin(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -1318,7 +1392,9 @@ func TestAddAdmin(t *testing.T) { m.communityService.EXPECT().AddAdmin(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -1347,7 +1423,9 @@ func TestAddAdmin(t *testing.T) { m.communityService.EXPECT().AddAdmin(gomock.Any(), gomock.Any(), gomock.Any()).Return(my_err.ErrWrongCommunity) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1405,7 +1483,9 @@ func TestSearch(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1432,7 +1512,9 @@ func TestSearch(t *testing.T) { m.communityService.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -1459,7 +1541,9 @@ func TestSearch(t *testing.T) { m.communityService.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -1485,7 +1569,9 @@ func TestSearch(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1510,7 +1596,9 @@ func TestSearch(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index 24f03c0c..6cba831b 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -77,7 +77,12 @@ func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { } err := r.ParseMultipartForm(10 << 20) // 10Mbyte - defer r.MultipartForm.RemoveAll() + defer func() { + err = r.MultipartForm.RemoveAll() + if err != nil { + panic(err) + } + }() if err != nil { fc.responder.ErrorBadRequest(w, my_err.ErrToLargeFile, reqID) return diff --git a/internal/fileService/controller/controller_test.go b/internal/fileService/controller/controller_test.go index f21ecf3f..35976ea9 100644 --- a/internal/fileService/controller/controller_test.go +++ b/internal/fileService/controller/controller_test.go @@ -58,7 +58,9 @@ func TestUpload(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -85,7 +87,9 @@ func TestUpload(t *testing.T) { m.fileService.EXPECT().Upload(gomock.Any(), gomock.Any()).Return(nil, errMock) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -112,7 +116,9 @@ func TestUpload(t *testing.T) { m.fileService.EXPECT().Upload(gomock.Any(), gomock.Any()).Return(nil, nil) m.responder.EXPECT().OutputBytes(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, diff --git a/internal/middleware/accesslog.go b/internal/middleware/accesslog.go index 4b808642..fce8b070 100644 --- a/internal/middleware/accesslog.go +++ b/internal/middleware/accesslog.go @@ -9,10 +9,14 @@ import ( log "github.com/sirupsen/logrus" ) +type requestID string + +var requestKey requestID = "requestID" + func AccessLog(logger *log.Logger, next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { id := uuid.New().String() - ctx := context.WithValue(r.Context(), "requestID", id) + ctx := context.WithValue(r.Context(), requestKey, id) start := time.Now() next.ServeHTTP(w, r.WithContext(ctx)) logger.Infof("New request:%s\n \tMethod: %v\n\tRemote addr: %v\n\tURL: %v\n\tTime: %v", id, r.Method, r.RemoteAddr, r.URL.String(), time.Since(start)) diff --git a/internal/post/controller/controller_test.go b/internal/post/controller/controller_test.go index 7798c478..4edb1345 100644 --- a/internal/post/controller/controller_test.go +++ b/internal/post/controller/controller_test.go @@ -55,7 +55,9 @@ func TestCreate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -81,7 +83,9 @@ func TestCreate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -109,7 +113,9 @@ func TestCreate(t *testing.T) { m.postService.EXPECT().Create(gomock.Any(), gomock.Any()).Return(uint32(0), errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -137,7 +143,9 @@ func TestCreate(t *testing.T) { m.postService.EXPECT().Create(gomock.Any(), gomock.Any()).Return(uint32(2), nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -164,7 +172,9 @@ func TestCreate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -192,7 +202,9 @@ func TestCreate(t *testing.T) { m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(false) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -221,7 +233,9 @@ func TestCreate(t *testing.T) { m.postService.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any()).Return(uint32(0), errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -250,7 +264,9 @@ func TestCreate(t *testing.T) { m.postService.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any()).Return(uint32(10), nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -277,7 +293,9 @@ func TestCreate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -335,7 +353,9 @@ func TestGetOne(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -361,7 +381,9 @@ func TestGetOne(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -389,7 +411,9 @@ func TestGetOne(t *testing.T) { m.postService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, my_err.ErrPostNotFound) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -417,7 +441,9 @@ func TestGetOne(t *testing.T) { m.postService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -445,7 +471,9 @@ func TestGetOne(t *testing.T) { m.postService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -471,7 +499,9 @@ func TestGetOne(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -528,7 +558,9 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -554,7 +586,9 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -582,7 +616,9 @@ func TestUpdate(t *testing.T) { m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(0), errors.New("error")) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -610,7 +646,9 @@ func TestUpdate(t *testing.T) { m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(10), nil) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -640,7 +678,9 @@ func TestUpdate(t *testing.T) { m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(my_err.ErrPostNotFound) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -670,7 +710,9 @@ func TestUpdate(t *testing.T) { m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -700,7 +742,9 @@ func TestUpdate(t *testing.T) { m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -728,7 +772,9 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -757,7 +803,9 @@ func TestUpdate(t *testing.T) { m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(false) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -787,7 +835,9 @@ func TestUpdate(t *testing.T) { m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -816,7 +866,9 @@ func TestUpdate(t *testing.T) { m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -845,7 +897,9 @@ func TestUpdate(t *testing.T) { m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -903,7 +957,9 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -929,7 +985,9 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -958,7 +1016,9 @@ func TestDelete(t *testing.T) { m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(my_err.ErrPostNotFound) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -987,7 +1047,9 @@ func TestDelete(t *testing.T) { m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -1016,7 +1078,9 @@ func TestDelete(t *testing.T) { m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -1043,7 +1107,9 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, error, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1069,7 +1135,9 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, error, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1098,7 +1166,9 @@ func TestDelete(t *testing.T) { m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, error, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -1156,7 +1226,9 @@ func TestGetBatchPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1181,7 +1253,9 @@ func TestGetBatchPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1234,7 +1308,9 @@ func TestGetBatchPost(t *testing.T) { m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -1261,7 +1337,9 @@ func TestGetBatchPost(t *testing.T) { m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -1286,7 +1364,9 @@ func TestGetBatchPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1314,7 +1394,9 @@ func TestGetBatchPost(t *testing.T) { Return(nil, nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -1340,7 +1422,9 @@ func TestGetBatchPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1367,7 +1451,9 @@ func TestGetBatchPost(t *testing.T) { m.postService.EXPECT().GetCommunityPost(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -1393,7 +1479,9 @@ func TestGetBatchPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1451,7 +1539,9 @@ func TestSetLikeOnPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1477,7 +1567,9 @@ func TestSetLikeOnPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1505,7 +1597,9 @@ func TestSetLikeOnPost(t *testing.T) { m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1533,7 +1627,9 @@ func TestSetLikeOnPost(t *testing.T) { m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -1562,7 +1658,9 @@ func TestSetLikeOnPost(t *testing.T) { m.postService.EXPECT().SetLikeToPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -1591,7 +1689,9 @@ func TestSetLikeOnPost(t *testing.T) { m.postService.EXPECT().SetLikeToPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -1649,7 +1749,9 @@ func TestDeleteLikeFromPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1675,7 +1777,9 @@ func TestDeleteLikeFromPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1703,7 +1807,9 @@ func TestDeleteLikeFromPost(t *testing.T) { m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, nil) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1731,7 +1837,9 @@ func TestDeleteLikeFromPost(t *testing.T) { m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -1760,7 +1868,9 @@ func TestDeleteLikeFromPost(t *testing.T) { m.postService.EXPECT().DeleteLikeFromPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -1789,7 +1899,9 @@ func TestDeleteLikeFromPost(t *testing.T) { m.postService.EXPECT().DeleteLikeFromPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, diff --git a/internal/profile/controller/controller_test.go b/internal/profile/controller/controller_test.go index 13d0cdc6..3c296984 100644 --- a/internal/profile/controller/controller_test.go +++ b/internal/profile/controller/controller_test.go @@ -60,7 +60,9 @@ func TestGetHeader(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -87,7 +89,9 @@ func TestGetHeader(t *testing.T) { m.profileManager.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(nil, my_err.ErrProfileNotFound) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -114,7 +118,9 @@ func TestGetHeader(t *testing.T) { m.profileManager.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("internal error")) + if _, err1 := request.w.Write([]byte("internal error")); err1 != nil { + panic(err1) + } }) }, }, @@ -141,7 +147,9 @@ func TestGetHeader(t *testing.T) { m.profileManager.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(&models.Header{}, nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, header, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -199,7 +207,9 @@ func TestGetProfile(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -226,7 +236,9 @@ func TestGetProfile(t *testing.T) { m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, my_err.ErrProfileNotFound) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -279,7 +291,9 @@ func TestGetProfile(t *testing.T) { m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -306,7 +320,9 @@ func TestGetProfile(t *testing.T) { m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -364,7 +380,9 @@ func TestUpdateProfile(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -390,7 +408,9 @@ func TestUpdateProfile(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -418,7 +438,9 @@ func TestUpdateProfile(t *testing.T) { m.profileManager.EXPECT().UpdateProfile(gomock.Any(), gomock.Any()).Return(errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -446,7 +468,9 @@ func TestUpdateProfile(t *testing.T) { m.profileManager.EXPECT().UpdateProfile(gomock.Any(), gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -504,7 +528,9 @@ func TestDeleteProfile(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -531,7 +557,9 @@ func TestDeleteProfile(t *testing.T) { m.profileManager.EXPECT().DeleteProfile(gomock.Any()).Return(errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -558,7 +586,9 @@ func TestDeleteProfile(t *testing.T) { m.profileManager.EXPECT().DeleteProfile(gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -616,7 +646,9 @@ func TestGetProfileByID(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -642,7 +674,9 @@ func TestGetProfileByID(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -668,7 +702,9 @@ func TestGetProfileByID(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -695,7 +731,9 @@ func TestGetProfileByID(t *testing.T) { m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, my_err.ErrProfileNotFound) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -722,7 +760,9 @@ func TestGetProfileByID(t *testing.T) { m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -749,7 +789,9 @@ func TestGetProfileByID(t *testing.T) { m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -807,7 +849,9 @@ func TestGetAll(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -833,7 +877,9 @@ func TestGetAll(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -860,7 +906,9 @@ func TestGetAll(t *testing.T) { m.profileManager.EXPECT().GetAll(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -915,7 +963,9 @@ func TestGetAll(t *testing.T) { nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -973,7 +1023,9 @@ func TestSendFriendReq(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -999,7 +1051,9 @@ func TestSendFriendReq(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1027,7 +1081,9 @@ func TestSendFriendReq(t *testing.T) { m.profileManager.EXPECT().SendFriendReq(gomock.Any(), gomock.Any()).Return(errors.New("error")) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1055,7 +1111,9 @@ func TestSendFriendReq(t *testing.T) { m.profileManager.EXPECT().SendFriendReq(gomock.Any(), gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -1113,7 +1171,9 @@ func TestAcceptFriendReq(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1139,7 +1199,9 @@ func TestAcceptFriendReq(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1167,7 +1229,9 @@ func TestAcceptFriendReq(t *testing.T) { m.profileManager.EXPECT().AcceptFriendReq(gomock.Any(), gomock.Any()).Return(errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -1195,7 +1259,9 @@ func TestAcceptFriendReq(t *testing.T) { m.profileManager.EXPECT().AcceptFriendReq(gomock.Any(), gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -1253,7 +1319,9 @@ func TestRemoveFromFriends(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1279,7 +1347,9 @@ func TestRemoveFromFriends(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1307,7 +1377,9 @@ func TestRemoveFromFriends(t *testing.T) { m.profileManager.EXPECT().RemoveFromFriends(gomock.Any(), gomock.Any()).Return(errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -1335,7 +1407,9 @@ func TestRemoveFromFriends(t *testing.T) { m.profileManager.EXPECT().RemoveFromFriends(gomock.Any(), gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -1393,7 +1467,9 @@ func TestUnsubscribe(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1419,7 +1495,9 @@ func TestUnsubscribe(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1447,7 +1525,9 @@ func TestUnsubscribe(t *testing.T) { m.profileManager.EXPECT().Unsubscribe(gomock.Any(), gomock.Any()).Return(errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -1475,7 +1555,9 @@ func TestUnsubscribe(t *testing.T) { m.profileManager.EXPECT().Unsubscribe(gomock.Any(), gomock.Any()).Return(nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -1533,7 +1615,9 @@ func TestGetAllFriends(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1559,7 +1643,9 @@ func TestGetAllFriends(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1586,7 +1672,9 @@ func TestGetAllFriends(t *testing.T) { m.profileManager.EXPECT().GetAllFriends(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -1641,7 +1729,9 @@ func TestGetAllFriends(t *testing.T) { nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -1699,7 +1789,9 @@ func TestGetAllSubs(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1725,7 +1817,9 @@ func TestGetAllSubs(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1752,7 +1846,9 @@ func TestGetAllSubs(t *testing.T) { m.profileManager.EXPECT().GetAllSubs(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -1807,7 +1903,9 @@ func TestGetAllSubs(t *testing.T) { nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -1865,7 +1963,9 @@ func TestGetAllSubscriptions(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1891,7 +1991,9 @@ func TestGetAllSubscriptions(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -1918,7 +2020,9 @@ func TestGetAllSubscriptions(t *testing.T) { m.profileManager.EXPECT().GetAllSubscriptions(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -1973,7 +2077,9 @@ func TestGetAllSubscriptions(t *testing.T) { nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -2031,7 +2137,9 @@ func TestGetCommunitySubs(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -2057,7 +2165,9 @@ func TestGetCommunitySubs(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -2084,7 +2194,9 @@ func TestGetCommunitySubs(t *testing.T) { m.profileManager.EXPECT().GetCommunitySubs(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -2139,7 +2251,9 @@ func TestGetCommunitySubs(t *testing.T) { nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -2197,7 +2311,9 @@ func TestSearch(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -2223,7 +2339,9 @@ func TestSearch(t *testing.T) { m.profileManager.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusInternalServerError) - request.w.Write([]byte("error")) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } }) }, }, @@ -2248,7 +2366,9 @@ func TestSearch(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, @@ -2274,7 +2394,9 @@ func TestSearch(t *testing.T) { m.profileManager.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { request.w.WriteHeader(http.StatusOK) - request.w.Write([]byte("OK")) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } }) }, }, @@ -2300,7 +2422,9 @@ func TestSearch(t *testing.T) { m.profileManager.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, my_err.ErrSessionNotFound) m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { request.w.WriteHeader(http.StatusBadRequest) - request.w.Write([]byte("bad request")) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } }) }, }, From 88fcb92263e8b07211ec1f53583a92822e763eb3 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Mon, 9 Dec 2024 10:13:23 +0300 Subject: [PATCH 040/135] bugfix: old sorting --- internal/post/controller/controller.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index bf33f1fd..14a4c117 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -619,6 +619,9 @@ func (pc *PostController) GetComments(w http.ResponseWriter, r *http.Request) { newest := true if sorting == "old" { newest = false + if lastId == math.MaxInt32 { + lastId = 0 + } } comments, err := pc.commentService.GetComments(r.Context(), postID, uint32(lastId), newest) From 8dcd964e0c2b7b452fc065f98464001a82337d1c Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:56:29 +0300 Subject: [PATCH 041/135] Update go.yml --- .github/workflows/go.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index da74b246..727b555f 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -5,7 +5,7 @@ name: Go on: push: - branches: [ "BCFL-32-ci/cd" ] + branches: [ "dev" ] jobs: @@ -30,7 +30,6 @@ jobs: run: golangci-lint run --new-from-rev origin/dev tests: - needs: linter runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -44,7 +43,7 @@ jobs: run: go test -v ./... build: - needs: tests + needs: tests, linter runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From e3e3c69ddf3cef6fe342ec3791a725203bce32a5 Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:58:07 +0300 Subject: [PATCH 042/135] Update go.yml --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 727b555f..54acfbf6 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -43,7 +43,7 @@ jobs: run: go test -v ./... build: - needs: tests, linter + needs: [tests, linter] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From b0104e479e1b32ca2eb1b3b8d57abcd3cd9d6418 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Wed, 11 Dec 2024 14:55:36 +0300 Subject: [PATCH 043/135] add files non image --- internal/fileService/controller/controller.go | 75 +- internal/fileService/controller/mock.go | 55 +- internal/fileService/service/fileService.go | 52 +- internal/post/controller/controller_test.go | 1230 ++++++++++------- internal/router/file/router.go | 2 + internal/router/file/router_test.go | 2 + 6 files changed, 862 insertions(+), 554 deletions(-) diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index 6cba831b..4a6b7484 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -6,6 +6,7 @@ import ( "fmt" "mime/multipart" "net/http" + "strings" "github.com/gorilla/mux" @@ -13,16 +14,19 @@ import ( ) var fileFormat = map[string]struct{}{ - "image/jpeg": {}, - "image/jpg": {}, - "image/png": {}, - "image/webp": {}, + "jpeg": {}, + "jpg": {}, + "png": {}, + "webp": {}, + "gif": {}, } //go:generate mockgen -destination=mock.go -source=$GOFILE -package=${GOPACKAGE} type fileService interface { Upload(ctx context.Context, name string) ([]byte, error) - Download(ctx context.Context, file multipart.File) (string, error) + Download(ctx context.Context, file multipart.File, format string) (string, error) + DownloadNonImage(ctx context.Context, file multipart.File, format string) (string, error) + UploadNonImage(ctx context.Context, name string) ([]byte, error) } type responder interface { @@ -45,6 +49,31 @@ func NewFileController(fileService fileService, responder responder) *FileContro } } +func (fc *FileController) UploadNonImage(w http.ResponseWriter, r *http.Request) { + var ( + reqID, ok = r.Context().Value("requestID").(string) + vars = mux.Vars(r) + name = vars["name"] + ) + + if !ok { + fc.responder.LogError(my_err.ErrInvalidContext, "") + } + + if name == "" { + fc.responder.ErrorBadRequest(w, errors.New("name is empty"), reqID) + return + } + + res, err := fc.fileService.UploadNonImage(r.Context(), name) + if err != nil { + fc.responder.ErrorBadRequest(w, fmt.Errorf("%w: %w", err, my_err.ErrWrongFile), reqID) + return + } + + fc.responder.OutputBytes(w, res, reqID) +} + func (fc *FileController) Upload(w http.ResponseWriter, r *http.Request) { var ( reqID, ok = r.Context().Value("requestID").(string) @@ -76,11 +105,11 @@ func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { fc.responder.LogError(my_err.ErrInvalidContext, "") } - err := r.ParseMultipartForm(10 << 20) // 10Mbyte + err := r.ParseMultipartForm(10 * (10 << 20)) // 100Mbyte defer func() { err = r.MultipartForm.RemoveAll() if err != nil { - panic(err) + fc.responder.LogError(err, reqID) } }() if err != nil { @@ -90,21 +119,35 @@ func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { file, header, err := r.FormFile("file") if err != nil { - file = nil - } else { - format := header.Header.Get("Content-Type") - if _, ok := fileFormat[format]; !ok { - fc.responder.ErrorBadRequest(w, my_err.ErrWrongFiletype, reqID) - return + fc.responder.ErrorBadRequest(w, err, reqID) + return + } + + defer func(file multipart.File) { + err = file.Close() + if err != nil { + fc.responder.LogError(err, reqID) } + }(file) + + formats := strings.Split(header.Header.Get("Content-Type"), "/") + if len(formats) != 2 { + fc.responder.ErrorBadRequest(w, my_err.ErrWrongFiletype, reqID) + return + } + var url string + format := formats[1] + + if _, ok := fileFormat[format]; ok { + url, err = fc.fileService.Download(r.Context(), file, format) + } else { + + url, err = fc.fileService.DownloadNonImage(r.Context(), file, format) } - defer file.Close() - url, err := fc.fileService.Download(r.Context(), file) if err != nil { fc.responder.ErrorBadRequest(w, err, reqID) return } - fc.responder.OutputJSON(w, url, reqID) } diff --git a/internal/fileService/controller/mock.go b/internal/fileService/controller/mock.go index ad31747d..ff73012b 100644 --- a/internal/fileService/controller/mock.go +++ b/internal/fileService/controller/mock.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: controller.go +// +// Generated by this command: +// +// mockgen -destination=mock.go -source=controller.go -package=controller +// // Package controller is a generated GoMock package. package controller @@ -17,6 +22,7 @@ import ( type MockfileService struct { ctrl *gomock.Controller recorder *MockfileServiceMockRecorder + isgomock struct{} } // MockfileServiceMockRecorder is the mock recorder for MockfileService. @@ -37,18 +43,33 @@ func (m *MockfileService) EXPECT() *MockfileServiceMockRecorder { } // Download mocks base method. -func (m *MockfileService) Download(ctx context.Context, file multipart.File) (string, error) { +func (m *MockfileService) Download(ctx context.Context, file multipart.File, format string) (string, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Download", ctx, file) + ret := m.ctrl.Call(m, "Download", ctx, file, format) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } // Download indicates an expected call of Download. -func (mr *MockfileServiceMockRecorder) Download(ctx, file interface{}) *gomock.Call { +func (mr *MockfileServiceMockRecorder) Download(ctx, file, format any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Download", reflect.TypeOf((*MockfileService)(nil).Download), ctx, file) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Download", reflect.TypeOf((*MockfileService)(nil).Download), ctx, file, format) +} + +// DownloadNonImage mocks base method. +func (m *MockfileService) DownloadNonImage(ctx context.Context, file multipart.File, format string) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DownloadNonImage", ctx, file, format) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DownloadNonImage indicates an expected call of DownloadNonImage. +func (mr *MockfileServiceMockRecorder) DownloadNonImage(ctx, file, format any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadNonImage", reflect.TypeOf((*MockfileService)(nil).DownloadNonImage), ctx, file, format) } // Upload mocks base method. @@ -61,15 +82,31 @@ func (m *MockfileService) Upload(ctx context.Context, name string) ([]byte, erro } // Upload indicates an expected call of Upload. -func (mr *MockfileServiceMockRecorder) Upload(ctx, name interface{}) *gomock.Call { +func (mr *MockfileServiceMockRecorder) Upload(ctx, name any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Upload", reflect.TypeOf((*MockfileService)(nil).Upload), ctx, name) } +// UploadNonImage mocks base method. +func (m *MockfileService) UploadNonImage(ctx context.Context, name string) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UploadNonImage", ctx, name) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UploadNonImage indicates an expected call of UploadNonImage. +func (mr *MockfileServiceMockRecorder) UploadNonImage(ctx, name any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UploadNonImage", reflect.TypeOf((*MockfileService)(nil).UploadNonImage), ctx, name) +} + // Mockresponder is a mock of responder interface. type Mockresponder struct { ctrl *gomock.Controller recorder *MockresponderMockRecorder + isgomock struct{} } // MockresponderMockRecorder is the mock recorder for Mockresponder. @@ -96,7 +133,7 @@ func (m *Mockresponder) ErrorBadRequest(w http.ResponseWriter, err error, reques } // ErrorBadRequest indicates an expected call of ErrorBadRequest. -func (mr *MockresponderMockRecorder) ErrorBadRequest(w, err, requestID interface{}) *gomock.Call { +func (mr *MockresponderMockRecorder) ErrorBadRequest(w, err, requestID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ErrorBadRequest", reflect.TypeOf((*Mockresponder)(nil).ErrorBadRequest), w, err, requestID) } @@ -108,7 +145,7 @@ func (m *Mockresponder) LogError(err error, requestID string) { } // LogError indicates an expected call of LogError. -func (mr *MockresponderMockRecorder) LogError(err, requestID interface{}) *gomock.Call { +func (mr *MockresponderMockRecorder) LogError(err, requestID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogError", reflect.TypeOf((*Mockresponder)(nil).LogError), err, requestID) } @@ -120,7 +157,7 @@ func (m *Mockresponder) OutputBytes(w http.ResponseWriter, data []byte, requestI } // OutputBytes indicates an expected call of OutputBytes. -func (mr *MockresponderMockRecorder) OutputBytes(w, data, requestID interface{}) *gomock.Call { +func (mr *MockresponderMockRecorder) OutputBytes(w, data, requestID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OutputBytes", reflect.TypeOf((*Mockresponder)(nil).OutputBytes), w, data, requestID) } @@ -132,7 +169,7 @@ func (m *Mockresponder) OutputJSON(w http.ResponseWriter, data any, requestId st } // OutputJSON indicates an expected call of OutputJSON. -func (mr *MockresponderMockRecorder) OutputJSON(w, data, requestId interface{}) *gomock.Call { +func (mr *MockresponderMockRecorder) OutputJSON(w, data, requestId any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OutputJSON", reflect.TypeOf((*Mockresponder)(nil).OutputJSON), w, data, requestId) } diff --git a/internal/fileService/service/fileService.go b/internal/fileService/service/fileService.go index 6a0b7d5e..700950b3 100644 --- a/internal/fileService/service/fileService.go +++ b/internal/fileService/service/fileService.go @@ -16,14 +16,16 @@ func NewFileService() *FileService { return &FileService{} } -func (f *FileService) Download(ctx context.Context, file multipart.File) (string, error) { +func (f *FileService) Download(ctx context.Context, file multipart.File, format string) (string, error) { var ( fileName = uuid.New().String() - filePath = fmt.Sprintf("/image/%s", fileName) + filePath = fmt.Sprintf("/image/%s.%s", fileName, format) dst, err = os.Create(filePath) ) - defer dst.Close() + defer func(dst *os.File) { + _ = dst.Close() + }(dst) if err != nil { return "", fmt.Errorf("save file: %w", err) } @@ -35,6 +37,25 @@ func (f *FileService) Download(ctx context.Context, file multipart.File) (string return filePath, nil } +func (f *FileService) DownloadNonImage(ctx context.Context, file multipart.File, format string) (string, error) { + var ( + fileName = uuid.New().String() + filePath = fmt.Sprintf("/file/%s.%s", fileName, format) + dst, err = os.Create(filePath) + ) + defer func(dst *os.File) { + _ = dst.Close() + }(dst) + if err != nil { + return "", fmt.Errorf("save file: %w", err) + } + if _, err := io.Copy(dst, file); err != nil { + return "", fmt.Errorf("save file: %w", err) + } + + return filePath, nil +} + func (f *FileService) Upload(ctx context.Context, name string) ([]byte, error) { var ( file, err = os.Open(fmt.Sprintf("/image/%s", name)) @@ -42,7 +63,30 @@ func (f *FileService) Upload(ctx context.Context, name string) ([]byte, error) { sl = make([]byte, 1024) ) - defer file.Close() + defer func(file *os.File) { + _ = file.Close() + }(file) + if err != nil { + return nil, fmt.Errorf("open file: %w", err) + } + + for n, err := file.Read(sl); err != io.EOF; n, err = file.Read(sl) { + res = append(res, sl[:n]...) + } + + return res, nil +} + +func (f *FileService) UploadNonImage(ctx context.Context, name string) ([]byte, error) { + var ( + file, err = os.Open(fmt.Sprintf("/file/%s", name)) + res []byte + sl = make([]byte, 1024) + ) + + defer func(file *os.File) { + _ = file.Close() + }(file) if err != nil { return nil, fmt.Errorf("open file: %w", err) } diff --git a/internal/post/controller/controller_test.go b/internal/post/controller/controller_test.go index 4edb1345..b69c00cb 100644 --- a/internal/post/controller/controller_test.go +++ b/internal/post/controller/controller_test.go @@ -18,11 +18,12 @@ import ( func getController(ctrl *gomock.Controller) (*PostController, *mocks) { m := &mocks{ - postService: NewMockPostService(ctrl), - responder: NewMockResponder(ctrl), + postService: NewMockPostService(ctrl), + responder: NewMockResponder(ctrl), + commentService: NewMockCommentService(ctrl), } - return NewPostController(m.postService, m.responder), m + return NewPostController(m.postService, m.commentService, m.responder), m } func TestNewPostController(t *testing.T) { @@ -53,19 +54,23 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "2", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() res := &Request{r: req, w: w} return res, nil @@ -81,19 +86,23 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "3", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -111,19 +120,23 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Create(gomock.Any(), gomock.Any()).Return(uint32(0), errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "4", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -141,19 +154,23 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Create(gomock.Any(), gomock.Any()).Return(uint32(2), nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "5", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=ljkhkg", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=ljkhkg", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -170,19 +187,23 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "6", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -200,19 +221,23 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(false) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "7", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -230,20 +255,26 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) - m.postService.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any()).Return(uint32(0), errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any()).Return( + uint32(0), errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "8", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -262,19 +293,23 @@ func TestCreate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.postService.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any()).Return(uint32(10), nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "9", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=10", + bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -291,42 +326,46 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -351,12 +390,14 @@ func TestGetOne(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -379,12 +420,14 @@ func TestGetOne(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -409,12 +452,14 @@ func TestGetOne(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, my_err.ErrPostNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -439,12 +484,14 @@ func TestGetOne(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -469,12 +516,14 @@ func TestGetOne(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -497,42 +546,46 @@ func TestGetOne(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -556,12 +609,14 @@ func TestUpdate(t *testing.T) { }, ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -584,12 +639,14 @@ func TestUpdate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -613,13 +670,17 @@ func TestUpdate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(0), errors.New("error")) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return( + uint32(0), errors.New("error"), + ) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -644,19 +705,23 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(10), nil) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "5", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -676,19 +741,23 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(my_err.ErrPostNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "6", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -708,19 +777,23 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "7", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -740,19 +813,23 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "8", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=nkljbkvhj", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=nkljbkvhj", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -770,19 +847,23 @@ func TestUpdate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "9", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -801,19 +882,23 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(false) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "10", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -833,19 +918,23 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "11", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=10", - bytes.NewBuffer([]byte(`{"id"`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=10", + bytes.NewBuffer([]byte(`{"id"`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -864,19 +953,23 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "12", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=1", - bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=1", + bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -895,42 +988,46 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -955,12 +1052,14 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -983,12 +1082,14 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1014,12 +1115,14 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(my_err.ErrPostNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1045,12 +1148,14 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1076,12 +1181,14 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1105,12 +1212,14 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, error, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, error, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1133,12 +1242,14 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, error, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, error, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1164,42 +1275,46 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, error, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, error, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1224,12 +1339,14 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1251,12 +1368,14 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1279,10 +1398,14 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, my_err.ErrNoMoreContent) - m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do(func(w, req any) { - request.w.WriteHeader(http.StatusNoContent) - }) + m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, my_err.ErrNoMoreContent, + ) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) }, }, { @@ -1305,13 +1428,17 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1335,12 +1462,14 @@ func TestGetBatchPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1362,12 +1491,14 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1392,12 +1523,14 @@ func TestGetBatchPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetBatchFromFriend(gomock.Any(), gomock.Any(), gomock.Any()). Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1420,12 +1553,14 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1448,13 +1583,17 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.postService.EXPECT().GetCommunityPost(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().GetCommunityPost( + gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), + ).Return(nil, nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1477,42 +1616,46 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1537,12 +1680,14 @@ func TestSetLikeOnPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1565,12 +1710,14 @@ func TestSetLikeOnPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1595,12 +1742,14 @@ func TestSetLikeOnPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1624,13 +1773,17 @@ func TestSetLikeOnPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return( + false, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1655,13 +1808,17 @@ func TestSetLikeOnPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, nil) - m.postService.EXPECT().SetLikeToPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().SetLikeToPost( + gomock.Any(), gomock.Any(), gomock.Any(), + ).Return(errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1687,42 +1844,46 @@ func TestSetLikeOnPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, nil) m.postService.EXPECT().SetLikeToPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1747,12 +1908,14 @@ func TestDeleteLikeFromPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1775,12 +1938,14 @@ func TestDeleteLikeFromPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1805,12 +1970,14 @@ func TestDeleteLikeFromPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, nil) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1834,13 +2001,17 @@ func TestDeleteLikeFromPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return( + false, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1865,13 +2036,17 @@ func TestDeleteLikeFromPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) - m.postService.EXPECT().DeleteLikeFromPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().DeleteLikeFromPost( + gomock.Any(), gomock.Any(), gomock.Any(), + ).Return(errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1897,48 +2072,53 @@ func TestDeleteLikeFromPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) m.postService.EXPECT().DeleteLikeFromPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } type mocks struct { - postService *MockPostService - responder *MockResponder + postService *MockPostService + responder *MockResponder + commentService *MockCommentService } type Request struct { diff --git a/internal/router/file/router.go b/internal/router/file/router.go index c5ae529a..4337e9a3 100644 --- a/internal/router/file/router.go +++ b/internal/router/file/router.go @@ -21,6 +21,7 @@ type SessionManager interface { type FileController interface { Upload(w http.ResponseWriter, r *http.Request) Download(w http.ResponseWriter, r *http.Request) + UploadNonImage(w http.ResponseWriter, r *http.Request) } func NewRouter( @@ -30,6 +31,7 @@ func NewRouter( router.HandleFunc("/image/{name}", fc.Upload).Methods(http.MethodGet, http.MethodOptions) router.HandleFunc("/image", fc.Download).Methods(http.MethodPost, http.MethodOptions) + router.HandleFunc("/file/{name}", fc.UploadNonImage).Methods(http.MethodGet, http.MethodOptions) router.Handle("/api/v1/metrics", promhttp.Handler()) diff --git a/internal/router/file/router_test.go b/internal/router/file/router_test.go index 6af2200b..1d88b5c0 100644 --- a/internal/router/file/router_test.go +++ b/internal/router/file/router_test.go @@ -27,6 +27,8 @@ func (m mockSessionManager) Destroy(sess *models.Session) error { type mockFileController struct{} +func (m mockFileController) UploadNonImage(w http.ResponseWriter, r *http.Request) {} + func (m mockFileController) Upload(w http.ResponseWriter, r *http.Request) {} func (m mockFileController) Download(w http.ResponseWriter, r *http.Request) {} From 6930c71b05e7381e1e2b879a093616184ae6d895 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Wed, 11 Dec 2024 14:59:25 +0300 Subject: [PATCH 044/135] return test for comment --- internal/post/controller/controller_test.go | 886 ++++++++++++++++++++ 1 file changed, 886 insertions(+) diff --git a/internal/post/controller/controller_test.go b/internal/post/controller/controller_test.go index b69c00cb..43eaeeab 100644 --- a/internal/post/controller/controller_test.go +++ b/internal/post/controller/controller_test.go @@ -2115,6 +2115,892 @@ func TestDeleteLikeFromPost(t *testing.T) { } } +func TestComment(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/api/v1/feed/2", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/api/v1/feed/2", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/api/v1/feed/2", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "4", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/api/v1/feed/2", bytes.NewBuffer([]byte(`{"id":1}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusInternalServerError, Body: "error"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().Comment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + _, _ = request.w.Write([]byte("error")) + }, + ) + }, + }, + { + name: "5", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/api/v1/feed/2", bytes.NewBuffer([]byte(`{"id":1}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().Comment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return( + &models.Comment{ + Content: models.Content{ + Text: "New comment", + }, + }, nil, + ) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + _, _ = request.w.Write([]byte("OK")) + }, + ) + }, + }, + { + name: "6", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed/2", + bytes.NewBuffer([]byte(`{"file":"очень большой текст, написанный в поле файл, как он сюда попал - честно говоря хз, надо проверить валидацию на файл длину"}`)), + ) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + } + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestGetComment(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/feed/2/comment", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.GetComments(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/feed/2/comment?id=fnf", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.GetComments(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/feed/2/comment?id=4", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.GetComments(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusInternalServerError, Body: "error"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + _, _ = request.w.Write([]byte("error")) + }, + ) + }, + }, + { + name: "4", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/feed/2/comment?sort=old", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.GetComments(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + _, _ = request.w.Write([]byte("OK")) + }, + ) + }, + }, + { + name: "5", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/feed/2/comment", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.GetComments(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusNoContent}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, my_err.ErrNoMoreContent) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestEditComment(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "4", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", bytes.NewBuffer([]byte(`{"text":"1"}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().EditComment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(my_err.ErrAccessDenied) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "5", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", bytes.NewBuffer([]byte(`{"text":"1"}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().EditComment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(my_err.ErrWrongComment) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "6", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", bytes.NewBuffer([]byte(`{"text":"1"}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusInternalServerError, Body: "error"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().EditComment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(errors.New("err")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + _, _ = request.w.Write([]byte("error")) + }, + ) + }, + }, + { + name: "7", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", bytes.NewBuffer([]byte(`{"text":"1"}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().EditComment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + _, _ = request.w.Write([]byte("OK")) + }, + ) + }, + }, + { + name: "8", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/2/1", + bytes.NewBuffer([]byte(`{"file":"очень большой текст, написанный в поле файл, как он сюда попал - честно говоря хз, надо проверить валидацию на файл длину"}`)), + ) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestDeleteComment(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().DeleteComment(gomock.Any(), gomock.Any(), gomock.Any()). + Return(my_err.ErrAccessDenied) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "4", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().DeleteComment(gomock.Any(), gomock.Any(), gomock.Any()). + Return(my_err.ErrWrongComment) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "5", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusInternalServerError, Body: "error"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().DeleteComment(gomock.Any(), gomock.Any(), gomock.Any()). + Return(errors.New("err")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + _, _ = request.w.Write([]byte("error")) + }, + ) + }, + }, + { + name: "6", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().DeleteComment(gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + _, _ = request.w.Write([]byte("OK")) + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + type mocks struct { postService *MockPostService responder *MockResponder From 457e70cb85bd9975f938ff5a5ff05465b9cff20b Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Thu, 12 Dec 2024 14:39:30 +0300 Subject: [PATCH 045/135] Update go.yml --- .github/workflows/go.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 54acfbf6..a0741bb1 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -6,6 +6,8 @@ name: Go on: push: branches: [ "dev" ] + pull_request: + branches: [ "dev" ] jobs: From dde7f581e58a08bc96da0b09cdbe6b19ee33cccc Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 12 Dec 2024 15:13:07 +0300 Subject: [PATCH 046/135] bugfix --- docker-compose.yml | 1 + internal/fileService/service/fileService.go | 4 +- internal/middleware/fileMetrics.go | 64 +++++++++++---------- internal/router/file/router.go | 2 +- 4 files changed, 39 insertions(+), 32 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 97d62812..5d07c916 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -62,6 +62,7 @@ services: dockerfile: Dockerfilefile volumes: - ./image:/image + - ./files:/files restart: always ports: - "8083:8083" diff --git a/internal/fileService/service/fileService.go b/internal/fileService/service/fileService.go index 700950b3..2b26d7d8 100644 --- a/internal/fileService/service/fileService.go +++ b/internal/fileService/service/fileService.go @@ -40,7 +40,7 @@ func (f *FileService) Download(ctx context.Context, file multipart.File, format func (f *FileService) DownloadNonImage(ctx context.Context, file multipart.File, format string) (string, error) { var ( fileName = uuid.New().String() - filePath = fmt.Sprintf("/file/%s.%s", fileName, format) + filePath = fmt.Sprintf("/files/%s.%s", fileName, format) dst, err = os.Create(filePath) ) defer func(dst *os.File) { @@ -79,7 +79,7 @@ func (f *FileService) Upload(ctx context.Context, name string) ([]byte, error) { func (f *FileService) UploadNonImage(ctx context.Context, name string) ([]byte, error) { var ( - file, err = os.Open(fmt.Sprintf("/file/%s", name)) + file, err = os.Open(fmt.Sprintf("/files/%s", name)) res []byte sl = make([]byte, 1024) ) diff --git a/internal/middleware/fileMetrics.go b/internal/middleware/fileMetrics.go index 9a55a646..315d47ad 100644 --- a/internal/middleware/fileMetrics.go +++ b/internal/middleware/fileMetrics.go @@ -41,35 +41,41 @@ func (rw *fileResponseWriter) Write(b []byte) (int, error) { } func FileMetricsMiddleware(metr *metrics.FileMetrics, next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - start := time.Now() - respWithCode := NewFileResponseWriter(w) - next.ServeHTTP(respWithCode, r) - statusCode := respWithCode.statusCode - path := r.URL.Path - method := r.Method - var ( - err error - format string - size int64 - ) - if r.Method == http.MethodPost { - format, size, err = getFormatAndSize(r) - } else if r.Method == http.MethodGet { - file := respWithCode.file - format = http.DetectContentType(file[:512]) - size = int64(len(file)) - } - if err != nil { - format = "error" - size = 0 - } - if statusCode != http.StatusOK && statusCode != http.StatusNoContent { - metr.IncErrors(path, strconv.Itoa(statusCode), method, format, size) - } - metr.IncHits(path, strconv.Itoa(statusCode), method, format, size) - metr.ObserveTiming(path, strconv.Itoa(statusCode), method, format, size, time.Since(start).Seconds()) - }) + return http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + start := time.Now() + respWithCode := NewFileResponseWriter(w) + next.ServeHTTP(respWithCode, r) + statusCode := respWithCode.statusCode + path := r.URL.Path + method := r.Method + var ( + err error + format string + size int64 + ) + if r.Method == http.MethodPost { + format, size, err = getFormatAndSize(r) + } else if r.Method == http.MethodGet { + file := respWithCode.file + size = int64(len(file)) + if size <= 512 { + format = http.DetectContentType(file[:size]) + } else { + format = http.DetectContentType(file[:512]) + } + } + if err != nil { + format = "error" + size = 0 + } + if statusCode != http.StatusOK && statusCode != http.StatusNoContent { + metr.IncErrors(path, strconv.Itoa(statusCode), method, format, size) + } + metr.IncHits(path, strconv.Itoa(statusCode), method, format, size) + metr.ObserveTiming(path, strconv.Itoa(statusCode), method, format, size, time.Since(start).Seconds()) + }, + ) } func getFormatAndSize(r *http.Request) (string, int64, error) { diff --git a/internal/router/file/router.go b/internal/router/file/router.go index 4337e9a3..3beebf22 100644 --- a/internal/router/file/router.go +++ b/internal/router/file/router.go @@ -31,7 +31,7 @@ func NewRouter( router.HandleFunc("/image/{name}", fc.Upload).Methods(http.MethodGet, http.MethodOptions) router.HandleFunc("/image", fc.Download).Methods(http.MethodPost, http.MethodOptions) - router.HandleFunc("/file/{name}", fc.UploadNonImage).Methods(http.MethodGet, http.MethodOptions) + router.HandleFunc("/files/{name}", fc.UploadNonImage).Methods(http.MethodGet, http.MethodOptions) router.Handle("/api/v1/metrics", promhttp.Handler()) From 8f3656c35c3e5fb6bac5f6cd282eaa76a585c3b2 Mon Sep 17 00:00:00 2001 From: slashlight Date: Thu, 12 Dec 2024 15:27:41 +0300 Subject: [PATCH 047/135] feat: added stickers microservice --- DB/migrations/000001_init_schema.up.sql | 6 ++ cmd/stickers/main.go | 29 ++++++ internal/app/stickers/app.go | 63 +++++++++++ internal/config/config.go | 6 ++ internal/router/stickers/router.go | 37 +++++++ internal/stickers/controller/controller.go | 110 ++++++++++++++++++++ internal/stickers/repository.go | 13 +++ internal/stickers/repository/QueryConsts.go | 7 ++ internal/stickers/repository/postgres.go | 73 +++++++++++++ internal/stickers/service/usecase.go | 40 +++++++ internal/stickers/sticker_controller.go | 11 ++ internal/stickers/sticker_usecase.go | 13 +++ pkg/my_err/error.go | 1 + 13 files changed, 409 insertions(+) create mode 100644 cmd/stickers/main.go create mode 100644 internal/app/stickers/app.go create mode 100644 internal/router/stickers/router.go create mode 100644 internal/stickers/controller/controller.go create mode 100644 internal/stickers/repository.go create mode 100644 internal/stickers/repository/QueryConsts.go create mode 100644 internal/stickers/repository/postgres.go create mode 100644 internal/stickers/service/usecase.go create mode 100644 internal/stickers/sticker_controller.go create mode 100644 internal/stickers/sticker_usecase.go diff --git a/DB/migrations/000001_init_schema.up.sql b/DB/migrations/000001_init_schema.up.sql index a1094117..18964dd1 100644 --- a/DB/migrations/000001_init_schema.up.sql +++ b/DB/migrations/000001_init_schema.up.sql @@ -80,6 +80,12 @@ CREATE TABLE IF NOT EXISTS reaction ( updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); +CREATE TABLE IF NOT EXISTS sticker ( + id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + file_path TEXT CONSTRAINT file_path_length CHECK (CHAR_LENGTH(file_path) <= 100) DEFAULT '', + profile_id INT REFERENCES profile(id) +); + ALTER TABLE friend ADD FOREIGN KEY ("sender") REFERENCES profile(id) ON DELETE CASCADE, ADD FOREIGN KEY ("receiver") REFERENCES profile(id) ON DELETE CASCADE ; diff --git a/cmd/stickers/main.go b/cmd/stickers/main.go new file mode 100644 index 00000000..b03eb4af --- /dev/null +++ b/cmd/stickers/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "flag" + "log" + + "github.com/2024_2_BetterCallFirewall/internal/app/stickers" + "github.com/2024_2_BetterCallFirewall/internal/config" +) + +func main() { + confPath := flag.String("c", ".env", "path to config file") + flag.Parse() + + cfg, err := config.GetConfig(*confPath) + if err != nil { + panic(err) + } + + server, err := stickers.GetHTTPServer(cfg) + if err != nil { + panic(err) + } + + log.Printf("Starting server on posrt %s", cfg.STCIKER.Port) + if err := server.ListenAndServe(); err != nil { + panic(err) + } +} diff --git a/internal/app/stickers/app.go b/internal/app/stickers/app.go new file mode 100644 index 00000000..edcf9334 --- /dev/null +++ b/internal/app/stickers/app.go @@ -0,0 +1,63 @@ +package stickers + +import ( + "fmt" + "net/http" + + "github.com/sirupsen/logrus" + + "github.com/2024_2_BetterCallFirewall/internal/config" + "github.com/2024_2_BetterCallFirewall/internal/ext_grpc" + "github.com/2024_2_BetterCallFirewall/internal/ext_grpc/adapter/auth" + "github.com/2024_2_BetterCallFirewall/internal/router" + "github.com/2024_2_BetterCallFirewall/internal/router/stickers" + controller "github.com/2024_2_BetterCallFirewall/internal/stickers/controller" + repository "github.com/2024_2_BetterCallFirewall/internal/stickers/repository" + service "github.com/2024_2_BetterCallFirewall/internal/stickers/service" + "github.com/2024_2_BetterCallFirewall/pkg/start_postgres" +) + +func GetHTTPServer(cfg *config.Config) (*http.Server, error) { + logger := logrus.New() + logger.Formatter = &logrus.TextFormatter{ + FullTimestamp: true, + DisableColors: false, + TimestampFormat: "2006-01-02 15:04:05", + ForceColors: true, + } + + connStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s", + cfg.DB.Host, + cfg.DB.Port, + cfg.DB.User, + cfg.DB.Pass, + cfg.DB.DBName, + cfg.DB.SSLMode, + ) + + postgresDB, err := start_postgres.StartPostgres(connStr, logger) + if err != nil { + return nil, err + } + + responder := router.NewResponder(logger) + provider, err := ext_grpc.GetGRPCProvider(cfg.AUTHGRPC.Host, cfg.AUTHGRPC.Port) + if err != nil { + return nil, err + } + sm := auth.New(provider) + + repo := repository.NewStickerRepo(postgresDB) + stickerService := service.NewStickerUsecase(repo) + stickerController := controller.NewStickerController(stickerService, responder) + + rout := stickers.NewRouter(stickerController, sm, logger) + server := &http.Server{ + Handler: rout, + Addr: fmt.Sprintf(":%s", cfg.STCIKER.Port), + ReadTimeout: cfg.STCIKER.ReadTimeout, + WriteTimeout: cfg.STCIKER.WriteTimeout, + } + + return server, nil +} diff --git a/internal/config/config.go b/internal/config/config.go index 2170e24f..798a156b 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -45,6 +45,7 @@ type Config struct { POST Server PROFILE Server COMMUNITY Server + STCIKER Server AUTHGRPC GRPCServer PROFILEGRPC GRPCServer POSTGRPC GRPCServer @@ -101,6 +102,11 @@ func GetConfig(configFilePath string) (*Config, error) { ReadTimeout: time.Duration(getIntEnv("SERVER_READ_TIMEOUT")) * time.Second, WriteTimeout: time.Duration(getIntEnv("SERVER_WRITE_TIMEOUT")) * time.Second, }, + STCIKER: Server{ + Port: os.Getenv("STCIKER_HTTP_PORT"), + ReadTimeout: time.Duration(getIntEnv("SERVER_READ_TIMEOUT")) * time.Second, + WriteTimeout: time.Duration(getIntEnv("SERVER_WRITE_TIMEOUT")) * time.Second, + }, PROFILEGRPC: GRPCServer{ Port: os.Getenv("PROFILE_GRPC_PORT"), Host: os.Getenv("PROFILE_GRPC_HOST"), diff --git a/internal/router/stickers/router.go b/internal/router/stickers/router.go new file mode 100644 index 00000000..3180fb79 --- /dev/null +++ b/internal/router/stickers/router.go @@ -0,0 +1,37 @@ +package stickers + +import ( + "net/http" + + "github.com/gorilla/mux" + "github.com/sirupsen/logrus" + + "github.com/2024_2_BetterCallFirewall/internal/middleware" + "github.com/2024_2_BetterCallFirewall/internal/models" +) + +type Controller interface { + AddNewSticker(w http.ResponseWriter, r *http.Request) + GetAllStickers(w http.ResponseWriter, r *http.Request) + GetMineStickers(w http.ResponseWriter, r *http.Request) +} + +type SessionManager interface { + Check(string) (*models.Session, error) + Create(userID uint32) (*models.Session, error) + Destroy(sess *models.Session) error +} + +func NewRouter(controller Controller, sm SessionManager, logger *logrus.Logger) http.Handler { + router := mux.NewRouter() + + router.HandleFunc("/api/v1/stickers/all", controller.GetAllStickers).Methods(http.MethodGet, http.MethodOptions) + router.HandleFunc("/api/v1/stickers", controller.AddNewSticker).Methods(http.MethodPost, http.MethodOptions) + router.HandleFunc("/api/v1/stickers", controller.GetMineStickers).Methods(http.MethodGet, http.MethodOptions) + + res := middleware.Auth(sm, router) + res = middleware.Preflite(res) + res = middleware.AccessLog(logger, res) + + return res +} diff --git a/internal/stickers/controller/controller.go b/internal/stickers/controller/controller.go new file mode 100644 index 00000000..b6560451 --- /dev/null +++ b/internal/stickers/controller/controller.go @@ -0,0 +1,110 @@ +package controller + +import ( + "errors" + "net/http" + + "github.com/2024_2_BetterCallFirewall/internal/models" + "github.com/2024_2_BetterCallFirewall/internal/stickers" + "github.com/2024_2_BetterCallFirewall/pkg/my_err" +) + +type Responder interface { + OutputJSON(w http.ResponseWriter, data any, requestID string) + OutputNoMoreContentJSON(w http.ResponseWriter, requestID string) + + ErrorBadRequest(w http.ResponseWriter, err error, requestID string) + ErrorInternal(w http.ResponseWriter, err error, requestID string) + LogError(err error, requestID string) +} + +type StickersHandlerImplementation struct { + StickersManager stickers.Usecase + Responder Responder +} + +func NewStickerController(manager stickers.Usecase, responder Responder) *StickersHandlerImplementation { + return &StickersHandlerImplementation{ + StickersManager: manager, + Responder: responder, + } +} + +func (s StickersHandlerImplementation) AddNewSticker(w http.ResponseWriter, r *http.Request) { + var ( + reqID, ok = r.Context().Value("requestID").(string) + ) + + if !ok { + s.Responder.LogError(my_err.ErrInvalidContext, "") + } + + filePath := r.URL.Query().Get("file_path") + if filePath == "" { + s.Responder.ErrorBadRequest(w, my_err.ErrInvalidQuery, reqID) + return + } + + sess, err := models.SessionFromContext(r.Context()) + if err != nil { + s.Responder.ErrorInternal(w, err, reqID) + return + } + + err = s.StickersManager.AddNewSticker(r.Context(), filePath, sess.UserID) + if err != nil { + s.Responder.ErrorInternal(w, err, reqID) + return + } + + s.Responder.OutputJSON(w, "New sticker is added", reqID) + return +} + +func (s StickersHandlerImplementation) GetAllStickers(w http.ResponseWriter, r *http.Request) { + var ( + reqID, ok = r.Context().Value("requestID").(string) + ) + + if !ok { + s.Responder.LogError(my_err.ErrInvalidContext, "") + } + + res, err := s.StickersManager.GetAllStickers(r.Context()) + if err != nil { + if errors.Is(err, my_err.ErrNoStickers) { + s.Responder.OutputNoMoreContentJSON(w, reqID) + return + } + s.Responder.ErrorInternal(w, err, reqID) + } + + s.Responder.OutputJSON(w, res, reqID) +} + +func (s StickersHandlerImplementation) GetMineStickers(w http.ResponseWriter, r *http.Request) { + var ( + reqID, ok = r.Context().Value("requestID").(string) + ) + + if !ok { + s.Responder.LogError(my_err.ErrInvalidContext, "") + } + + sess, err := models.SessionFromContext(r.Context()) + if err != nil { + s.Responder.ErrorInternal(w, err, reqID) + return + } + + res, err := s.StickersManager.GetMineStickers(r.Context(), sess.UserID) + if err != nil { + if errors.Is(err, my_err.ErrNoStickers) { + s.Responder.OutputNoMoreContentJSON(w, reqID) + return + } + s.Responder.ErrorInternal(w, err, reqID) + } + + s.Responder.OutputJSON(w, res, reqID) +} diff --git a/internal/stickers/repository.go b/internal/stickers/repository.go new file mode 100644 index 00000000..d1f10877 --- /dev/null +++ b/internal/stickers/repository.go @@ -0,0 +1,13 @@ +package stickers + +import ( + "context" + + "github.com/2024_2_BetterCallFirewall/internal/models" +) + +type Repository interface { + AddNewSticker(ctx context.Context, filepath string, userID uint32) error + GetAllStickers(ctx context.Context) ([]*models.Picture, error) + GetMineStickers(ctx context.Context, userID uint32) ([]*models.Picture, error) +} diff --git a/internal/stickers/repository/QueryConsts.go b/internal/stickers/repository/QueryConsts.go new file mode 100644 index 00000000..8ea9f2fc --- /dev/null +++ b/internal/stickers/repository/QueryConsts.go @@ -0,0 +1,7 @@ +package repository + +const ( + InsertNewSticker = `INSERT INTO sticker(file_path, profile_id) VALUES ($1, $2)` + GetAllSticker = `SELECT file_path FROM sticker` + GetUserStickers = `SELECT file_path FROM sticker WHERE user_id = $1` +) diff --git a/internal/stickers/repository/postgres.go b/internal/stickers/repository/postgres.go new file mode 100644 index 00000000..829834a2 --- /dev/null +++ b/internal/stickers/repository/postgres.go @@ -0,0 +1,73 @@ +package repository + +import ( + "context" + "database/sql" + "errors" + + "github.com/2024_2_BetterCallFirewall/internal/models" + "github.com/2024_2_BetterCallFirewall/pkg/my_err" +) + +type StickerRepo struct { + DB *sql.DB +} + +func NewStickerRepo(db *sql.DB) *StickerRepo { + repo := &StickerRepo{ + DB: db, + } + return repo +} + +func (s StickerRepo) AddNewSticker(ctx context.Context, filepath string, userID uint32) error { + _, err := s.DB.ExecContext(ctx, InsertNewSticker, filepath, userID) + if err != nil { + return err + } + return nil +} + +func (s StickerRepo) GetAllStickers(ctx context.Context) ([]*models.Picture, error) { + rows, err := s.DB.QueryContext(ctx, GetAllSticker) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, my_err.ErrNoStickers + } + return nil, err + } + defer rows.Close() + var res []*models.Picture + for rows.Next() { + var pic models.Picture + err = rows.Scan(&pic) + if err != nil { + return nil, err + } + res = append(res, &pic) + } + + return res, nil +} + +func (s StickerRepo) GetMineStickers(ctx context.Context, userID uint32) ([]*models.Picture, error) { + rows, err := s.DB.QueryContext(ctx, GetUserStickers, userID) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, my_err.ErrNoStickers + } + return nil, err + } + defer rows.Close() + var res []*models.Picture + for rows.Next() { + var pic models.Picture + err = rows.Scan(&pic) + if err != nil { + return nil, err + } + res = append(res, &pic) + } + + return res, nil +} diff --git a/internal/stickers/service/usecase.go b/internal/stickers/service/usecase.go new file mode 100644 index 00000000..e4891e6b --- /dev/null +++ b/internal/stickers/service/usecase.go @@ -0,0 +1,40 @@ +package service + +import ( + "context" + + "github.com/2024_2_BetterCallFirewall/internal/models" + "github.com/2024_2_BetterCallFirewall/internal/stickers" +) + +type StickerUsecaseImplementation struct { + repo stickers.Repository +} + +func NewStickerUsecase(stickerRepo stickers.Repository) *StickerUsecaseImplementation { + return &StickerUsecaseImplementation{repo: stickerRepo} +} + +func (s StickerUsecaseImplementation) AddNewSticker(ctx context.Context, filepath string, userID uint32) error { + err := s.repo.AddNewSticker(ctx, filepath, userID) + if err != nil { + return err + } + return nil +} + +func (s StickerUsecaseImplementation) GetAllStickers(ctx context.Context) ([]*models.Picture, error) { + res, err := s.repo.GetAllStickers(ctx) + if err != nil { + return nil, err + } + return res, nil +} + +func (s StickerUsecaseImplementation) GetMineStickers(ctx context.Context, userID uint32) ([]*models.Picture, error) { + res, err := s.repo.GetMineStickers(ctx, userID) + if err != nil { + return nil, err + } + return res, nil +} diff --git a/internal/stickers/sticker_controller.go b/internal/stickers/sticker_controller.go new file mode 100644 index 00000000..c722c7d2 --- /dev/null +++ b/internal/stickers/sticker_controller.go @@ -0,0 +1,11 @@ +package stickers + +import ( + "net/http" +) + +type Controller interface { + AddNewSticker(w http.ResponseWriter, r *http.Request) + GetAllStickers(w http.ResponseWriter, r *http.Request) + GetMineStickers(w http.ResponseWriter, r *http.Request) +} diff --git a/internal/stickers/sticker_usecase.go b/internal/stickers/sticker_usecase.go new file mode 100644 index 00000000..315e6939 --- /dev/null +++ b/internal/stickers/sticker_usecase.go @@ -0,0 +1,13 @@ +package stickers + +import ( + "context" + + "github.com/2024_2_BetterCallFirewall/internal/models" +) + +type Usecase interface { + AddNewSticker(ctx context.Context, filepath string, userID uint32) error + GetAllStickers(ctx context.Context) ([]*models.Picture, error) + GetMineStickers(ctx context.Context, userID uint32) ([]*models.Picture, error) +} diff --git a/pkg/my_err/error.go b/pkg/my_err/error.go index c4bad589..0004aa74 100644 --- a/pkg/my_err/error.go +++ b/pkg/my_err/error.go @@ -35,4 +35,5 @@ var ( ErrWrongPost = errors.New("wrong post") ErrTextTooLong = errors.New("text len is too big") ErrWrongComment = errors.New("wrong comment") + ErrNoStickers = errors.New("no stickers found") ) From 1c1138c469e8db7e0b95d5f64f01214f8b188e36 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 12 Dec 2024 17:28:43 +0300 Subject: [PATCH 048/135] bugfix: requestID key --- internal/auth/controller/controller.go | 15 ++++++--- internal/chat/controller/controller.go | 7 ++-- internal/community/controller/controller.go | 19 ++++++----- internal/fileService/controller/controller.go | 5 +-- internal/middleware/accesslog.go | 21 +++++++----- internal/post/controller/controller.go | 23 ++++++------- internal/profile/controller/controller.go | 33 ++++++++++--------- 7 files changed, 69 insertions(+), 54 deletions(-) diff --git a/internal/auth/controller/controller.go b/internal/auth/controller/controller.go index 18cb4777..60eceb25 100644 --- a/internal/auth/controller/controller.go +++ b/internal/auth/controller/controller.go @@ -11,6 +11,7 @@ import ( "golang.org/x/crypto/bcrypt" "github.com/2024_2_BetterCallFirewall/internal/auth" + "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/pkg/my_err" @@ -35,7 +36,9 @@ type AuthController struct { SessionManager auth.SessionManager } -func NewAuthController(responder Responder, serviceAuth AuthService, sessionManager auth.SessionManager) *AuthController { +func NewAuthController( + responder Responder, serviceAuth AuthService, sessionManager auth.SessionManager, +) *AuthController { return &AuthController{ responder: responder, serviceAuth: serviceAuth, @@ -44,7 +47,7 @@ func NewAuthController(responder Responder, serviceAuth AuthService, sessionMana } func (c *AuthController) Register(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -57,7 +60,9 @@ func (c *AuthController) Register(w http.ResponseWriter, r *http.Request) { } user.ID, err = c.serviceAuth.Register(user, r.Context()) - if errors.Is(err, my_err.ErrUserAlreadyExists) || errors.Is(err, my_err.ErrNonValidEmail) || errors.Is(err, bcrypt.ErrPasswordTooLong) { + if errors.Is(err, my_err.ErrUserAlreadyExists) || errors.Is(err, my_err.ErrNonValidEmail) || errors.Is( + err, bcrypt.ErrPasswordTooLong, + ) { c.responder.ErrorBadRequest(w, err, reqID) return } @@ -87,7 +92,7 @@ func (c *AuthController) Register(w http.ResponseWriter, r *http.Request) { } func (c *AuthController) Auth(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -129,7 +134,7 @@ func (c *AuthController) Auth(w http.ResponseWriter, r *http.Request) { } func (c *AuthController) Logout(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } diff --git a/internal/chat/controller/controller.go b/internal/chat/controller/controller.go index 4cb7220c..efd28ede 100644 --- a/internal/chat/controller/controller.go +++ b/internal/chat/controller/controller.go @@ -12,6 +12,7 @@ import ( "github.com/gorilla/websocket" "github.com/2024_2_BetterCallFirewall/internal/chat" + "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/pkg/my_err" ) @@ -55,7 +56,7 @@ var ( ) func (cc *ChatController) SetConnection(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { cc.responder.LogError(my_err.ErrInvalidContext, "") return @@ -107,7 +108,7 @@ func (cc *ChatController) SendChatMsg(ctx context.Context, reqID string) { func (cc *ChatController) GetAllChats(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) lastTimeQuery = r.URL.Query().Get("lastTime") lastTime time.Time err error @@ -166,7 +167,7 @@ func GetIdFromURL(r *http.Request) (uint32, error) { func (cc *ChatController) GetChat(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) lastTimeQuery = r.URL.Query().Get("lastTime") lastTime time.Time err error diff --git a/internal/community/controller/controller.go b/internal/community/controller/controller.go index aaf0cf6f..82e178cb 100644 --- a/internal/community/controller/controller.go +++ b/internal/community/controller/controller.go @@ -10,6 +10,7 @@ import ( "github.com/gorilla/mux" + "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/pkg/my_err" ) @@ -50,7 +51,7 @@ func NewCommunityController(responder responder, service communityService) *Cont } func (c *Controller) GetOne(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -78,7 +79,7 @@ func (c *Controller) GetOne(w http.ResponseWriter, r *http.Request) { func (c *Controller) GetAll(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) lastID = r.URL.Query().Get("id") intLastID uint64 err error @@ -119,7 +120,7 @@ func (c *Controller) GetAll(w http.ResponseWriter, r *http.Request) { } func (c *Controller) Update(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -157,7 +158,7 @@ func (c *Controller) Update(w http.ResponseWriter, r *http.Request) { } func (c *Controller) Delete(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -189,7 +190,7 @@ func (c *Controller) Delete(w http.ResponseWriter, r *http.Request) { } func (c *Controller) Create(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -216,7 +217,7 @@ func (c *Controller) Create(w http.ResponseWriter, r *http.Request) { } func (c *Controller) JoinToCommunity(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -243,7 +244,7 @@ func (c *Controller) JoinToCommunity(w http.ResponseWriter, r *http.Request) { } func (c *Controller) LeaveFromCommunity(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -270,7 +271,7 @@ func (c *Controller) LeaveFromCommunity(w http.ResponseWriter, r *http.Request) } func (c *Controller) AddAdmin(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -314,7 +315,7 @@ func (c *Controller) AddAdmin(w http.ResponseWriter, r *http.Request) { func (c *Controller) SearchCommunity(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) subStr = r.URL.Query().Get("q") lastID = r.URL.Query().Get("id") id uint64 diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index 6cba831b..6c6af14f 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -9,6 +9,7 @@ import ( "github.com/gorilla/mux" + "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/pkg/my_err" ) @@ -47,7 +48,7 @@ func NewFileController(fileService fileService, responder responder) *FileContro func (fc *FileController) Upload(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) vars = mux.Vars(r) name = vars["name"] ) @@ -71,7 +72,7 @@ func (fc *FileController) Upload(w http.ResponseWriter, r *http.Request) { } func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { fc.responder.LogError(my_err.ErrInvalidContext, "") } diff --git a/internal/middleware/accesslog.go b/internal/middleware/accesslog.go index fce8b070..9da97f26 100644 --- a/internal/middleware/accesslog.go +++ b/internal/middleware/accesslog.go @@ -11,14 +11,19 @@ import ( type requestID string -var requestKey requestID = "requestID" +var RequestKey requestID = "requestID" func AccessLog(logger *log.Logger, next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - id := uuid.New().String() - ctx := context.WithValue(r.Context(), requestKey, id) - start := time.Now() - next.ServeHTTP(w, r.WithContext(ctx)) - logger.Infof("New request:%s\n \tMethod: %v\n\tRemote addr: %v\n\tURL: %v\n\tTime: %v", id, r.Method, r.RemoteAddr, r.URL.String(), time.Since(start)) - }) + return http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + id := uuid.New().String() + ctx := context.WithValue(r.Context(), RequestKey, id) + start := time.Now() + next.ServeHTTP(w, r.WithContext(ctx)) + logger.Infof( + "New request:%s\n \tMethod: %v\n\tRemote addr: %v\n\tURL: %v\n\tTime: %v", id, r.Method, r.RemoteAddr, + r.URL.String(), time.Since(start), + ) + }, + ) } diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index 14a4c117..2c0ec656 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -13,6 +13,7 @@ import ( "github.com/gorilla/mux" + "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/pkg/my_err" ) @@ -74,7 +75,7 @@ func NewPostController(service PostService, commentService CommentService, respo func (pc *PostController) Create(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) comunity = r.URL.Query().Get("community") id uint32 err error @@ -125,7 +126,7 @@ func (pc *PostController) Create(w http.ResponseWriter, r *http.Request) { } func (pc *PostController) GetOne(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { pc.responder.LogError(my_err.ErrInvalidContext, "") } @@ -159,7 +160,7 @@ func (pc *PostController) GetOne(w http.ResponseWriter, r *http.Request) { func (pc *PostController) Update(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) id, err = getIDFromURL(r, postIDkey) community = r.URL.Query().Get("community") ) @@ -216,7 +217,7 @@ func (pc *PostController) Update(w http.ResponseWriter, r *http.Request) { func (pc *PostController) Delete(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) postID, err = getIDFromURL(r, postIDkey) community = r.URL.Query().Get("community") ) @@ -261,7 +262,7 @@ func (pc *PostController) Delete(w http.ResponseWriter, r *http.Request) { func (pc *PostController) GetBatchPosts(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) section = r.URL.Query().Get("section") communityID = r.URL.Query().Get("community") posts []*models.Post @@ -401,7 +402,7 @@ func (pc *PostController) checkAccessToCommunity(r *http.Request, communityID ui } func (pc *PostController) SetLikeOnPost(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { pc.responder.LogError(my_err.ErrInvalidContext, "") } @@ -439,7 +440,7 @@ func (pc *PostController) SetLikeOnPost(w http.ResponseWriter, r *http.Request) } func (pc *PostController) DeleteLikeFromPost(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { pc.responder.LogError(my_err.ErrInvalidContext, "") } @@ -476,7 +477,7 @@ func (pc *PostController) DeleteLikeFromPost(w http.ResponseWriter, r *http.Requ } func (pc *PostController) Comment(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { pc.responder.LogError(my_err.ErrInvalidContext, "") } @@ -515,7 +516,7 @@ func (pc *PostController) Comment(w http.ResponseWriter, r *http.Request) { } func (pc *PostController) DeleteComment(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { pc.responder.LogError(my_err.ErrInvalidContext, "") } @@ -552,7 +553,7 @@ func (pc *PostController) DeleteComment(w http.ResponseWriter, r *http.Request) } func (pc *PostController) EditComment(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { pc.responder.LogError(my_err.ErrInvalidContext, "") } @@ -599,7 +600,7 @@ func (pc *PostController) EditComment(w http.ResponseWriter, r *http.Request) { } func (pc *PostController) GetComments(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { pc.responder.LogError(my_err.ErrInvalidContext, "") } diff --git a/internal/profile/controller/controller.go b/internal/profile/controller/controller.go index f3475488..d731d941 100644 --- a/internal/profile/controller/controller.go +++ b/internal/profile/controller/controller.go @@ -11,6 +11,7 @@ import ( "github.com/gorilla/mux" "golang.org/x/crypto/bcrypt" + "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/internal/profile" "github.com/2024_2_BetterCallFirewall/pkg/my_err" @@ -39,7 +40,7 @@ func NewProfileController(manager profile.ProfileUsecase, responder Responder) * } func (h *ProfileHandlerImplementation) GetHeader(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { h.Responder.LogError(my_err.ErrInvalidContext, "") } @@ -65,7 +66,7 @@ func (h *ProfileHandlerImplementation) GetHeader(w http.ResponseWriter, r *http. } func (h *ProfileHandlerImplementation) GetProfile(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { h.Responder.LogError(my_err.ErrInvalidContext, "") } @@ -94,7 +95,7 @@ func (h *ProfileHandlerImplementation) GetProfile(w http.ResponseWriter, r *http } func (h *ProfileHandlerImplementation) UpdateProfile(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { h.Responder.LogError(my_err.ErrInvalidContext, "") } @@ -133,7 +134,7 @@ func (h *ProfileHandlerImplementation) getNewProfile(r *http.Request) (*models.F func (h *ProfileHandlerImplementation) DeleteProfile(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) sess, err = models.SessionFromContext(r.Context()) ) @@ -175,7 +176,7 @@ func GetIdFromURL(r *http.Request) (uint32, error) { func (h *ProfileHandlerImplementation) GetProfileById(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) id, err = GetIdFromURL(r) ) @@ -215,7 +216,7 @@ func GetLastId(r *http.Request) (uint32, error) { func (h *ProfileHandlerImplementation) GetAll(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) sess, err = models.SessionFromContext(r.Context()) ) @@ -262,7 +263,7 @@ func GetReceiverAndSender(r *http.Request) (uint32, uint32, error) { func (h *ProfileHandlerImplementation) SendFriendReq(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) receiver, sender, err = GetReceiverAndSender(r) ) @@ -286,7 +287,7 @@ func (h *ProfileHandlerImplementation) SendFriendReq(w http.ResponseWriter, r *h func (h *ProfileHandlerImplementation) AcceptFriendReq(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) whose, who, err = GetReceiverAndSender(r) ) @@ -308,7 +309,7 @@ func (h *ProfileHandlerImplementation) AcceptFriendReq(w http.ResponseWriter, r func (h *ProfileHandlerImplementation) RemoveFromFriends(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) whose, who, err = GetReceiverAndSender(r) ) @@ -330,7 +331,7 @@ func (h *ProfileHandlerImplementation) RemoveFromFriends(w http.ResponseWriter, func (h *ProfileHandlerImplementation) Unsubscribe(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) ) if !ok { @@ -352,7 +353,7 @@ func (h *ProfileHandlerImplementation) Unsubscribe(w http.ResponseWriter, r *htt func (h *ProfileHandlerImplementation) GetAllFriends(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) id, err = GetIdFromURL(r) ) @@ -386,7 +387,7 @@ func (h *ProfileHandlerImplementation) GetAllFriends(w http.ResponseWriter, r *h func (h *ProfileHandlerImplementation) GetAllSubs(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) id, err = GetIdFromURL(r) ) @@ -418,7 +419,7 @@ func (h *ProfileHandlerImplementation) GetAllSubs(w http.ResponseWriter, r *http func (h *ProfileHandlerImplementation) GetAllSubscriptions(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) id, err = GetIdFromURL(r) ) @@ -452,7 +453,7 @@ func (h *ProfileHandlerImplementation) GetAllSubscriptions(w http.ResponseWriter func (h *ProfileHandlerImplementation) GetCommunitySubs(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) id, err = GetIdFromURL(r) ) @@ -487,7 +488,7 @@ func (h *ProfileHandlerImplementation) GetCommunitySubs(w http.ResponseWriter, r func (h *ProfileHandlerImplementation) SearchProfile(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) subStr = r.URL.Query().Get("q") lastID = r.URL.Query().Get("id") id uint64 @@ -528,7 +529,7 @@ func (h *ProfileHandlerImplementation) SearchProfile(w http.ResponseWriter, r *h } func (h *ProfileHandlerImplementation) ChangePassword(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { h.Responder.LogError(my_err.ErrInvalidContext, "") } From bd9e1d48c8159b8bd3230cf3c006aea87fd97249 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 12 Dec 2024 17:34:46 +0300 Subject: [PATCH 049/135] hotfix tests --- internal/post/controller/controller_test.go | 1230 +++++++++++-------- 1 file changed, 705 insertions(+), 525 deletions(-) diff --git a/internal/post/controller/controller_test.go b/internal/post/controller/controller_test.go index 4edb1345..ed2e5360 100644 --- a/internal/post/controller/controller_test.go +++ b/internal/post/controller/controller_test.go @@ -18,11 +18,12 @@ import ( func getController(ctrl *gomock.Controller) (*PostController, *mocks) { m := &mocks{ - postService: NewMockPostService(ctrl), - responder: NewMockResponder(ctrl), + postService: NewMockPostService(ctrl), + responder: NewMockResponder(ctrl), + CommentService: NewMockCommentService(ctrl), } - return NewPostController(m.postService, m.responder), m + return NewPostController(m.postService, m.CommentService, m.responder), m } func TestNewPostController(t *testing.T) { @@ -53,19 +54,23 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "2", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() res := &Request{r: req, w: w} return res, nil @@ -81,19 +86,23 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "3", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -111,19 +120,23 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Create(gomock.Any(), gomock.Any()).Return(uint32(0), errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "4", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -141,19 +154,23 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Create(gomock.Any(), gomock.Any()).Return(uint32(2), nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "5", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=ljkhkg", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=ljkhkg", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -170,19 +187,23 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "6", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -200,19 +221,23 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(false) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "7", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -230,20 +255,26 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) - m.postService.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any()).Return(uint32(0), errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any()).Return( + uint32(0), errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "8", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -262,19 +293,23 @@ func TestCreate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.postService.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any()).Return(uint32(10), nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "9", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=10", + bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -291,42 +326,46 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -351,12 +390,14 @@ func TestGetOne(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -379,12 +420,14 @@ func TestGetOne(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -409,12 +452,14 @@ func TestGetOne(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, my_err.ErrPostNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -439,12 +484,14 @@ func TestGetOne(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -469,12 +516,14 @@ func TestGetOne(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -497,42 +546,46 @@ func TestGetOne(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -556,12 +609,14 @@ func TestUpdate(t *testing.T) { }, ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -584,12 +639,14 @@ func TestUpdate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -613,13 +670,17 @@ func TestUpdate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(0), errors.New("error")) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return( + uint32(0), errors.New("error"), + ) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -644,19 +705,23 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(10), nil) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "5", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -676,19 +741,23 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(my_err.ErrPostNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "6", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -708,19 +777,23 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "7", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -740,19 +813,23 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "8", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=nkljbkvhj", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=nkljbkvhj", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -770,19 +847,23 @@ func TestUpdate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "9", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -801,19 +882,23 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(false) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "10", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -833,19 +918,23 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "11", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=10", - bytes.NewBuffer([]byte(`{"id"`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=10", + bytes.NewBuffer([]byte(`{"id"`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -864,19 +953,23 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "12", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=1", - bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=1", + bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -895,42 +988,46 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -955,12 +1052,14 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -983,12 +1082,14 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1014,12 +1115,14 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(my_err.ErrPostNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1045,12 +1148,14 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1076,12 +1181,14 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1105,12 +1212,14 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, error, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, error, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1133,12 +1242,14 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, error, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, error, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1164,42 +1275,46 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, error, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, error, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1224,12 +1339,14 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1251,12 +1368,14 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1279,10 +1398,14 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, my_err.ErrNoMoreContent) - m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do(func(w, req any) { - request.w.WriteHeader(http.StatusNoContent) - }) + m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, my_err.ErrNoMoreContent, + ) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) }, }, { @@ -1305,13 +1428,17 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1335,12 +1462,14 @@ func TestGetBatchPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1362,12 +1491,14 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1392,12 +1523,14 @@ func TestGetBatchPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetBatchFromFriend(gomock.Any(), gomock.Any(), gomock.Any()). Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1420,12 +1553,14 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1448,13 +1583,17 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.postService.EXPECT().GetCommunityPost(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().GetCommunityPost( + gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), + ).Return(nil, nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1477,42 +1616,46 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1537,12 +1680,14 @@ func TestSetLikeOnPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1565,12 +1710,14 @@ func TestSetLikeOnPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1595,12 +1742,14 @@ func TestSetLikeOnPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1624,13 +1773,17 @@ func TestSetLikeOnPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return( + false, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1655,13 +1808,17 @@ func TestSetLikeOnPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, nil) - m.postService.EXPECT().SetLikeToPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().SetLikeToPost( + gomock.Any(), gomock.Any(), gomock.Any(), + ).Return(errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1687,42 +1844,46 @@ func TestSetLikeOnPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, nil) m.postService.EXPECT().SetLikeToPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1747,12 +1908,14 @@ func TestDeleteLikeFromPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1775,12 +1938,14 @@ func TestDeleteLikeFromPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1805,12 +1970,14 @@ func TestDeleteLikeFromPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, nil) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1834,13 +2001,17 @@ func TestDeleteLikeFromPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return( + false, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1865,13 +2036,17 @@ func TestDeleteLikeFromPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) - m.postService.EXPECT().DeleteLikeFromPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().DeleteLikeFromPost( + gomock.Any(), gomock.Any(), gomock.Any(), + ).Return(errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1897,48 +2072,53 @@ func TestDeleteLikeFromPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) m.postService.EXPECT().DeleteLikeFromPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } type mocks struct { - postService *MockPostService - responder *MockResponder + postService *MockPostService + CommentService *MockCommentService + responder *MockResponder } type Request struct { From 14ab8051ccad27956f520807a1ff868df98da203 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 12 Dec 2024 17:18:30 +0300 Subject: [PATCH 050/135] fix panic --- internal/fileService/controller/controller.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index 8b95ec4f..a6b87b1b 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -107,16 +107,16 @@ func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { } err := r.ParseMultipartForm(10 * (10 << 20)) // 100Mbyte + if err != nil { + fc.responder.ErrorBadRequest(w, my_err.ErrToLargeFile, reqID) + return + } defer func() { err = r.MultipartForm.RemoveAll() if err != nil { fc.responder.LogError(err, reqID) } }() - if err != nil { - fc.responder.ErrorBadRequest(w, my_err.ErrToLargeFile, reqID) - return - } file, header, err := r.FormFile("file") if err != nil { From 84e079bd139d1d626df89d7c5347ec0e7e5636d7 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 12 Dec 2024 17:54:53 +0300 Subject: [PATCH 051/135] fix tests --- .../fileService/controller/controller_test.go | 317 +++++++++++++++--- internal/post/controller/controller_test.go | 2 +- 2 files changed, 275 insertions(+), 44 deletions(-) diff --git a/internal/fileService/controller/controller_test.go b/internal/fileService/controller/controller_test.go index 35976ea9..cb536d54 100644 --- a/internal/fileService/controller/controller_test.go +++ b/internal/fileService/controller/controller_test.go @@ -3,6 +3,7 @@ package controller import ( "context" "errors" + "mime/multipart" "net/http" "net/http/httptest" "testing" @@ -56,12 +57,14 @@ func TestUpload(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -85,12 +88,14 @@ func TestUpload(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.fileService.EXPECT().Upload(gomock.Any(), gomock.Any()).Return(nil, errMock) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -114,42 +119,268 @@ func TestUpload(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.fileService.EXPECT().Upload(gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputBytes(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputBytes(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestUploadNonImage(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/files/default", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *FileController, request Request) (Response, error) { + implementation.UploadNonImage(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/files/default", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"name": "default"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *FileController, request Request) (Response, error) { + implementation.UploadNonImage(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.fileService.EXPECT().UploadNonImage(gomock.Any(), gomock.Any()).Return(nil, errMock) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/files/default", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"name": "default"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *FileController, request Request) (Response, error) { + implementation.UploadNonImage(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.fileService.EXPECT().UploadNonImage(gomock.Any(), gomock.Any()).Return(nil, nil) + m.responder.EXPECT().OutputBytes(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestDownload(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/image", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *FileController, request Request) (Response, error) { + implementation.Download(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/image", nil) + w := httptest.NewRecorder() + req.MultipartForm = &multipart.Form{ + File: make(map[string][]*multipart.FileHeader), + } + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *FileController, request Request) (Response, error) { + implementation.Download(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } diff --git a/internal/post/controller/controller_test.go b/internal/post/controller/controller_test.go index cb4001d3..43eaeeab 100644 --- a/internal/post/controller/controller_test.go +++ b/internal/post/controller/controller_test.go @@ -23,7 +23,7 @@ func getController(ctrl *gomock.Controller) (*PostController, *mocks) { commentService: NewMockCommentService(ctrl), } - return NewPostController(m.postService, m.CommentService, m.responder), m + return NewPostController(m.postService, m.commentService, m.responder), m } func TestNewPostController(t *testing.T) { From a7878adaa35b2cda14e64a252fbb549afa86c746 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 12 Dec 2024 18:53:02 +0300 Subject: [PATCH 052/135] fix: responder --- internal/router/responder.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/internal/router/responder.go b/internal/router/responder.go index 29ce8895..fb7dab96 100644 --- a/internal/router/responder.go +++ b/internal/router/responder.go @@ -60,8 +60,15 @@ func (r *Respond) OutputNoMoreContentJSON(w http.ResponseWriter, requestID strin } func (r *Respond) OutputBytes(w http.ResponseWriter, data []byte, requestID string) { - w.Header().Set("Content-Type", "image/avif,image/webp") - w.Header().Set("Access-Control-Allow-Origin", "http://185.241.194.197:8000") + var format string + if len(data) < 512 { + format = http.DetectContentType(data) + } else { + format = http.DetectContentType(data[:512]) + } + + w.Header().Set("Content-Type", format) + w.Header().Set("Access-Control-Allow-Origin", "http://vilka.online") w.Header().Set("Access-Control-Allow-Credentials", "true") w.WriteHeader(http.StatusOK) From c04451a9fd4fe52ce0ab7bd3578d457a2654199d Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Thu, 12 Dec 2024 20:52:17 +0300 Subject: [PATCH 053/135] Update go.yml --- .github/workflows/go.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index a0741bb1..4bbfa618 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -45,7 +45,6 @@ jobs: run: go test -v ./... build: - needs: [tests, linter] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From 8bf8947fcb2f2f88233dcaff127c9e00eba6f59b Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:13:43 +0300 Subject: [PATCH 054/135] Update go.yml --- .github/workflows/go.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 4bbfa618..40330894 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -45,6 +45,7 @@ jobs: run: go test -v ./... build: + needs: tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From 6db340be2e5d9fe3014fa0080739c72a2bd21d38 Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:22:43 +0300 Subject: [PATCH 055/135] Update go.yml --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 40330894..a0741bb1 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -45,7 +45,7 @@ jobs: run: go test -v ./... build: - needs: tests + needs: [tests, linter] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From 9678a341a3fd39fa1db77d9928e2e99dc8486676 Mon Sep 17 00:00:00 2001 From: slashlight Date: Fri, 13 Dec 2024 10:49:01 +0300 Subject: [PATCH 056/135] feat: added stickers dockerfile --- Dockerfilesticker | 25 +++++++++++++++++++++++++ cmd/stickers/main.go | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 Dockerfilesticker diff --git a/Dockerfilesticker b/Dockerfilesticker new file mode 100644 index 00000000..c6aa08d4 --- /dev/null +++ b/Dockerfilesticker @@ -0,0 +1,25 @@ +FROM golang:alpine AS build + +WORKDIR /stickers + +COPY go.mod . +COPY go.sum . + +RUN go mod download +RUN go mod vendor + +COPY . . + +RUN go build cmd/stickers/main.go + +FROM alpine:latest + +WORKDIR /stickers + +EXPOSE 8088 + +COPY .env . + +COPY --from=build /stickers/main /stickers/main + +CMD ["./main"] \ No newline at end of file diff --git a/cmd/stickers/main.go b/cmd/stickers/main.go index b03eb4af..45e748d3 100644 --- a/cmd/stickers/main.go +++ b/cmd/stickers/main.go @@ -22,7 +22,7 @@ func main() { panic(err) } - log.Printf("Starting server on posrt %s", cfg.STCIKER.Port) + log.Printf("Starting server on port %s", cfg.STCIKER.Port) if err := server.ListenAndServe(); err != nil { panic(err) } From 562a0217460d8025b4b44cc923edbf7bf6931f46 Mon Sep 17 00:00:00 2001 From: slashlight Date: Fri, 13 Dec 2024 10:49:41 +0300 Subject: [PATCH 057/135] feat: added stickers docker-compose.yml --- docker-compose.yml | 47 ++++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 97d62812..6d123656 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,9 +2,7 @@ version: '3.9' services: authgrpc: - build: - context: . - dockerfile: Dockerfileauthgrpc + image: slashlight/authgrpc:latest restart: always ports: - "7072:7072" @@ -12,9 +10,7 @@ services: - redis profilegrpc: - build: - context: . - dockerfile: Dockerfileprofilegrpc + image: slashlight/profilegrpc:latest restart: always ports: - "7074:7074" @@ -22,9 +18,7 @@ services: - db - authgrpc postgrpc: - build: - context: . - dockerfile: Dockerfilepostgrpc + image: slashlight/postgrpc:latest restart: always ports: - "7075:7075" @@ -33,9 +27,7 @@ services: - profilegrpc community: - build: - context: . - dockerfile: Dockerfilecommunity + image: slashlight/community:latest restart: always ports: - "8086:8086" @@ -45,9 +37,7 @@ services: - authgrpc auth: - build: - context: . - dockerfile: Dockerfileauth + image: slashlight/auth:latest restart: always ports: - "8082:8082" @@ -57,9 +47,7 @@ services: - community file: - build: - context: . - dockerfile: Dockerfilefile + image: slashlight/file:latest volumes: - ./image:/image restart: always @@ -70,9 +58,7 @@ services: - auth profile: - build: - context: . - dockerfile: Dockerfileprofile + image: slashlight/profile:latest restart: always ports: - "8084:8084" @@ -83,9 +69,7 @@ services: - file post: - build: - context: . - dockerfile: Dockerfilepost + image: slashlight/post:latest restart: always ports: - "8085:8085" @@ -96,9 +80,7 @@ services: - community - profile chat: - build: - context: . - dockerfile: Dockerfilechat + image: slashlight/chat:latest restart: always ports: - "8087:8087" @@ -107,6 +89,17 @@ services: - authgrpc - post + stickers: + build: + context: . + dockerfile: Dockerfilesticker + restart: always + ports: + - "8088:8088" + depends_on: + - db + - authgrpc + db: image: postgres:latest ports: From cb0ac30e1e6317328cc1b5b0f5b682ae97c405a9 Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:44:27 +0300 Subject: [PATCH 058/135] Update go.yml --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index a0741bb1..70dbf5c5 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -65,7 +65,7 @@ jobs: run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_LOGIN }} --password-stdin - name: Build Docker images run: | - for service in auth authgrpc chat community file post postgrpc profile profilegrpc; do + for service in auth authgrpc chat community file post postgrpc profile profilegrpc sticker; do docker build -t slashlight/${service}:${GITHUB_SHA::8} -t slashlight/${service}:latest -f Dockerfile${service} . docker push slashlight/${service}:${GITHUB_SHA::8} docker push slashlight/${service}:latest From 245eb40efa7cba02097d07263f02c4fb1a767a7d Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:45:03 +0300 Subject: [PATCH 059/135] Update docker-compose.yml --- docker-compose.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 6d123656..42a290c6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -90,9 +90,7 @@ services: - post stickers: - build: - context: . - dockerfile: Dockerfilesticker + image: slashlight/sticker:latest restart: always ports: - "8088:8088" @@ -180,4 +178,4 @@ services: volumes: - postgres_data: \ No newline at end of file + postgres_data: From b3f62ee43b807a9a5a9d0bbdff0b8c08e21ae0e3 Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:45:35 +0300 Subject: [PATCH 060/135] Update docker-compose.yml --- docker-compose.yml | 39 ++++++++++----------------------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 5d07c916..188ac0a8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,9 +2,7 @@ version: '3.9' services: authgrpc: - build: - context: . - dockerfile: Dockerfileauthgrpc + image: slashlight/authgrpc:latest restart: always ports: - "7072:7072" @@ -12,9 +10,7 @@ services: - redis profilegrpc: - build: - context: . - dockerfile: Dockerfileprofilegrpc + image: slashlight/profilegrpc:latest restart: always ports: - "7074:7074" @@ -22,9 +18,7 @@ services: - db - authgrpc postgrpc: - build: - context: . - dockerfile: Dockerfilepostgrpc + image: slashlight/postgrpc:latest restart: always ports: - "7075:7075" @@ -33,9 +27,7 @@ services: - profilegrpc community: - build: - context: . - dockerfile: Dockerfilecommunity + image: slashlight/community:latest restart: always ports: - "8086:8086" @@ -45,9 +37,7 @@ services: - authgrpc auth: - build: - context: . - dockerfile: Dockerfileauth + image: slashlight/auth:latest restart: always ports: - "8082:8082" @@ -57,12 +47,9 @@ services: - community file: - build: - context: . - dockerfile: Dockerfilefile + image: slashlight/file:latest volumes: - ./image:/image - - ./files:/files restart: always ports: - "8083:8083" @@ -71,9 +58,7 @@ services: - auth profile: - build: - context: . - dockerfile: Dockerfileprofile + image: slashlight/profile:latest restart: always ports: - "8084:8084" @@ -84,9 +69,7 @@ services: - file post: - build: - context: . - dockerfile: Dockerfilepost + image: slashlight/post:latest restart: always ports: - "8085:8085" @@ -97,9 +80,7 @@ services: - community - profile chat: - build: - context: . - dockerfile: Dockerfilechat + image: slashlight/chat:latest restart: always ports: - "8087:8087" @@ -188,4 +169,4 @@ services: volumes: - postgres_data: \ No newline at end of file + postgres_data: From 82882f3880a79080488bf8b1d85d3149be0ebbec Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:48:18 +0300 Subject: [PATCH 061/135] Update docker-compose.yml --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 188ac0a8..56ce5ce1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -50,6 +50,7 @@ services: image: slashlight/file:latest volumes: - ./image:/image + - ./files:/files restart: always ports: - "8083:8083" From f27b3f13e0c7b3b21b0fc723ffc97882de11f1f9 Mon Sep 17 00:00:00 2001 From: Alexeyzem <92686279+Alexeyzem@users.noreply.github.com> Date: Fri, 13 Dec 2024 16:13:17 +0300 Subject: [PATCH 062/135] Update controller.go --- internal/post/controller/controller.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index 2c0ec656..4c0ee3b5 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -21,7 +21,8 @@ import ( const ( postIDkey = "id" commentIDKey = "comment_id" - filePrefix = "/image/" + imagePrefix = "/image/" + filePrefix = "/files/" ) //go:generate mockgen -destination=mock.go -source=$GOFILE -package=${GOPACKAGE} @@ -644,5 +645,5 @@ func validateContent(content models.Content) bool { } func validateFile(filepath models.Picture) bool { - return len(filepath) < 100 && (len(filepath) == 0 || strings.HasPrefix(string(filepath), filePrefix)) + return len(filepath) < 100 && (len(filepath) == 0 || strings.HasPrefix(string(filepath), filePrefix) || strings.HasPrefix(string(filepath), imagePrefix)) } From 03280df909a5ab11ac1a4b0a9d41d7c30a613d2a Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Fri, 13 Dec 2024 20:15:46 +0300 Subject: [PATCH 063/135] add stickers and files to chat --- DB/migrations/000001_init_schema.up.sql | 5 +- internal/chat/controller/controller.go | 12 ++-- internal/chat/controller/mock.go | 25 +++++--- internal/chat/repository.go | 2 +- .../chat/repository/postgres/queryConst.go | 2 +- .../chat/repository/postgres/repository.go | 16 +++-- internal/chat/service/chat.go | 12 +++- internal/chat/service/chat_test.go | 20 +++--- internal/chat/usecase.go | 2 +- internal/models/chat.go | 14 +++-- pkg/my_err/error.go | 61 ++++++++++--------- 11 files changed, 105 insertions(+), 66 deletions(-) diff --git a/DB/migrations/000001_init_schema.up.sql b/DB/migrations/000001_init_schema.up.sql index a1094117..bd7a540c 100644 --- a/DB/migrations/000001_init_schema.up.sql +++ b/DB/migrations/000001_init_schema.up.sql @@ -57,6 +57,8 @@ CREATE TABLE IF NOT EXISTS message ( receiver INT REFERENCES profile(id) ON DELETE CASCADE , sender INT REFERENCES profile(id) ON DELETE CASCADE , content TEXT CONSTRAINT content_message_length CHECK (CHAR_LENGTH(content) <= 500) DEFAULT '', + file_path TEXT CONSTRAINT file_path_message_length CHECK (CHAR_LENGTH(file_path) <= 200) DEFAULT '', + sticker_path TEXT CONSTRAINT sticker_path_message_length CHECK (CHAR_LENGTH(sticker_path) <= 200) DEFAULT '', is_read BOOLEAN DEFAULT FALSE, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() @@ -67,7 +69,8 @@ CREATE TABLE IF NOT EXISTS comment ( user_id INT REFERENCES profile(id) ON DELETE CASCADE , post_id INT REFERENCES post(id) ON DELETE CASCADE , content TEXT CONSTRAINT content_comment_length CHECK (CHAR_LENGTH(content) <= 500) DEFAULT '', - file_path TEXT CONSTRAINT file_path_comment CHECK ( CHAR_LENGTH(file_path) <= 100 ) DEFAULT '', + file_path TEXT CONSTRAINT file_path_comment CHECK ( CHAR_LENGTH(file_path) <= 200 ) DEFAULT '', + sticker_path TEXT CONSTRAINT sticker_path_comment_length CHECK (CHAR_LENGTH(sticker_path) <= 200) DEFAULT '', created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); diff --git a/internal/chat/controller/controller.go b/internal/chat/controller/controller.go index efd28ede..6eef9a3d 100644 --- a/internal/chat/controller/controller.go +++ b/internal/chat/controller/controller.go @@ -87,14 +87,18 @@ func (cc *ChatController) SetConnection(w http.ResponseWriter, r *http.Request) }() go client.Write() go client.Read(sess.UserID) - cc.SendChatMsg(ctx, reqID) + cc.SendChatMsg(ctx, reqID, w) } -func (cc *ChatController) SendChatMsg(ctx context.Context, reqID string) { +func (cc *ChatController) SendChatMsg(ctx context.Context, reqID string, w http.ResponseWriter) { for msg := range cc.Messages { - err := cc.chatService.SendNewMessage(ctx, msg.Receiver, msg.Sender, msg.Content) + if msg.Content.StickerPath != "" && (msg.Content.FilePath != "" || msg.Content.Text != "") { + cc.responder.ErrorBadRequest(w, my_err.ErrStickerHasAnotherContent, reqID) + return + } + err := cc.chatService.SendNewMessage(ctx, msg.Receiver, msg.Sender, &msg.Content) if err != nil { - cc.responder.LogError(err, reqID) + cc.responder.ErrorInternal(w, err, reqID) return } diff --git a/internal/chat/controller/mock.go b/internal/chat/controller/mock.go index 85872a35..f05a0949 100644 --- a/internal/chat/controller/mock.go +++ b/internal/chat/controller/mock.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: controller.go +// +// Generated by this command: +// +// mockgen -destination=mock.go -source=controller.go -package=controller +// // Package controller is a generated GoMock package. package controller @@ -18,6 +23,7 @@ import ( type MockResponder struct { ctrl *gomock.Controller recorder *MockResponderMockRecorder + isgomock struct{} } // MockResponderMockRecorder is the mock recorder for MockResponder. @@ -44,7 +50,7 @@ func (m *MockResponder) ErrorBadRequest(w http.ResponseWriter, err error, reques } // ErrorBadRequest indicates an expected call of ErrorBadRequest. -func (mr *MockResponderMockRecorder) ErrorBadRequest(w, err, requestId interface{}) *gomock.Call { +func (mr *MockResponderMockRecorder) ErrorBadRequest(w, err, requestId any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ErrorBadRequest", reflect.TypeOf((*MockResponder)(nil).ErrorBadRequest), w, err, requestId) } @@ -56,7 +62,7 @@ func (m *MockResponder) ErrorInternal(w http.ResponseWriter, err error, requestI } // ErrorInternal indicates an expected call of ErrorInternal. -func (mr *MockResponderMockRecorder) ErrorInternal(w, err, requestId interface{}) *gomock.Call { +func (mr *MockResponderMockRecorder) ErrorInternal(w, err, requestId any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ErrorInternal", reflect.TypeOf((*MockResponder)(nil).ErrorInternal), w, err, requestId) } @@ -68,7 +74,7 @@ func (m *MockResponder) LogError(err error, requestId string) { } // LogError indicates an expected call of LogError. -func (mr *MockResponderMockRecorder) LogError(err, requestId interface{}) *gomock.Call { +func (mr *MockResponderMockRecorder) LogError(err, requestId any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogError", reflect.TypeOf((*MockResponder)(nil).LogError), err, requestId) } @@ -80,7 +86,7 @@ func (m *MockResponder) OutputJSON(w http.ResponseWriter, data any, requestId st } // OutputJSON indicates an expected call of OutputJSON. -func (mr *MockResponderMockRecorder) OutputJSON(w, data, requestId interface{}) *gomock.Call { +func (mr *MockResponderMockRecorder) OutputJSON(w, data, requestId any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OutputJSON", reflect.TypeOf((*MockResponder)(nil).OutputJSON), w, data, requestId) } @@ -92,7 +98,7 @@ func (m *MockResponder) OutputNoMoreContentJSON(w http.ResponseWriter, requestId } // OutputNoMoreContentJSON indicates an expected call of OutputNoMoreContentJSON. -func (mr *MockResponderMockRecorder) OutputNoMoreContentJSON(w, requestId interface{}) *gomock.Call { +func (mr *MockResponderMockRecorder) OutputNoMoreContentJSON(w, requestId any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OutputNoMoreContentJSON", reflect.TypeOf((*MockResponder)(nil).OutputNoMoreContentJSON), w, requestId) } @@ -101,6 +107,7 @@ func (mr *MockResponderMockRecorder) OutputNoMoreContentJSON(w, requestId interf type MockChatService struct { ctrl *gomock.Controller recorder *MockChatServiceMockRecorder + isgomock struct{} } // MockChatServiceMockRecorder is the mock recorder for MockChatService. @@ -130,7 +137,7 @@ func (m *MockChatService) GetAllChats(ctx context.Context, userID uint32, lastUp } // GetAllChats indicates an expected call of GetAllChats. -func (mr *MockChatServiceMockRecorder) GetAllChats(ctx, userID, lastUpdateTime interface{}) *gomock.Call { +func (mr *MockChatServiceMockRecorder) GetAllChats(ctx, userID, lastUpdateTime any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllChats", reflect.TypeOf((*MockChatService)(nil).GetAllChats), ctx, userID, lastUpdateTime) } @@ -145,13 +152,13 @@ func (m *MockChatService) GetChat(ctx context.Context, userID, chatID uint32, la } // GetChat indicates an expected call of GetChat. -func (mr *MockChatServiceMockRecorder) GetChat(ctx, userID, chatID, lastSentTime interface{}) *gomock.Call { +func (mr *MockChatServiceMockRecorder) GetChat(ctx, userID, chatID, lastSentTime any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChat", reflect.TypeOf((*MockChatService)(nil).GetChat), ctx, userID, chatID, lastSentTime) } // SendNewMessage mocks base method. -func (m *MockChatService) SendNewMessage(ctx context.Context, receiver, sender uint32, message string) error { +func (m *MockChatService) SendNewMessage(ctx context.Context, receiver, sender uint32, message *models.MessageContent) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SendNewMessage", ctx, receiver, sender, message) ret0, _ := ret[0].(error) @@ -159,7 +166,7 @@ func (m *MockChatService) SendNewMessage(ctx context.Context, receiver, sender u } // SendNewMessage indicates an expected call of SendNewMessage. -func (mr *MockChatServiceMockRecorder) SendNewMessage(ctx, receiver, sender, message interface{}) *gomock.Call { +func (mr *MockChatServiceMockRecorder) SendNewMessage(ctx, receiver, sender, message any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendNewMessage", reflect.TypeOf((*MockChatService)(nil).SendNewMessage), ctx, receiver, sender, message) } diff --git a/internal/chat/repository.go b/internal/chat/repository.go index f9816362..33578bfb 100644 --- a/internal/chat/repository.go +++ b/internal/chat/repository.go @@ -10,5 +10,5 @@ import ( type ChatRepository interface { GetChats(ctx context.Context, userID uint32, lastUpdateTime time.Time) ([]*models.Chat, error) GetMessages(ctx context.Context, userID uint32, chatID uint32, lastSentTime time.Time) ([]*models.Message, error) - SendNewMessage(ctx context.Context, receiver uint32, sender uint32, message string) error + SendNewMessage(ctx context.Context, receiver uint32, sender uint32, message *models.MessageContent) error } diff --git a/internal/chat/repository/postgres/queryConst.go b/internal/chat/repository/postgres/queryConst.go index e37fd3bf..c5c22f95 100644 --- a/internal/chat/repository/postgres/queryConst.go +++ b/internal/chat/repository/postgres/queryConst.go @@ -43,5 +43,5 @@ AND created_at < $3 ORDER BY created_at DESC LIMIT 20;` - sendNewMessage = `INSERT INTO message(receiver, sender, content) VALUES ($1, $2, $3)` + sendNewMessage = `INSERT INTO message(receiver, sender, content, file_path, sticker_path) VALUES ($1, $2, $3, $4, $5)` ) diff --git a/internal/chat/repository/postgres/repository.go b/internal/chat/repository/postgres/repository.go index 81c2eacc..45c3c387 100644 --- a/internal/chat/repository/postgres/repository.go +++ b/internal/chat/repository/postgres/repository.go @@ -38,7 +38,9 @@ func (cr *Repo) GetChats(ctx context.Context, userID uint32, lastUpdateTime time for rows.Next() { chat := &models.Chat{} - if err := rows.Scan(&chat.Receiver.AuthorID, &chat.Receiver.Author, &chat.Receiver.Avatar, &chat.LastMessage, &chat.LastDate); err != nil { + if err := rows.Scan( + &chat.Receiver.AuthorID, &chat.Receiver.Author, &chat.Receiver.Avatar, &chat.LastMessage, &chat.LastDate, + ); err != nil { return nil, fmt.Errorf("postgres get chats: %w", err) } chats = append(chats, chat) @@ -51,7 +53,9 @@ func (cr *Repo) GetChats(ctx context.Context, userID uint32, lastUpdateTime time return chats, nil } -func (cr *Repo) GetMessages(ctx context.Context, userID uint32, chatID uint32, lastSentTime time.Time) ([]*models.Message, error) { +func (cr *Repo) GetMessages( + ctx context.Context, userID uint32, chatID uint32, lastSentTime time.Time, +) ([]*models.Message, error) { var messages []*models.Message rows, err := cr.db.QueryContext(ctx, getLatestMessagesBatch, userID, chatID, pq.FormatTimestamp(lastSentTime)) @@ -79,8 +83,12 @@ func (cr *Repo) GetMessages(ctx context.Context, userID uint32, chatID uint32, l } -func (cr *Repo) SendNewMessage(ctx context.Context, receiver uint32, sender uint32, message string) error { - _, err := cr.db.ExecContext(ctx, sendNewMessage, receiver, sender, message) +func (cr *Repo) SendNewMessage( + ctx context.Context, receiver uint32, sender uint32, message *models.MessageContent, +) error { + _, err := cr.db.ExecContext( + ctx, sendNewMessage, receiver, sender, message.Text, message.FilePath, message.StickerPath, + ) if err != nil { return fmt.Errorf("postgres send new message: %w", err) } diff --git a/internal/chat/service/chat.go b/internal/chat/service/chat.go index 207a5b39..af454abe 100644 --- a/internal/chat/service/chat.go +++ b/internal/chat/service/chat.go @@ -19,7 +19,9 @@ func NewChatService(repo chat.ChatRepository) *ChatService { } } -func (cs *ChatService) GetAllChats(ctx context.Context, userID uint32, lastUpdateTime time.Time) ([]*models.Chat, error) { +func (cs *ChatService) GetAllChats( + ctx context.Context, userID uint32, lastUpdateTime time.Time, +) ([]*models.Chat, error) { chats, err := cs.repo.GetChats(ctx, userID, lastUpdateTime) if err != nil { @@ -29,7 +31,9 @@ func (cs *ChatService) GetAllChats(ctx context.Context, userID uint32, lastUpdat return chats, nil } -func (cs *ChatService) GetChat(ctx context.Context, userID uint32, chatID uint32, lastSent time.Time) ([]*models.Message, error) { +func (cs *ChatService) GetChat( + ctx context.Context, userID uint32, chatID uint32, lastSent time.Time, +) ([]*models.Message, error) { messages, err := cs.repo.GetMessages(ctx, userID, chatID, lastSent) if err != nil { return nil, fmt.Errorf("get all messages: %w", err) @@ -42,7 +46,9 @@ func (cs *ChatService) GetChat(ctx context.Context, userID uint32, chatID uint32 return messages, nil } -func (cs *ChatService) SendNewMessage(ctx context.Context, receiver uint32, sender uint32, message string) error { +func (cs *ChatService) SendNewMessage( + ctx context.Context, receiver uint32, sender uint32, message *models.MessageContent, +) error { err := cs.repo.SendNewMessage(ctx, receiver, sender, message) if err != nil { return fmt.Errorf("send new message: %w", err) diff --git a/internal/chat/service/chat_test.go b/internal/chat/service/chat_test.go index 6f9e8c00..06b6bbff 100644 --- a/internal/chat/service/chat_test.go +++ b/internal/chat/service/chat_test.go @@ -25,7 +25,9 @@ func (m MockRepo) GetChats(ctx context.Context, userID uint32, lastUpdateTime ti return []*models.Chat{}, nil } -func (m MockRepo) GetMessages(ctx context.Context, userID uint32, chatID uint32, lastSentTime time.Time) ([]*models.Message, error) { +func (m MockRepo) GetMessages( + ctx context.Context, userID uint32, chatID uint32, lastSentTime time.Time, +) ([]*models.Message, error) { if userID == 0 || chatID == 0 { return nil, errMock } @@ -34,8 +36,10 @@ func (m MockRepo) GetMessages(ctx context.Context, userID uint32, chatID uint32, }, nil } -func (m MockRepo) SendNewMessage(ctx context.Context, receiver uint32, sender uint32, message string) error { - if receiver == 0 || sender == 0 || message == "" { +func (m MockRepo) SendNewMessage( + ctx context.Context, receiver uint32, sender uint32, message *models.MessageContent, +) error { + if receiver == 0 || sender == 0 || message.Text == "" { return errMock } return nil @@ -115,7 +119,7 @@ func TestGetChat(t *testing.T) { type TestStructSendNewMessage struct { sender uint32 receiver uint32 - message string + message *models.MessageContent wantErr error } @@ -125,25 +129,25 @@ func TestSendNewMessage(t *testing.T) { { sender: 0, receiver: 10, - message: "hello", + message: &models.MessageContent{Text: "hello"}, wantErr: errMock, }, { sender: 10, receiver: 0, - message: "hello", + message: &models.MessageContent{Text: "hello"}, wantErr: errMock, }, { sender: 1, receiver: 10, - message: "", + message: &models.MessageContent{Text: ""}, wantErr: errMock, }, { sender: 1, receiver: 10, - message: "hello", + message: &models.MessageContent{Text: "hello"}, wantErr: nil, }, } diff --git a/internal/chat/usecase.go b/internal/chat/usecase.go index c2dc25b0..8c3e7ab6 100644 --- a/internal/chat/usecase.go +++ b/internal/chat/usecase.go @@ -10,5 +10,5 @@ import ( type ChatService interface { GetAllChats(ctx context.Context, userID uint32, lastUpdateTime time.Time) ([]*models.Chat, error) GetChat(ctx context.Context, userID uint32, chatID uint32, lastSentTime time.Time) ([]*models.Message, error) - SendNewMessage(ctx context.Context, receiver uint32, sender uint32, message string) error + SendNewMessage(ctx context.Context, receiver uint32, sender uint32, message *models.MessageContent) error } diff --git a/internal/models/chat.go b/internal/models/chat.go index 56c68911..e73fddc0 100644 --- a/internal/models/chat.go +++ b/internal/models/chat.go @@ -11,8 +11,14 @@ type Chat struct { } type Message struct { - Sender uint32 `json:"sender"` - Receiver uint32 `json:"receiver"` - Content string `json:"content"` - CreatedAt time.Time `json:"created_at"` + Sender uint32 `json:"sender"` + Receiver uint32 `json:"receiver"` + Content MessageContent `json:"content"` + CreatedAt time.Time `json:"created_at"` +} + +type MessageContent struct { + Text string `json:"text"` + FilePath string `json:"file_path"` + StickerPath string `json:"sticker_path"` } diff --git a/pkg/my_err/error.go b/pkg/my_err/error.go index c4bad589..0b504a34 100644 --- a/pkg/my_err/error.go +++ b/pkg/my_err/error.go @@ -5,34 +5,35 @@ import ( ) var ( - ErrUserNotFound = errors.New("user not found") - ErrUserAlreadyExists = errors.New("user already exists") - ErrNoAuth = errors.New("no auth") - ErrWrongEmailOrPassword = errors.New("wrong email or password") - ErrNonValidEmail = errors.New("invalid email") - ErrSessionNotFound = errors.New("session not found") - ErrSessionAlreadyExists = errors.New("session already exists") - ErrToLargeFile = errors.New("file too large") - ErrNoMoreContent = errors.New("no more content") - ErrWrongFiletype = errors.New("wrong type of file") - ErrPostNotFound = errors.New("post not found") - ErrAccessDenied = errors.New("access denied") - ErrInternal = errors.New("internal error") - ErrWrongOwner = errors.New("wrong owner") - ErrSameUser = errors.New("same user") - ErrEmptyId = errors.New("empty id") - ErrBigId = errors.New("id is too big") - ErrProfileNotFound = errors.New("profile not found") - ErrAnotherService = errors.New("another service") - ErrInvalidQuery = errors.New("invalid query parameter") - ErrInvalidContext = errors.New("invalid context parameter") - ErrWrongDateFormat = errors.New("wrong date format") - ErrWrongFile = errors.New("wrong file name") - ErrNoFile = errors.New("file not found") - ErrResNotOK = errors.New("res not OK") - ErrLikeAlreadyExists = errors.New("like already exists") - ErrWrongCommunity = errors.New("wrong community") - ErrWrongPost = errors.New("wrong post") - ErrTextTooLong = errors.New("text len is too big") - ErrWrongComment = errors.New("wrong comment") + ErrUserNotFound = errors.New("user not found") + ErrUserAlreadyExists = errors.New("user already exists") + ErrNoAuth = errors.New("no auth") + ErrWrongEmailOrPassword = errors.New("wrong email or password") + ErrNonValidEmail = errors.New("invalid email") + ErrSessionNotFound = errors.New("session not found") + ErrSessionAlreadyExists = errors.New("session already exists") + ErrToLargeFile = errors.New("file too large") + ErrNoMoreContent = errors.New("no more content") + ErrWrongFiletype = errors.New("wrong type of file") + ErrPostNotFound = errors.New("post not found") + ErrAccessDenied = errors.New("access denied") + ErrInternal = errors.New("internal error") + ErrWrongOwner = errors.New("wrong owner") + ErrSameUser = errors.New("same user") + ErrEmptyId = errors.New("empty id") + ErrBigId = errors.New("id is too big") + ErrProfileNotFound = errors.New("profile not found") + ErrAnotherService = errors.New("another service") + ErrInvalidQuery = errors.New("invalid query parameter") + ErrInvalidContext = errors.New("invalid context parameter") + ErrWrongDateFormat = errors.New("wrong date format") + ErrWrongFile = errors.New("wrong file name") + ErrNoFile = errors.New("file not found") + ErrResNotOK = errors.New("res not OK") + ErrLikeAlreadyExists = errors.New("like already exists") + ErrWrongCommunity = errors.New("wrong community") + ErrWrongPost = errors.New("wrong post") + ErrTextTooLong = errors.New("text len is too big") + ErrWrongComment = errors.New("wrong comment") + ErrStickerHasAnotherContent = errors.New("sticker has another content") ) From 48d1885409dfc70312a373f3694e822c441dc09b Mon Sep 17 00:00:00 2001 From: Alexeyzem <92686279+Alexeyzem@users.noreply.github.com> Date: Fri, 13 Dec 2024 20:29:47 +0300 Subject: [PATCH 064/135] Update controller.go --- internal/stickers/controller/controller.go | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/internal/stickers/controller/controller.go b/internal/stickers/controller/controller.go index b6560451..1c02c4d7 100644 --- a/internal/stickers/controller/controller.go +++ b/internal/stickers/controller/controller.go @@ -31,9 +31,7 @@ func NewStickerController(manager stickers.Usecase, responder Responder) *Sticke } func (s StickersHandlerImplementation) AddNewSticker(w http.ResponseWriter, r *http.Request) { - var ( - reqID, ok = r.Context().Value("requestID").(string) - ) + reqID, ok := r.Context().Value("requestID").(string) if !ok { s.Responder.LogError(my_err.ErrInvalidContext, "") @@ -58,13 +56,10 @@ func (s StickersHandlerImplementation) AddNewSticker(w http.ResponseWriter, r *h } s.Responder.OutputJSON(w, "New sticker is added", reqID) - return } func (s StickersHandlerImplementation) GetAllStickers(w http.ResponseWriter, r *http.Request) { - var ( - reqID, ok = r.Context().Value("requestID").(string) - ) + reqID, ok := r.Context().Value("requestID").(string) if !ok { s.Responder.LogError(my_err.ErrInvalidContext, "") @@ -77,15 +72,14 @@ func (s StickersHandlerImplementation) GetAllStickers(w http.ResponseWriter, r * return } s.Responder.ErrorInternal(w, err, reqID) + return } s.Responder.OutputJSON(w, res, reqID) } func (s StickersHandlerImplementation) GetMineStickers(w http.ResponseWriter, r *http.Request) { - var ( - reqID, ok = r.Context().Value("requestID").(string) - ) + reqID, ok := r.Context().Value("requestID").(string) if !ok { s.Responder.LogError(my_err.ErrInvalidContext, "") @@ -104,6 +98,7 @@ func (s StickersHandlerImplementation) GetMineStickers(w http.ResponseWriter, r return } s.Responder.ErrorInternal(w, err, reqID) + return } s.Responder.OutputJSON(w, res, reqID) From 3f62e36ed4158f3f7df78122659fbfe9d909259b Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Fri, 13 Dec 2024 20:47:30 +0300 Subject: [PATCH 065/135] feature: update database --- DB/migrations/000001_init_schema.up.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/DB/migrations/000001_init_schema.up.sql b/DB/migrations/000001_init_schema.up.sql index bd7a540c..e09a672b 100644 --- a/DB/migrations/000001_init_schema.up.sql +++ b/DB/migrations/000001_init_schema.up.sql @@ -47,7 +47,7 @@ CREATE TABLE IF NOT EXISTS post ( author_id INT REFERENCES profile(id) ON DELETE CASCADE, community_id INT REFERENCES community(id) ON DELETE CASCADE DEFAULT NULL, content TEXT CONSTRAINT content_post_length CHECK (CHAR_LENGTH(content) <= 500) DEFAULT '', - file_path TEXT CONSTRAINT file_path_length CHECK (CHAR_LENGTH(file_path) <= 100) DEFAULT '', + file_path TEXT CONSTRAINT file_path_length CHECK (CHAR_LENGTH(file_path) <= 1000) DEFAULT '', created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); @@ -57,8 +57,8 @@ CREATE TABLE IF NOT EXISTS message ( receiver INT REFERENCES profile(id) ON DELETE CASCADE , sender INT REFERENCES profile(id) ON DELETE CASCADE , content TEXT CONSTRAINT content_message_length CHECK (CHAR_LENGTH(content) <= 500) DEFAULT '', - file_path TEXT CONSTRAINT file_path_message_length CHECK (CHAR_LENGTH(file_path) <= 200) DEFAULT '', - sticker_path TEXT CONSTRAINT sticker_path_message_length CHECK (CHAR_LENGTH(sticker_path) <= 200) DEFAULT '', + file_path TEXT CONSTRAINT file_path_message_length CHECK (CHAR_LENGTH(file_path) <= 1000) DEFAULT '', + sticker_path TEXT CONSTRAINT sticker_path_message_length CHECK (CHAR_LENGTH(sticker_path) <= 100) DEFAULT '', is_read BOOLEAN DEFAULT FALSE, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() @@ -69,7 +69,7 @@ CREATE TABLE IF NOT EXISTS comment ( user_id INT REFERENCES profile(id) ON DELETE CASCADE , post_id INT REFERENCES post(id) ON DELETE CASCADE , content TEXT CONSTRAINT content_comment_length CHECK (CHAR_LENGTH(content) <= 500) DEFAULT '', - file_path TEXT CONSTRAINT file_path_comment CHECK ( CHAR_LENGTH(file_path) <= 200 ) DEFAULT '', + file_path TEXT CONSTRAINT file_path_comment CHECK ( CHAR_LENGTH(file_path) <= 1000 ) DEFAULT '', sticker_path TEXT CONSTRAINT sticker_path_comment_length CHECK (CHAR_LENGTH(sticker_path) <= 200) DEFAULT '', created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() From 09cba9e390f1d586211b3b223d8de5d829e43ef3 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Fri, 13 Dec 2024 22:36:31 +0300 Subject: [PATCH 066/135] add more then one file for chat, post and comment --- internal/api/grpc/post_api/grpc_server.go | 8 +- .../api/grpc/post_api/grpc_server_test.go | 55 +++-- internal/api/grpc/post_api/post.pb.go | 14 +- internal/chat/controller/controller.go | 4 +- internal/chat/controller/mock.go | 136 +++++------ internal/chat/repository.go | 4 +- .../chat/repository/postgres/repository.go | 8 +- internal/chat/service/chat.go | 10 +- internal/chat/service/chat_test.go | 16 +- internal/chat/usecase.go | 2 +- internal/ext_grpc/adapter/post/post_test.go | 71 +++--- internal/ext_grpc/port/post/post.go | 7 +- internal/models/chat.go | 75 +++++- internal/models/chat_test.go | 85 +++++++ internal/models/content.go | 49 +++- internal/models/content_test.go | 50 ++++ internal/models/post.go | 59 +++++ internal/models/post_test.go | 87 +++++++ internal/post/controller/controller.go | 89 ++++--- internal/post/controller/controller_test.go | 59 ++++- internal/post/controller/mock.go | 32 +-- internal/post/repository/postgres/postgres.go | 48 ++-- .../post/repository/postgres/postgres_test.go | 217 +++++++++++++----- internal/post/service/comment.go | 16 +- internal/post/service/comment_mock.go | 8 +- internal/post/service/comment_test.go | 44 ++-- internal/post/service/mock.go | 22 +- internal/post/service/mock_helper.go | 4 +- internal/post/service/post.go | 30 +-- internal/post/service/post_profile.go | 9 +- internal/post/service/post_profile_test.go | 8 +- internal/post/service/post_test.go | 184 +++++++-------- proto/post.proto | 2 +- 33 files changed, 1062 insertions(+), 450 deletions(-) create mode 100644 internal/models/chat_test.go create mode 100644 internal/models/content_test.go create mode 100644 internal/models/post_test.go diff --git a/internal/api/grpc/post_api/grpc_server.go b/internal/api/grpc/post_api/grpc_server.go index bc2af8e6..99f2a6c6 100644 --- a/internal/api/grpc/post_api/grpc_server.go +++ b/internal/api/grpc/post_api/grpc_server.go @@ -40,7 +40,13 @@ func (a *Adapter) GetAuthorsPosts(ctx context.Context, req *Request) (*Response, resp := &Response{ Posts: make([]*Post, 0, len(res)), } + for _, post := range res { + files := make([]string, 0, len(post.PostContent.File)) + for _, f := range post.PostContent.File { + files = append(files, string(f)) + } + resp.Posts = append( resp.Posts, &Post{ ID: post.ID, @@ -52,7 +58,7 @@ func (a *Adapter) GetAuthorsPosts(ctx context.Context, req *Request) (*Response, }, PostContent: &Content{ Text: post.PostContent.Text, - File: string(post.PostContent.File), + File: files, CreatedAt: post.PostContent.CreatedAt.Unix(), UpdatedAt: post.PostContent.UpdatedAt.Unix(), }, diff --git a/internal/api/grpc/post_api/grpc_server_test.go b/internal/api/grpc/post_api/grpc_server_test.go index 8a3f1649..fcbfcb71 100644 --- a/internal/api/grpc/post_api/grpc_server_test.go +++ b/internal/api/grpc/post_api/grpc_server_test.go @@ -68,9 +68,12 @@ func TestGetAuthorsPosts(t *testing.T) { return &Response{ Posts: []*Post{ { - ID: 1, - PostContent: &Content{Text: "New Post", CreatedAt: createTime.Unix(), UpdatedAt: createTime.Unix()}, - Head: &Header{AuthorID: 1, Author: "Alexey Zemliakov"}, + ID: 1, + PostContent: &Content{ + Text: "New Post", CreatedAt: createTime.Unix(), UpdatedAt: createTime.Unix(), + File: []string{}, + }, + Head: &Header{AuthorID: 1, Author: "Alexey Zemliakov"}, }, }, }, @@ -82,9 +85,11 @@ func TestGetAuthorsPosts(t *testing.T) { Return( []*models.Post{ { - ID: 1, - PostContent: models.Content{Text: "New Post", CreatedAt: createTime, UpdatedAt: createTime}, - Header: models.Header{AuthorID: 1, Author: "Alexey Zemliakov"}, + ID: 1, + PostContent: models.Content{ + Text: "New Post", CreatedAt: createTime, UpdatedAt: createTime, + }, + Header: models.Header{AuthorID: 1, Author: "Alexey Zemliakov"}, }, }, nil, @@ -94,29 +99,31 @@ func TestGetAuthorsPosts(t *testing.T) { } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - adapter, mock := getAdapter(ctrl) - ctx := context.Background() + adapter, mock := getAdapter(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(input, mock) + v.SetupMock(input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, adapter, input) - assert.Equal(t, res, actual) - assert.Equal(t, status.Code(err), v.ExpectedErrCode) - }) + actual, err := v.Run(ctx, adapter, input) + assert.Equal(t, res, actual) + assert.Equal(t, status.Code(err), v.ExpectedErrCode) + }, + ) } } diff --git a/internal/api/grpc/post_api/post.pb.go b/internal/api/grpc/post_api/post.pb.go index 7d222125..b4241ae2 100644 --- a/internal/api/grpc/post_api/post.pb.go +++ b/internal/api/grpc/post_api/post.pb.go @@ -285,10 +285,10 @@ type Content struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Text string `protobuf:"bytes,1,opt,name=Text,proto3" json:"Text,omitempty"` - File string `protobuf:"bytes,2,opt,name=File,proto3" json:"File,omitempty"` - CreatedAt int64 `protobuf:"varint,3,opt,name=CreatedAt,proto3" json:"CreatedAt,omitempty"` - UpdatedAt int64 `protobuf:"varint,4,opt,name=UpdatedAt,proto3" json:"UpdatedAt,omitempty"` + Text string `protobuf:"bytes,1,opt,name=Text,proto3" json:"Text,omitempty"` + File []string `protobuf:"bytes,2,rep,name=File,proto3" json:"File,omitempty"` + CreatedAt int64 `protobuf:"varint,3,opt,name=CreatedAt,proto3" json:"CreatedAt,omitempty"` + UpdatedAt int64 `protobuf:"varint,4,opt,name=UpdatedAt,proto3" json:"UpdatedAt,omitempty"` } func (x *Content) Reset() { @@ -330,11 +330,11 @@ func (x *Content) GetText() string { return "" } -func (x *Content) GetFile() string { +func (x *Content) GetFile() []string { if x != nil { return x.File } - return "" + return nil } func (x *Content) GetCreatedAt() int64 { @@ -386,7 +386,7 @@ var file_proto_post_proto_rawDesc = []byte{ 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x6d, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x65, 0x78, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x12, 0x12, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, diff --git a/internal/chat/controller/controller.go b/internal/chat/controller/controller.go index 6eef9a3d..f505369c 100644 --- a/internal/chat/controller/controller.go +++ b/internal/chat/controller/controller.go @@ -92,6 +92,7 @@ func (cc *ChatController) SetConnection(w http.ResponseWriter, r *http.Request) func (cc *ChatController) SendChatMsg(ctx context.Context, reqID string, w http.ResponseWriter) { for msg := range cc.Messages { + msg := msg.ToDto() if msg.Content.StickerPath != "" && (msg.Content.FilePath != "" || msg.Content.Text != "") { cc.responder.ErrorBadRequest(w, my_err.ErrStickerHasAnotherContent, reqID) return @@ -105,7 +106,8 @@ func (cc *ChatController) SendChatMsg(ctx context.Context, reqID string, w http. resConn, ok := mapUserConn[msg.Receiver] if ok { //resConn.Socket.ReadMessage() - resConn.Receive <- msg + m := msg.FromDto() + resConn.Receive <- &m } } } diff --git a/internal/chat/controller/mock.go b/internal/chat/controller/mock.go index f05a0949..348a7797 100644 --- a/internal/chat/controller/mock.go +++ b/internal/chat/controller/mock.go @@ -19,6 +19,74 @@ import ( gomock "github.com/golang/mock/gomock" ) +// MockChatService is a mock of ChatService interface. +type MockChatService struct { + ctrl *gomock.Controller + recorder *MockChatServiceMockRecorder + isgomock struct{} +} + +// MockChatServiceMockRecorder is the mock recorder for MockChatService. +type MockChatServiceMockRecorder struct { + mock *MockChatService +} + +// NewMockChatService creates a new mock instance. +func NewMockChatService(ctrl *gomock.Controller) *MockChatService { + mock := &MockChatService{ctrl: ctrl} + mock.recorder = &MockChatServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockChatService) EXPECT() *MockChatServiceMockRecorder { + return m.recorder +} + +// GetAllChats mocks base method. +func (m *MockChatService) GetAllChats(ctx context.Context, userID uint32, lastUpdateTime time.Time) ([]*models.Chat, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAllChats", ctx, userID, lastUpdateTime) + ret0, _ := ret[0].([]*models.Chat) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAllChats indicates an expected call of GetAllChats. +func (mr *MockChatServiceMockRecorder) GetAllChats(ctx, userID, lastUpdateTime any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllChats", reflect.TypeOf((*MockChatService)(nil).GetAllChats), ctx, userID, lastUpdateTime) +} + +// GetChat mocks base method. +func (m *MockChatService) GetChat(ctx context.Context, userID, chatID uint32, lastSentTime time.Time) ([]*models.Message, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetChat", ctx, userID, chatID, lastSentTime) + ret0, _ := ret[0].([]*models.Message) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetChat indicates an expected call of GetChat. +func (mr *MockChatServiceMockRecorder) GetChat(ctx, userID, chatID, lastSentTime any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChat", reflect.TypeOf((*MockChatService)(nil).GetChat), ctx, userID, chatID, lastSentTime) +} + +// SendNewMessage mocks base method. +func (m *MockChatService) SendNewMessage(ctx context.Context, receiver, sender uint32, message *models.MessageContentDto) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendNewMessage", ctx, receiver, sender, message) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendNewMessage indicates an expected call of SendNewMessage. +func (mr *MockChatServiceMockRecorder) SendNewMessage(ctx, receiver, sender, message any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendNewMessage", reflect.TypeOf((*MockChatService)(nil).SendNewMessage), ctx, receiver, sender, message) +} + // MockResponder is a mock of Responder interface. type MockResponder struct { ctrl *gomock.Controller @@ -102,71 +170,3 @@ func (mr *MockResponderMockRecorder) OutputNoMoreContentJSON(w, requestId any) * mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OutputNoMoreContentJSON", reflect.TypeOf((*MockResponder)(nil).OutputNoMoreContentJSON), w, requestId) } - -// MockChatService is a mock of ChatService interface. -type MockChatService struct { - ctrl *gomock.Controller - recorder *MockChatServiceMockRecorder - isgomock struct{} -} - -// MockChatServiceMockRecorder is the mock recorder for MockChatService. -type MockChatServiceMockRecorder struct { - mock *MockChatService -} - -// NewMockChatService creates a new mock instance. -func NewMockChatService(ctrl *gomock.Controller) *MockChatService { - mock := &MockChatService{ctrl: ctrl} - mock.recorder = &MockChatServiceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockChatService) EXPECT() *MockChatServiceMockRecorder { - return m.recorder -} - -// GetAllChats mocks base method. -func (m *MockChatService) GetAllChats(ctx context.Context, userID uint32, lastUpdateTime time.Time) ([]*models.Chat, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAllChats", ctx, userID, lastUpdateTime) - ret0, _ := ret[0].([]*models.Chat) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetAllChats indicates an expected call of GetAllChats. -func (mr *MockChatServiceMockRecorder) GetAllChats(ctx, userID, lastUpdateTime any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllChats", reflect.TypeOf((*MockChatService)(nil).GetAllChats), ctx, userID, lastUpdateTime) -} - -// GetChat mocks base method. -func (m *MockChatService) GetChat(ctx context.Context, userID, chatID uint32, lastSentTime time.Time) ([]*models.Message, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetChat", ctx, userID, chatID, lastSentTime) - ret0, _ := ret[0].([]*models.Message) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetChat indicates an expected call of GetChat. -func (mr *MockChatServiceMockRecorder) GetChat(ctx, userID, chatID, lastSentTime any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChat", reflect.TypeOf((*MockChatService)(nil).GetChat), ctx, userID, chatID, lastSentTime) -} - -// SendNewMessage mocks base method. -func (m *MockChatService) SendNewMessage(ctx context.Context, receiver, sender uint32, message *models.MessageContent) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SendNewMessage", ctx, receiver, sender, message) - ret0, _ := ret[0].(error) - return ret0 -} - -// SendNewMessage indicates an expected call of SendNewMessage. -func (mr *MockChatServiceMockRecorder) SendNewMessage(ctx, receiver, sender, message any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendNewMessage", reflect.TypeOf((*MockChatService)(nil).SendNewMessage), ctx, receiver, sender, message) -} diff --git a/internal/chat/repository.go b/internal/chat/repository.go index 33578bfb..f430453a 100644 --- a/internal/chat/repository.go +++ b/internal/chat/repository.go @@ -9,6 +9,6 @@ import ( type ChatRepository interface { GetChats(ctx context.Context, userID uint32, lastUpdateTime time.Time) ([]*models.Chat, error) - GetMessages(ctx context.Context, userID uint32, chatID uint32, lastSentTime time.Time) ([]*models.Message, error) - SendNewMessage(ctx context.Context, receiver uint32, sender uint32, message *models.MessageContent) error + GetMessages(ctx context.Context, userID uint32, chatID uint32, lastSentTime time.Time) ([]*models.MessageDto, error) + SendNewMessage(ctx context.Context, receiver uint32, sender uint32, message *models.MessageContentDto) error } diff --git a/internal/chat/repository/postgres/repository.go b/internal/chat/repository/postgres/repository.go index 45c3c387..b0d084ac 100644 --- a/internal/chat/repository/postgres/repository.go +++ b/internal/chat/repository/postgres/repository.go @@ -55,8 +55,8 @@ func (cr *Repo) GetChats(ctx context.Context, userID uint32, lastUpdateTime time func (cr *Repo) GetMessages( ctx context.Context, userID uint32, chatID uint32, lastSentTime time.Time, -) ([]*models.Message, error) { - var messages []*models.Message +) ([]*models.MessageDto, error) { + var messages []*models.MessageDto rows, err := cr.db.QueryContext(ctx, getLatestMessagesBatch, userID, chatID, pq.FormatTimestamp(lastSentTime)) @@ -69,7 +69,7 @@ func (cr *Repo) GetMessages( defer rows.Close() for rows.Next() { - msg := &models.Message{} + msg := &models.MessageDto{} if err := rows.Scan(&msg.Sender, &msg.Receiver, &msg.Content, &msg.CreatedAt); err != nil { return nil, fmt.Errorf("postgres get messages: %w", err) } @@ -84,7 +84,7 @@ func (cr *Repo) GetMessages( } func (cr *Repo) SendNewMessage( - ctx context.Context, receiver uint32, sender uint32, message *models.MessageContent, + ctx context.Context, receiver uint32, sender uint32, message *models.MessageContentDto, ) error { _, err := cr.db.ExecContext( ctx, sendNewMessage, receiver, sender, message.Text, message.FilePath, message.StickerPath, diff --git a/internal/chat/service/chat.go b/internal/chat/service/chat.go index af454abe..c5203620 100644 --- a/internal/chat/service/chat.go +++ b/internal/chat/service/chat.go @@ -43,11 +43,17 @@ func (cs *ChatService) GetChat( messages[i].CreatedAt = convertTime(m.CreatedAt) } - return messages, nil + res := make([]*models.Message, 0, len(messages)) + for _, m := range messages { + mes := m.FromDto() + res = append(res, &mes) + } + + return res, nil } func (cs *ChatService) SendNewMessage( - ctx context.Context, receiver uint32, sender uint32, message *models.MessageContent, + ctx context.Context, receiver uint32, sender uint32, message *models.MessageContentDto, ) error { err := cs.repo.SendNewMessage(ctx, receiver, sender, message) if err != nil { diff --git a/internal/chat/service/chat_test.go b/internal/chat/service/chat_test.go index 06b6bbff..68ccf7a2 100644 --- a/internal/chat/service/chat_test.go +++ b/internal/chat/service/chat_test.go @@ -27,17 +27,17 @@ func (m MockRepo) GetChats(ctx context.Context, userID uint32, lastUpdateTime ti func (m MockRepo) GetMessages( ctx context.Context, userID uint32, chatID uint32, lastSentTime time.Time, -) ([]*models.Message, error) { +) ([]*models.MessageDto, error) { if userID == 0 || chatID == 0 { return nil, errMock } - return []*models.Message{ + return []*models.MessageDto{ {CreatedAt: createTime}, }, nil } func (m MockRepo) SendNewMessage( - ctx context.Context, receiver uint32, sender uint32, message *models.MessageContent, + ctx context.Context, receiver uint32, sender uint32, message *models.MessageContentDto, ) error { if receiver == 0 || sender == 0 || message.Text == "" { return errMock @@ -119,7 +119,7 @@ func TestGetChat(t *testing.T) { type TestStructSendNewMessage struct { sender uint32 receiver uint32 - message *models.MessageContent + message *models.MessageContentDto wantErr error } @@ -129,25 +129,25 @@ func TestSendNewMessage(t *testing.T) { { sender: 0, receiver: 10, - message: &models.MessageContent{Text: "hello"}, + message: &models.MessageContentDto{Text: "hello"}, wantErr: errMock, }, { sender: 10, receiver: 0, - message: &models.MessageContent{Text: "hello"}, + message: &models.MessageContentDto{Text: "hello"}, wantErr: errMock, }, { sender: 1, receiver: 10, - message: &models.MessageContent{Text: ""}, + message: &models.MessageContentDto{Text: ""}, wantErr: errMock, }, { sender: 1, receiver: 10, - message: &models.MessageContent{Text: "hello"}, + message: &models.MessageContentDto{Text: "hello"}, wantErr: nil, }, } diff --git a/internal/chat/usecase.go b/internal/chat/usecase.go index 8c3e7ab6..7449ea1b 100644 --- a/internal/chat/usecase.go +++ b/internal/chat/usecase.go @@ -10,5 +10,5 @@ import ( type ChatService interface { GetAllChats(ctx context.Context, userID uint32, lastUpdateTime time.Time) ([]*models.Chat, error) GetChat(ctx context.Context, userID uint32, chatID uint32, lastSentTime time.Time) ([]*models.Message, error) - SendNewMessage(ctx context.Context, receiver uint32, sender uint32, message *models.MessageContent) error + SendNewMessage(ctx context.Context, receiver uint32, sender uint32, message *models.MessageContentDto) error } diff --git a/internal/ext_grpc/adapter/post/post_test.go b/internal/ext_grpc/adapter/post/post_test.go index d4f2a8c6..0ba0a3dd 100644 --- a/internal/ext_grpc/adapter/post/post_test.go +++ b/internal/ext_grpc/adapter/post/post_test.go @@ -65,6 +65,7 @@ func TestGetAuthorsPost(t *testing.T) { Text: "new post", CreatedAt: time.Unix(createTime.Unix(), 0), UpdatedAt: time.Unix(createTime.Unix(), 0), + File: []models.Picture{}, }, Header: models.Header{ AuthorID: 1, @@ -75,51 +76,55 @@ func TestGetAuthorsPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request *models.Header, m *mocks) { m.client.EXPECT().GetAuthorsPosts(gomock.Any(), gomock.Any()). - Return(&post_api.Response{ - Posts: []*post_api.Post{ - { - ID: 1, - PostContent: &post_api.Content{ - Text: "new post", - CreatedAt: createTime.Unix(), - UpdatedAt: createTime.Unix(), - }, - Head: &post_api.Header{ - AuthorID: 1, + Return( + &post_api.Response{ + Posts: []*post_api.Post{ + { + ID: 1, + PostContent: &post_api.Content{ + Text: "new post", + CreatedAt: createTime.Unix(), + UpdatedAt: createTime.Unix(), + }, + Head: &post_api.Header{ + AuthorID: 1, + }, }, }, - }, - }, nil) + }, nil, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - adapter, mock := getAdapter(ctrl) - ctx := context.Background() + adapter, mock := getAdapter(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(input, mock) + v.SetupMock(input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, adapter, input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, adapter, input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } diff --git a/internal/ext_grpc/port/post/post.go b/internal/ext_grpc/port/post/post.go index 9a373296..a5c5264b 100644 --- a/internal/ext_grpc/port/post/post.go +++ b/internal/ext_grpc/port/post/post.go @@ -22,6 +22,11 @@ func NewRequest(header *models.Header, userID uint32) *post_api.Request { func UnmarshalResponse(response *post_api.Response) []*models.Post { res := make([]*models.Post, 0, len(response.Posts)) for _, post := range response.Posts { + files := make([]models.Picture, 0, len(post.PostContent.File)) + for _, file := range post.PostContent.File { + files = append(files, models.Picture(file)) + } + res = append( res, &models.Post{ ID: post.ID, @@ -33,7 +38,7 @@ func UnmarshalResponse(response *post_api.Response) []*models.Post { }, PostContent: models.Content{ Text: post.PostContent.Text, - File: models.Picture(post.PostContent.File), + File: files, CreatedAt: time.Unix(post.PostContent.CreatedAt, 0), UpdatedAt: time.Unix(post.PostContent.UpdatedAt, 0), }, diff --git a/internal/models/chat.go b/internal/models/chat.go index e73fddc0..e5dd5b7a 100644 --- a/internal/models/chat.go +++ b/internal/models/chat.go @@ -1,6 +1,7 @@ package models import ( + "strings" "time" ) @@ -17,8 +18,76 @@ type Message struct { CreatedAt time.Time `json:"created_at"` } +type MessageDto struct { + Sender uint32 + Receiver uint32 + Content MessageContentDto + CreatedAt time.Time +} + +func (m *Message) ToDto() MessageDto { + return MessageDto{ + Sender: m.Sender, + Receiver: m.Receiver, + Content: m.Content.ToDto(), + CreatedAt: m.CreatedAt, + } +} + +func (m *MessageDto) FromDto() Message { + return Message{ + Sender: m.Sender, + Receiver: m.Receiver, + Content: m.Content.FromDto(), + CreatedAt: m.CreatedAt, + } +} + type MessageContent struct { - Text string `json:"text"` - FilePath string `json:"file_path"` - StickerPath string `json:"sticker_path"` + Text string `json:"text"` + FilePath []string `json:"file_path"` + StickerPath string `json:"sticker_path"` +} + +type MessageContentDto struct { + Text string + FilePath string + StickerPath string +} + +func (mc *MessageContent) ToDto() MessageContentDto { + files := make([]string, 0, len(mc.FilePath)) + for _, f := range mc.FilePath { + if f == "" { + continue + } + files = append(files, f) + } + + return MessageContentDto{ + Text: mc.Text, + FilePath: strings.Join(files, "||;||"), + StickerPath: mc.StickerPath, + } +} + +func (mc *MessageContentDto) FromDto() MessageContent { + files := strings.Split(mc.FilePath, "||;||") + contentFiles := make([]string, 0, len(files)) + for _, f := range files { + if f == "" { + continue + } + contentFiles = append(contentFiles, f) + } + + if len(contentFiles) == 0 { + contentFiles = nil + } + + return MessageContent{ + Text: mc.Text, + FilePath: contentFiles, + StickerPath: mc.StickerPath, + } } diff --git a/internal/models/chat_test.go b/internal/models/chat_test.go new file mode 100644 index 00000000..2004900c --- /dev/null +++ b/internal/models/chat_test.go @@ -0,0 +1,85 @@ +package models + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +type TestCaseMessageContent struct { + content MessageContent + contentDto MessageContentDto +} + +func TestFromDtoMessageContent(t *testing.T) { + tests := []TestCaseMessageContent{ + {content: MessageContent{}, contentDto: MessageContentDto{}}, + {content: MessageContent{Text: "text"}, contentDto: MessageContentDto{Text: "text"}}, + {content: MessageContent{FilePath: []string{"image"}}, contentDto: MessageContentDto{FilePath: "image"}}, + { + content: MessageContent{FilePath: []string{"image", "second image"}}, + contentDto: MessageContentDto{FilePath: "image||;||second image"}, + }, + } + + for _, test := range tests { + res := test.contentDto.FromDto() + assert.Equal(t, test.content, res) + } +} + +func TestToDtoMessageContent(t *testing.T) { + tests := []TestCaseMessageContent{ + {content: MessageContent{}, contentDto: MessageContentDto{}}, + {content: MessageContent{Text: "text"}, contentDto: MessageContentDto{Text: "text"}}, + {content: MessageContent{FilePath: []string{"image"}}, contentDto: MessageContentDto{FilePath: "image"}}, + { + content: MessageContent{FilePath: []string{"image", "second image"}}, + contentDto: MessageContentDto{FilePath: "image||;||second image"}, + }, + { + content: MessageContent{FilePath: []string{""}}, + contentDto: MessageContentDto{FilePath: ""}, + }, + } + + for _, test := range tests { + res := test.content.ToDto() + assert.Equal(t, test.contentDto, res) + } +} + +type TestCaseMessage struct { + message Message + messageDto MessageDto +} + +func TestMessageFromDto(t *testing.T) { + tests := []TestCaseMessage{ + {message: Message{}, messageDto: MessageDto{}}, + { + message: Message{Content: MessageContent{FilePath: []string{"image"}}}, + messageDto: MessageDto{Content: MessageContentDto{FilePath: "image"}}, + }, + } + + for _, test := range tests { + res := test.messageDto.FromDto() + assert.Equal(t, test.message, res) + } +} + +func TestMessageToDto(t *testing.T) { + tests := []TestCaseMessage{ + {message: Message{}, messageDto: MessageDto{}}, + { + message: Message{Content: MessageContent{FilePath: []string{"image"}}}, + messageDto: MessageDto{Content: MessageContentDto{FilePath: "image"}}, + }, + } + + for _, test := range tests { + res := test.message.ToDto() + assert.Equal(t, test.messageDto, res) + } +} diff --git a/internal/models/content.go b/internal/models/content.go index 2629c5ce..def50fda 100644 --- a/internal/models/content.go +++ b/internal/models/content.go @@ -1,12 +1,59 @@ package models import ( + "strings" "time" ) type Content struct { Text string `json:"text"` - File Picture `json:"file,omitempty"` + File []Picture `json:"file,omitempty"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } + +func (c *Content) ToDto() ContentDto { + files := make([]string, 0, len(c.File)) + for _, f := range c.File { + if f == "" { + continue + } + files = append(files, string(f)) + } + + return ContentDto{ + Text: c.Text, + File: Picture(strings.Join(files, "||;||")), + CreatedAt: c.CreatedAt, + UpdatedAt: c.UpdatedAt, + } +} + +type ContentDto struct { + Text string + File Picture + CreatedAt time.Time + UpdatedAt time.Time +} + +func (c *ContentDto) FromDto() Content { + files := strings.Split(string(c.File), "||;||") + contentFiles := make([]Picture, 0, len(files)) + for _, f := range files { + if f == "" { + continue + } + contentFiles = append(contentFiles, Picture(f)) + } + + if len(contentFiles) == 0 { + contentFiles = nil + } + + return Content{ + Text: c.Text, + File: contentFiles, + CreatedAt: c.CreatedAt, + UpdatedAt: c.UpdatedAt, + } +} diff --git a/internal/models/content_test.go b/internal/models/content_test.go new file mode 100644 index 00000000..be7353c5 --- /dev/null +++ b/internal/models/content_test.go @@ -0,0 +1,50 @@ +package models + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +type TestCase struct { + content Content + contentDto ContentDto +} + +func TestFromDto(t *testing.T) { + tests := []TestCase{ + {content: Content{}, contentDto: ContentDto{}}, + {content: Content{Text: "text"}, contentDto: ContentDto{Text: "text"}}, + {content: Content{File: []Picture{"image"}}, contentDto: ContentDto{File: "image"}}, + { + content: Content{File: []Picture{"image", "second image"}}, + contentDto: ContentDto{File: "image||;||second image"}, + }, + } + + for _, test := range tests { + res := test.contentDto.FromDto() + assert.Equal(t, test.content, res) + } +} + +func TestToDto(t *testing.T) { + tests := []TestCase{ + {content: Content{}, contentDto: ContentDto{}}, + {content: Content{Text: "text"}, contentDto: ContentDto{Text: "text"}}, + {content: Content{File: []Picture{"image"}}, contentDto: ContentDto{File: "image"}}, + { + content: Content{File: []Picture{"image", "second image"}}, + contentDto: ContentDto{File: "image||;||second image"}, + }, + { + content: Content{File: []Picture{""}}, + contentDto: ContentDto{File: ""}, + }, + } + + for _, test := range tests { + res := test.content.ToDto() + assert.Equal(t, test.contentDto, res) + } +} diff --git a/internal/models/post.go b/internal/models/post.go index 85f99c75..d7ad6845 100644 --- a/internal/models/post.go +++ b/internal/models/post.go @@ -9,6 +9,37 @@ type Post struct { CommentCount uint32 `json:"comment_count"` } +func (p *Post) ToDto() PostDto { + return PostDto{ + ID: p.ID, + Header: p.Header, + PostContent: p.PostContent.ToDto(), + LikesCount: p.LikesCount, + IsLiked: p.IsLiked, + CommentCount: p.CommentCount, + } +} + +type PostDto struct { + ID uint32 + Header Header + PostContent ContentDto + LikesCount uint32 + IsLiked bool + CommentCount uint32 +} + +func (p *PostDto) FromDto() Post { + return Post{ + ID: p.ID, + Header: p.Header, + PostContent: p.PostContent.FromDto(), + LikesCount: p.LikesCount, + IsLiked: p.IsLiked, + CommentCount: p.CommentCount, + } +} + type Header struct { AuthorID uint32 `json:"author_id"` CommunityID uint32 `json:"community_id"` @@ -23,3 +54,31 @@ type Comment struct { LikesCount uint32 `json:"likes_count"` IsLiked bool `json:"is_liked"` } + +func (c *Comment) ToDto() CommentDto { + return CommentDto{ + ID: c.ID, + Header: c.Header, + Content: c.Content.ToDto(), + LikesCount: c.LikesCount, + IsLiked: c.IsLiked, + } +} + +type CommentDto struct { + ID uint32 + Header Header + Content ContentDto + LikesCount uint32 + IsLiked bool +} + +func (c *CommentDto) FromDto() Comment { + return Comment{ + ID: c.ID, + Header: c.Header, + Content: c.Content.FromDto(), + LikesCount: c.LikesCount, + IsLiked: c.IsLiked, + } +} diff --git a/internal/models/post_test.go b/internal/models/post_test.go new file mode 100644 index 00000000..02a7663c --- /dev/null +++ b/internal/models/post_test.go @@ -0,0 +1,87 @@ +package models + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +type TestCasePost struct { + post Post + postDto PostDto +} + +func TestPostFromDto(t *testing.T) { + tests := []TestCasePost{ + {post: Post{}, postDto: PostDto{}}, + {post: Post{PostContent: Content{Text: "text"}}, postDto: PostDto{PostContent: ContentDto{Text: "text"}}}, + { + post: Post{PostContent: Content{File: []Picture{"image"}}}, + postDto: PostDto{PostContent: ContentDto{File: "image"}}, + }, + { + post: Post{PostContent: Content{File: []Picture{"image", "second image"}}}, + postDto: PostDto{PostContent: ContentDto{File: "image||;||second image"}}, + }, + } + + for _, test := range tests { + res := test.postDto.FromDto() + assert.Equal(t, test.post, res) + } +} + +func TestPostToDto(t *testing.T) { + tests := []TestCasePost{ + {post: Post{}, postDto: PostDto{}}, + {post: Post{PostContent: Content{Text: "text"}}, postDto: PostDto{PostContent: ContentDto{Text: "text"}}}, + { + post: Post{PostContent: Content{File: []Picture{"image"}}}, + postDto: PostDto{PostContent: ContentDto{File: "image"}}, + }, + { + post: Post{PostContent: Content{File: []Picture{"image", "second image"}}}, + postDto: PostDto{PostContent: ContentDto{File: "image||;||second image"}}, + }, + } + + for _, test := range tests { + res := test.post.ToDto() + assert.Equal(t, test.postDto, res) + } +} + +type TestCaseComment struct { + comment Comment + commentDto CommentDto +} + +func TestCommentFromDto(t *testing.T) { + tests := []TestCaseComment{ + {comment: Comment{}, commentDto: CommentDto{}}, + { + comment: Comment{Content: Content{File: []Picture{"image"}}}, + commentDto: CommentDto{Content: ContentDto{File: "image"}}, + }, + } + + for _, test := range tests { + res := test.commentDto.FromDto() + assert.Equal(t, test.comment, res) + } +} + +func TestCommentToDto(t *testing.T) { + tests := []TestCaseComment{ + {comment: Comment{}, commentDto: CommentDto{}}, + { + comment: Comment{Content: Content{File: []Picture{"image"}}}, + commentDto: CommentDto{Content: ContentDto{File: "image"}}, + }, + } + + for _, test := range tests { + res := test.comment.ToDto() + assert.Equal(t, test.commentDto, res) + } +} diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index 4c0ee3b5..24c8acd2 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -21,22 +21,22 @@ import ( const ( postIDkey = "id" commentIDKey = "comment_id" - imagePrefix = "/image/" - filePrefix = "/files/" + imagePrefix = "/image/" + filePrefix = "/files/" ) //go:generate mockgen -destination=mock.go -source=$GOFILE -package=${GOPACKAGE} type PostService interface { - Create(ctx context.Context, post *models.Post) (uint32, error) - Get(ctx context.Context, postID, userID uint32) (*models.Post, error) - Update(ctx context.Context, post *models.Post) error + Create(ctx context.Context, post *models.PostDto) (uint32, error) + Get(ctx context.Context, postID, userID uint32) (*models.PostDto, error) + Update(ctx context.Context, post *models.PostDto) error Delete(ctx context.Context, postID uint32) error - GetBatch(ctx context.Context, lastID, userID uint32) ([]*models.Post, error) - GetBatchFromFriend(ctx context.Context, userID uint32, lastID uint32) ([]*models.Post, error) + GetBatch(ctx context.Context, lastID, userID uint32) ([]*models.PostDto, error) + GetBatchFromFriend(ctx context.Context, userID uint32, lastID uint32) ([]*models.PostDto, error) GetPostAuthorID(ctx context.Context, postID uint32) (uint32, error) - GetCommunityPost(ctx context.Context, communityID, userID, lastID uint32) ([]*models.Post, error) - CreateCommunityPost(ctx context.Context, post *models.Post) (uint32, error) + GetCommunityPost(ctx context.Context, communityID, userID, lastID uint32) ([]*models.PostDto, error) + CreateCommunityPost(ctx context.Context, post *models.PostDto) (uint32, error) CheckAccessToCommunity(ctx context.Context, userID uint32, communityID uint32) bool SetLikeToPost(ctx context.Context, postID uint32, userID uint32) error @@ -45,10 +45,10 @@ type PostService interface { } type CommentService interface { - Comment(ctx context.Context, userID, postID uint32, comment *models.Content) (*models.Comment, error) + Comment(ctx context.Context, userID, postID uint32, comment *models.ContentDto) (*models.CommentDto, error) DeleteComment(ctx context.Context, commentID, userID uint32) error - EditComment(ctx context.Context, commentID, userID uint32, comment *models.Content) error - GetComments(ctx context.Context, postID, lastID uint32, newest bool) ([]*models.Comment, error) + EditComment(ctx context.Context, commentID, userID uint32, comment *models.ContentDto) error + GetComments(ctx context.Context, postID, lastID uint32, newest bool) ([]*models.CommentDto, error) } type Responder interface { @@ -92,10 +92,6 @@ func (pc *PostController) Create(w http.ResponseWriter, r *http.Request) { return } - if !validateContent(newPost.PostContent) { - pc.responder.ErrorBadRequest(w, my_err.ErrTextTooLong, reqID) - return - } if comunity != "" { comID, err := strconv.ParseUint(comunity, 10, 32) if err != nil { @@ -123,7 +119,7 @@ func (pc *PostController) Create(w http.ResponseWriter, r *http.Request) { newPost.ID = id - pc.responder.OutputJSON(w, newPost, reqID) + pc.responder.OutputJSON(w, newPost.FromDto(), reqID) } func (pc *PostController) GetOne(w http.ResponseWriter, r *http.Request) { @@ -156,7 +152,7 @@ func (pc *PostController) GetOne(w http.ResponseWriter, r *http.Request) { } } - pc.responder.OutputJSON(w, post, reqID) + pc.responder.OutputJSON(w, post.FromDto(), reqID) } func (pc *PostController) Update(w http.ResponseWriter, r *http.Request) { @@ -197,11 +193,6 @@ func (pc *PostController) Update(w http.ResponseWriter, r *http.Request) { pc.responder.ErrorBadRequest(w, err, reqID) return } - - if !validateContent(post.PostContent) { - pc.responder.ErrorBadRequest(w, my_err.ErrTextTooLong, reqID) - return - } post.ID = id if err := pc.postService.Update(r.Context(), post); err != nil { @@ -213,7 +204,7 @@ func (pc *PostController) Update(w http.ResponseWriter, r *http.Request) { return } - pc.responder.OutputJSON(w, post, reqID) + pc.responder.OutputJSON(w, post.FromDto(), reqID) } func (pc *PostController) Delete(w http.ResponseWriter, r *http.Request) { @@ -266,7 +257,7 @@ func (pc *PostController) GetBatchPosts(w http.ResponseWriter, r *http.Request) reqID, ok = r.Context().Value(middleware.RequestKey).(string) section = r.URL.Query().Get("section") communityID = r.URL.Query().Get("community") - posts []*models.Post + posts []*models.PostDto intLastID uint64 err error id uint64 @@ -322,10 +313,15 @@ func (pc *PostController) GetBatchPosts(w http.ResponseWriter, r *http.Request) } } - pc.responder.OutputJSON(w, posts, reqID) + res := make([]models.Post, 0, len(posts)) + for _, post := range posts { + res = append(res, post.FromDto()) + } + + pc.responder.OutputJSON(w, res, reqID) } -func (pc *PostController) getPostFromBody(r *http.Request) (*models.Post, error) { +func (pc *PostController) getPostFromBody(r *http.Request) (*models.PostDto, error) { var newPost models.Post err := json.NewDecoder(r.Body).Decode(&newPost) @@ -333,13 +329,18 @@ func (pc *PostController) getPostFromBody(r *http.Request) (*models.Post, error) return nil, err } + if !validateContent(newPost.PostContent) { + return nil, my_err.ErrTextTooLong + } + sess, err := models.SessionFromContext(r.Context()) if err != nil { return nil, err } newPost.Header.AuthorID = sess.UserID + post := newPost.ToDto() - return &newPost, nil + return &post, nil } func getIDFromURL(r *http.Request, key string) (uint32, error) { @@ -506,14 +507,15 @@ func (pc *PostController) Comment(w http.ResponseWriter, r *http.Request) { return } - newComment, err := pc.commentService.Comment(r.Context(), sess.UserID, postID, &content) + contentDto := content.ToDto() + newComment, err := pc.commentService.Comment(r.Context(), sess.UserID, postID, &contentDto) if err != nil { pc.responder.ErrorInternal(w, err, reqID) return } newComment.Content.CreatedAt = time.Now() - pc.responder.OutputJSON(w, newComment, reqID) + pc.responder.OutputJSON(w, newComment.FromDto(), reqID) } func (pc *PostController) DeleteComment(w http.ResponseWriter, r *http.Request) { @@ -582,7 +584,8 @@ func (pc *PostController) EditComment(w http.ResponseWriter, r *http.Request) { return } - if err := pc.commentService.EditComment(r.Context(), commentID, sess.UserID, &content); err != nil { + contentDto := content.ToDto() + if err := pc.commentService.EditComment(r.Context(), commentID, sess.UserID, &contentDto); err != nil { if errors.Is(err, my_err.ErrAccessDenied) { pc.responder.ErrorBadRequest(w, err, reqID) return @@ -637,13 +640,31 @@ func (pc *PostController) GetComments(w http.ResponseWriter, r *http.Request) { return } - pc.responder.OutputJSON(w, comments, reqID) + res := make([]models.Comment, 0, len(comments)) + for _, comment := range comments { + res = append(res, comment.FromDto()) + } + + pc.responder.OutputJSON(w, res, reqID) } func validateContent(content models.Content) bool { return validateFile(content.File) && len(content.Text) < 500 } -func validateFile(filepath models.Picture) bool { - return len(filepath) < 100 && (len(filepath) == 0 || strings.HasPrefix(string(filepath), filePrefix) || strings.HasPrefix(string(filepath), imagePrefix)) +func validateFile(filepaths []models.Picture) bool { + if len(filepaths) > 10 { + return false + } + + for _, f := range filepaths { + if len(f) > 100 { + return false + } + if !(strings.HasPrefix(string(f), filePrefix) || strings.HasPrefix(string(f), imagePrefix)) { + return false + } + } + + return true } diff --git a/internal/post/controller/controller_test.go b/internal/post/controller/controller_test.go index 43eaeeab..4a6692b1 100644 --- a/internal/post/controller/controller_test.go +++ b/internal/post/controller/controller_test.go @@ -515,7 +515,7 @@ func TestGetOne(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.postService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) + m.postService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(&models.PostDto{}, nil) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( func(w, err, req any) { request.w.WriteHeader(http.StatusOK) @@ -1585,7 +1585,13 @@ func TestGetBatchPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetCommunityPost( gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), - ).Return(nil, nil) + ).Return( + []*models.PostDto{ + { + ID: 1, + }, + }, nil, + ) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( func(w, err, req any) { request.w.WriteHeader(http.StatusOK) @@ -2255,8 +2261,8 @@ func TestComment(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.commentService.EXPECT().Comment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return( - &models.Comment{ - Content: models.Content{ + &models.CommentDto{ + Content: models.ContentDto{ Text: "New comment", }, }, nil, @@ -2274,7 +2280,7 @@ func TestComment(t *testing.T) { SetupInput: func() (*Request, error) { req := httptest.NewRequest( http.MethodPost, "/api/v1/feed/2", - bytes.NewBuffer([]byte(`{"file":"очень большой текст, написанный в поле файл, как он сюда попал - честно говоря хз, надо проверить валидацию на файл длину"}`)), + bytes.NewBuffer([]byte(`{"file":["очень большой текст, написанный в поле файл, как он сюда попал - честно говоря хз, надо проверить валидацию на файл длину"]}`)), ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "2"}) @@ -2333,7 +2339,7 @@ func TestComment(t *testing.T) { } } -func TestGetComment(t *testing.T) { +func TestGetComments(t *testing.T) { tests := []TableTest[Response, Request]{ { name: "1", @@ -2441,7 +2447,12 @@ func TestGetComment(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.commentService.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(nil, nil) + Return( + []*models.CommentDto{ + {ID: 1}, + }, + nil, + ) m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( func(w, data, req any) { request.w.WriteHeader(http.StatusOK) @@ -2727,7 +2738,39 @@ func TestEditComment(t *testing.T) { SetupInput: func() (*Request, error) { req := httptest.NewRequest( http.MethodPut, "/api/v1/feed/2/1", - bytes.NewBuffer([]byte(`{"file":"очень большой текст, написанный в поле файл, как он сюда попал - честно говоря хз, надо проверить валидацию на файл длину"}`)), + bytes.NewBuffer([]byte(`{"file":["","", "", "", "", "", "", "", "", "", "", "", ""]}`)), + ) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "9", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/2/1", + bytes.NewBuffer([]byte(`{"file":["my wrong file"]}`)), ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) diff --git a/internal/post/controller/mock.go b/internal/post/controller/mock.go index 67592057..2b4ded61 100644 --- a/internal/post/controller/mock.go +++ b/internal/post/controller/mock.go @@ -72,7 +72,7 @@ func (mr *MockPostServiceMockRecorder) CheckLikes(ctx, postID, userID any) *gomo } // Create mocks base method. -func (m *MockPostService) Create(ctx context.Context, post *models.Post) (uint32, error) { +func (m *MockPostService) Create(ctx context.Context, post *models.PostDto) (uint32, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Create", ctx, post) ret0, _ := ret[0].(uint32) @@ -87,7 +87,7 @@ func (mr *MockPostServiceMockRecorder) Create(ctx, post any) *gomock.Call { } // CreateCommunityPost mocks base method. -func (m *MockPostService) CreateCommunityPost(ctx context.Context, post *models.Post) (uint32, error) { +func (m *MockPostService) CreateCommunityPost(ctx context.Context, post *models.PostDto) (uint32, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateCommunityPost", ctx, post) ret0, _ := ret[0].(uint32) @@ -130,10 +130,10 @@ func (mr *MockPostServiceMockRecorder) DeleteLikeFromPost(ctx, postID, userID an } // Get mocks base method. -func (m *MockPostService) Get(ctx context.Context, postID, userID uint32) (*models.Post, error) { +func (m *MockPostService) Get(ctx context.Context, postID, userID uint32) (*models.PostDto, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Get", ctx, postID, userID) - ret0, _ := ret[0].(*models.Post) + ret0, _ := ret[0].(*models.PostDto) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -145,10 +145,10 @@ func (mr *MockPostServiceMockRecorder) Get(ctx, postID, userID any) *gomock.Call } // GetBatch mocks base method. -func (m *MockPostService) GetBatch(ctx context.Context, lastID, userID uint32) ([]*models.Post, error) { +func (m *MockPostService) GetBatch(ctx context.Context, lastID, userID uint32) ([]*models.PostDto, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBatch", ctx, lastID, userID) - ret0, _ := ret[0].([]*models.Post) + ret0, _ := ret[0].([]*models.PostDto) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -160,10 +160,10 @@ func (mr *MockPostServiceMockRecorder) GetBatch(ctx, lastID, userID any) *gomock } // GetBatchFromFriend mocks base method. -func (m *MockPostService) GetBatchFromFriend(ctx context.Context, userID, lastID uint32) ([]*models.Post, error) { +func (m *MockPostService) GetBatchFromFriend(ctx context.Context, userID, lastID uint32) ([]*models.PostDto, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBatchFromFriend", ctx, userID, lastID) - ret0, _ := ret[0].([]*models.Post) + ret0, _ := ret[0].([]*models.PostDto) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -175,10 +175,10 @@ func (mr *MockPostServiceMockRecorder) GetBatchFromFriend(ctx, userID, lastID an } // GetCommunityPost mocks base method. -func (m *MockPostService) GetCommunityPost(ctx context.Context, communityID, userID, lastID uint32) ([]*models.Post, error) { +func (m *MockPostService) GetCommunityPost(ctx context.Context, communityID, userID, lastID uint32) ([]*models.PostDto, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetCommunityPost", ctx, communityID, userID, lastID) - ret0, _ := ret[0].([]*models.Post) + ret0, _ := ret[0].([]*models.PostDto) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -219,7 +219,7 @@ func (mr *MockPostServiceMockRecorder) SetLikeToPost(ctx, postID, userID any) *g } // Update mocks base method. -func (m *MockPostService) Update(ctx context.Context, post *models.Post) error { +func (m *MockPostService) Update(ctx context.Context, post *models.PostDto) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Update", ctx, post) ret0, _ := ret[0].(error) @@ -257,10 +257,10 @@ func (m *MockCommentService) EXPECT() *MockCommentServiceMockRecorder { } // Comment mocks base method. -func (m *MockCommentService) Comment(ctx context.Context, userID, postID uint32, comment *models.Content) (*models.Comment, error) { +func (m *MockCommentService) Comment(ctx context.Context, userID, postID uint32, comment *models.ContentDto) (*models.CommentDto, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Comment", ctx, userID, postID, comment) - ret0, _ := ret[0].(*models.Comment) + ret0, _ := ret[0].(*models.CommentDto) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -286,7 +286,7 @@ func (mr *MockCommentServiceMockRecorder) DeleteComment(ctx, commentID, userID a } // EditComment mocks base method. -func (m *MockCommentService) EditComment(ctx context.Context, commentID, userID uint32, comment *models.Content) error { +func (m *MockCommentService) EditComment(ctx context.Context, commentID, userID uint32, comment *models.ContentDto) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "EditComment", ctx, commentID, userID, comment) ret0, _ := ret[0].(error) @@ -300,10 +300,10 @@ func (mr *MockCommentServiceMockRecorder) EditComment(ctx, commentID, userID, co } // GetComments mocks base method. -func (m *MockCommentService) GetComments(ctx context.Context, postID, lastID uint32, newest bool) ([]*models.Comment, error) { +func (m *MockCommentService) GetComments(ctx context.Context, postID, lastID uint32, newest bool) ([]*models.CommentDto, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetComments", ctx, postID, lastID, newest) - ret0, _ := ret[0].([]*models.Comment) + ret0, _ := ret[0].([]*models.CommentDto) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/internal/post/repository/postgres/postgres.go b/internal/post/repository/postgres/postgres.go index ce2fcbf2..3a0bbaa5 100644 --- a/internal/post/repository/postgres/postgres.go +++ b/internal/post/repository/postgres/postgres.go @@ -48,7 +48,7 @@ func NewAdapter(db *sql.DB) *Adapter { } } -func (a *Adapter) Create(ctx context.Context, post *models.Post) (uint32, error) { +func (a *Adapter) Create(ctx context.Context, post *models.PostDto) (uint32, error) { var postID uint32 if err := a.db.QueryRowContext( @@ -60,8 +60,8 @@ func (a *Adapter) Create(ctx context.Context, post *models.Post) (uint32, error) return postID, nil } -func (a *Adapter) Get(ctx context.Context, postID uint32) (*models.Post, error) { - var post models.Post +func (a *Adapter) Get(ctx context.Context, postID uint32) (*models.PostDto, error) { + var post models.PostDto if err := a.db.QueryRowContext(ctx, getPost, postID). Scan( @@ -97,7 +97,7 @@ func (a *Adapter) Delete(ctx context.Context, postID uint32) error { return nil } -func (a *Adapter) Update(ctx context.Context, post *models.Post) error { +func (a *Adapter) Update(ctx context.Context, post *models.PostDto) error { res, err := a.db.ExecContext( ctx, updatePost, post.PostContent.Text, post.PostContent.UpdatedAt, post.PostContent.File, post.ID, ) @@ -118,7 +118,7 @@ func (a *Adapter) Update(ctx context.Context, post *models.Post) error { return nil } -func (a *Adapter) GetPosts(ctx context.Context, lastID uint32) ([]*models.Post, error) { +func (a *Adapter) GetPosts(ctx context.Context, lastID uint32) ([]*models.PostDto, error) { rows, err := a.db.QueryContext(ctx, getPostBatch, lastID) if err != nil { if errors.Is(err, sql.ErrNoRows) { @@ -128,10 +128,10 @@ func (a *Adapter) GetPosts(ctx context.Context, lastID uint32) ([]*models.Post, } defer rows.Close() - var posts []*models.Post + var posts []*models.PostDto for rows.Next() { - var post models.Post + var post models.PostDto if err := rows.Scan( &post.ID, &post.Header.AuthorID, &post.Header.CommunityID, &post.PostContent.Text, &post.PostContent.File, &post.PostContent.CreatedAt, @@ -148,7 +148,7 @@ func (a *Adapter) GetPosts(ctx context.Context, lastID uint32) ([]*models.Post, return posts, nil } -func (a *Adapter) GetFriendsPosts(ctx context.Context, friendsID []uint32, lastID uint32) ([]*models.Post, error) { +func (a *Adapter) GetFriendsPosts(ctx context.Context, friendsID []uint32, lastID uint32) ([]*models.PostDto, error) { friends := convertSliceToString(friendsID) rows, err := a.db.QueryContext(ctx, getFriendsPost, lastID, friends) if rows != nil { @@ -165,8 +165,8 @@ func (a *Adapter) GetFriendsPosts(ctx context.Context, friendsID []uint32, lastI return createPostBatchFromRows(rows) } -func (a *Adapter) GetAuthorPosts(ctx context.Context, header *models.Header) ([]*models.Post, error) { - var posts []*models.Post +func (a *Adapter) GetAuthorPosts(ctx context.Context, header *models.Header) ([]*models.PostDto, error) { + var posts []*models.PostDto rows, err := a.db.QueryContext(ctx, getProfilePosts, header.AuthorID) @@ -180,7 +180,7 @@ func (a *Adapter) GetAuthorPosts(ctx context.Context, header *models.Header) ([] defer rows.Close() for rows.Next() { - var post models.Post + var post models.PostDto err = rows.Scan(&post.ID, &post.PostContent.Text, &post.PostContent.File, &post.PostContent.CreatedAt) if err != nil { return nil, fmt.Errorf("postgres get author posts: %w", err) @@ -205,11 +205,11 @@ func (a *Adapter) GetPostAuthor(ctx context.Context, postID uint32) (uint32, err return authorID, nil } -func createPostBatchFromRows(rows *sql.Rows) ([]*models.Post, error) { - var posts []*models.Post +func createPostBatchFromRows(rows *sql.Rows) ([]*models.PostDto, error) { + var posts []*models.PostDto for rows.Next() { - var post models.Post + var post models.PostDto if err := rows.Scan( &post.ID, &post.Header.AuthorID, &post.PostContent.Text, &post.PostContent.File, &post.PostContent.CreatedAt, @@ -241,7 +241,7 @@ func convertSliceToString(sl []uint32) string { return res } -func (a *Adapter) CreateCommunityPost(ctx context.Context, post *models.Post, communityID uint32) (uint32, error) { +func (a *Adapter) CreateCommunityPost(ctx context.Context, post *models.PostDto, communityID uint32) (uint32, error) { var ID uint32 if err := a.db.QueryRowContext( ctx, createCommunityPost, communityID, post.PostContent.Text, post.PostContent.File, @@ -253,15 +253,15 @@ func (a *Adapter) CreateCommunityPost(ctx context.Context, post *models.Post, co } -func (a *Adapter) GetCommunityPosts(ctx context.Context, communityID, id uint32) ([]*models.Post, error) { - var posts []*models.Post +func (a *Adapter) GetCommunityPosts(ctx context.Context, communityID, id uint32) ([]*models.PostDto, error) { + var posts []*models.PostDto rows, err := a.db.QueryContext(ctx, getCommunityPosts, communityID, id) if err != nil { return nil, fmt.Errorf("postgres get community posts: %w", err) } defer rows.Close() for rows.Next() { - post := &models.Post{} + post := &models.PostDto{} err = rows.Scan( &post.ID, &post.Header.CommunityID, &post.PostContent.Text, &post.PostContent.File, &post.PostContent.CreatedAt, @@ -323,7 +323,9 @@ func (a *Adapter) CheckLikes(ctx context.Context, postID, userID uint32) (bool, return true, nil } -func (a *Adapter) CreateComment(ctx context.Context, comment *models.Content, userID, postID uint32) (uint32, error) { +func (a *Adapter) CreateComment( + ctx context.Context, comment *models.ContentDto, userID, postID uint32, +) (uint32, error) { var id uint32 if err := a.db.QueryRowContext( @@ -354,7 +356,7 @@ func (a *Adapter) DeleteComment(ctx context.Context, commentID uint32) error { return nil } -func (a *Adapter) UpdateComment(ctx context.Context, comment *models.Content, commentID uint32) error { +func (a *Adapter) UpdateComment(ctx context.Context, comment *models.ContentDto, commentID uint32) error { res, err := a.db.ExecContext( ctx, updateComment, comment.Text, comment.File, commentID, ) @@ -375,7 +377,7 @@ func (a *Adapter) UpdateComment(ctx context.Context, comment *models.Content, co return nil } -func (a *Adapter) GetComments(ctx context.Context, postID, lastID uint32, newest bool) ([]*models.Comment, error) { +func (a *Adapter) GetComments(ctx context.Context, postID, lastID uint32, newest bool) ([]*models.CommentDto, error) { var ( rows *sql.Rows err error @@ -394,9 +396,9 @@ func (a *Adapter) GetComments(ctx context.Context, postID, lastID uint32, newest return nil, fmt.Errorf("postgres get posts: %w", err) } - var comments []*models.Comment + var comments []*models.CommentDto for rows.Next() { - comment := models.Comment{} + comment := models.CommentDto{} if err := rows.Scan( &comment.ID, &comment.Header.AuthorID, &comment.Content.Text, &comment.Content.File, &comment.Content.CreatedAt, diff --git a/internal/post/repository/postgres/postgres_test.go b/internal/post/repository/postgres/postgres_test.go index 936b938c..7413f96a 100644 --- a/internal/post/repository/postgres/postgres_test.go +++ b/internal/post/repository/postgres/postgres_test.go @@ -21,7 +21,7 @@ type TestCaseGet struct { ID uint32 wantErr error dbErr error - wantPost *models.Post + wantPost *models.PostDto } func TestGet(t *testing.T) { @@ -33,11 +33,16 @@ func TestGet(t *testing.T) { var ID uint32 = 1 rows := sqlmock.NewRows([]string{"id", "author_id", "content", "file_path", "created_at"}) - expect := []*models.Post{ - {ID: ID, Header: models.Header{AuthorID: 1}, PostContent: models.Content{Text: "content from user 1", File: "http://somefile", CreatedAt: time.Now()}}, + expect := []*models.PostDto{ + { + ID: ID, Header: models.Header{AuthorID: 1}, + PostContent: models.ContentDto{Text: "content from user 1", File: "http://somefile", CreatedAt: time.Now()}, + }, } for _, post := range expect { - rows = rows.AddRow(ID, post.Header.AuthorID, post.PostContent.Text, post.PostContent.File, post.PostContent.CreatedAt) + rows = rows.AddRow( + ID, post.Header.AuthorID, post.PostContent.Text, post.PostContent.File, post.PostContent.CreatedAt, + ) } repo := NewAdapter(db) @@ -63,7 +68,7 @@ func TestGet(t *testing.T) { } type TestCaseCreate struct { - post *models.Post + post *models.PostDto wantID uint32 wantErr error dbErr error @@ -79,9 +84,22 @@ func TestCreate(t *testing.T) { repo := NewAdapter(db) tests := []TestCaseCreate{ - {post: &models.Post{Header: models.Header{AuthorID: 1}, PostContent: models.Content{Text: "content from user 1"}}, wantID: 1, wantErr: nil, dbErr: nil}, - {post: &models.Post{Header: models.Header{AuthorID: 2}, PostContent: models.Content{Text: "content from user 2", File: "http://someFile"}}, wantID: 2, wantErr: nil, dbErr: nil}, - {post: &models.Post{Header: models.Header{AuthorID: 10}, PostContent: models.Content{Text: "wrong query"}}, wantID: 0, wantErr: errMockDB, dbErr: errMockDB}, + { + post: &models.PostDto{ + Header: models.Header{AuthorID: 1}, PostContent: models.ContentDto{Text: "content from user 1"}, + }, wantID: 1, wantErr: nil, dbErr: nil, + }, + { + post: &models.PostDto{ + Header: models.Header{AuthorID: 2}, + PostContent: models.ContentDto{Text: "content from user 2", File: "http://someFile"}, + }, wantID: 2, wantErr: nil, dbErr: nil, + }, + { + post: &models.PostDto{ + Header: models.Header{AuthorID: 10}, PostContent: models.ContentDto{Text: "wrong query"}, + }, wantID: 0, wantErr: errMockDB, dbErr: errMockDB, + }, } for _, test := range tests { @@ -137,7 +155,7 @@ func TestDelete(t *testing.T) { } type TestCaseUpdate struct { - post *models.Post + post *models.PostDto rowsAffected int64 wantErr error dbErr error @@ -153,15 +171,32 @@ func TestUpdate(t *testing.T) { repo := NewAdapter(db) tests := []TestCaseUpdate{ - {post: &models.Post{ID: 1, PostContent: models.Content{Text: "update post", File: "http://someFile", UpdatedAt: time.Now()}}, wantErr: nil, dbErr: nil, rowsAffected: 1}, - {post: &models.Post{ID: 2, PostContent: models.Content{Text: "wrong ID", UpdatedAt: time.Now()}}, wantErr: my_err.ErrPostNotFound, dbErr: nil, rowsAffected: 0}, - {post: &models.Post{ID: 1, PostContent: models.Content{Text: "update post who was update early", UpdatedAt: time.Now()}}, wantErr: nil, dbErr: nil, rowsAffected: 1}, - {post: &models.Post{ID: 5, PostContent: models.Content{Text: "wrong query", UpdatedAt: time.Now()}}, wantErr: errMockDB, dbErr: errMockDB, rowsAffected: 0}, + { + post: &models.PostDto{ + ID: 1, + PostContent: models.ContentDto{Text: "update post", File: "http://someFile", UpdatedAt: time.Now()}, + }, wantErr: nil, dbErr: nil, rowsAffected: 1, + }, + { + post: &models.PostDto{ID: 2, PostContent: models.ContentDto{Text: "wrong ID", UpdatedAt: time.Now()}}, + wantErr: my_err.ErrPostNotFound, dbErr: nil, rowsAffected: 0, + }, + { + post: &models.PostDto{ + ID: 1, PostContent: models.ContentDto{Text: "update post who was update early", UpdatedAt: time.Now()}, + }, wantErr: nil, dbErr: nil, rowsAffected: 1, + }, + { + post: &models.PostDto{ID: 5, PostContent: models.ContentDto{Text: "wrong query", UpdatedAt: time.Now()}}, + wantErr: errMockDB, dbErr: errMockDB, rowsAffected: 0, + }, } for _, test := range tests { mock.ExpectExec(regexp.QuoteMeta(updatePost)). - WithArgs(test.post.PostContent.Text, test.post.PostContent.UpdatedAt, test.post.PostContent.File, test.post.ID). + WithArgs( + test.post.PostContent.Text, test.post.PostContent.UpdatedAt, test.post.PostContent.File, test.post.ID, + ). WillReturnResult(sqlmock.NewResult(0, test.rowsAffected)). WillReturnError(test.dbErr) @@ -212,7 +247,7 @@ func TestGetPostAuthor(t *testing.T) { type TestCaseGetAuthorPosts struct { Author *models.Header - wantPosts []*models.Post + wantPosts []*models.PostDto dbErr error wantErr error } @@ -230,16 +265,20 @@ func TestGetAuthorsPosts(t *testing.T) { tests := []TestCaseGetAuthorPosts{ { Author: &models.Header{AuthorID: 1}, - wantPosts: []*models.Post{ + wantPosts: []*models.PostDto{ { - ID: 1, - Header: models.Header{AuthorID: 1}, - PostContent: models.Content{Text: "content from user 1", File: "http://somefile", CreatedAt: createTime}, + ID: 1, + Header: models.Header{AuthorID: 1}, + PostContent: models.ContentDto{ + Text: "content from user 1", File: "http://somefile", CreatedAt: createTime, + }, }, { - ID: 2, - Header: models.Header{AuthorID: 1}, - PostContent: models.Content{Text: "another content from user 1", File: "http://somefile2", CreatedAt: createTime}, + ID: 2, + Header: models.Header{AuthorID: 1}, + PostContent: models.ContentDto{ + Text: "another content from user 1", File: "http://somefile2", CreatedAt: createTime, + }, }, }, wantErr: nil, @@ -247,8 +286,11 @@ func TestGetAuthorsPosts(t *testing.T) { }, { Author: &models.Header{AuthorID: 2}, - wantPosts: []*models.Post{ - {ID: 3, Header: models.Header{AuthorID: 2}, PostContent: models.Content{Text: "content from user 2", CreatedAt: createTime}}, + wantPosts: []*models.PostDto{ + { + ID: 3, Header: models.Header{AuthorID: 2}, + PostContent: models.ContentDto{Text: "content from user 2", CreatedAt: createTime}, + }, }, wantErr: nil, dbErr: nil, @@ -287,7 +329,7 @@ func TestGetAuthorsPosts(t *testing.T) { type TestCaseGetPosts struct { lastID uint32 - wantPost []*models.Post + wantPost []*models.PostDto dbErr error wantErr error } @@ -300,18 +342,51 @@ func TestGetPosts(t *testing.T) { defer db.Close() createTime := time.Now() - expect := []*models.Post{ - {ID: 1, Header: models.Header{AuthorID: 1}, PostContent: models.Content{Text: "content from user 1", CreatedAt: createTime}}, - {ID: 2, Header: models.Header{AuthorID: 1}, PostContent: models.Content{Text: "content from user 1", CreatedAt: createTime}}, - {ID: 3, Header: models.Header{AuthorID: 2}, PostContent: models.Content{Text: "content from user 2", CreatedAt: createTime}}, - {ID: 4, Header: models.Header{AuthorID: 2}, PostContent: models.Content{Text: "content from user 2", CreatedAt: createTime}}, - {ID: 5, Header: models.Header{AuthorID: 3}, PostContent: models.Content{Text: "content from user 3", CreatedAt: createTime}}, - {ID: 6, Header: models.Header{AuthorID: 3}, PostContent: models.Content{Text: "content from user 3", CreatedAt: createTime}}, - {ID: 7, Header: models.Header{AuthorID: 6}, PostContent: models.Content{Text: "content from user 6", CreatedAt: createTime}}, - {ID: 8, Header: models.Header{AuthorID: 4}, PostContent: models.Content{Text: "content from user 4", CreatedAt: createTime}}, - {ID: 9, Header: models.Header{AuthorID: 2}, PostContent: models.Content{Text: "content from user 2", CreatedAt: createTime}}, - {ID: 10, Header: models.Header{AuthorID: 1}, PostContent: models.Content{Text: "content from user 1", CreatedAt: createTime}}, - {ID: 11, Header: models.Header{AuthorID: 2}, PostContent: models.Content{Text: "content from user 2", CreatedAt: createTime}}, + expect := []*models.PostDto{ + { + ID: 1, Header: models.Header{AuthorID: 1}, + PostContent: models.ContentDto{Text: "content from user 1", CreatedAt: createTime}, + }, + { + ID: 2, Header: models.Header{AuthorID: 1}, + PostContent: models.ContentDto{Text: "content from user 1", CreatedAt: createTime}, + }, + { + ID: 3, Header: models.Header{AuthorID: 2}, + PostContent: models.ContentDto{Text: "content from user 2", CreatedAt: createTime}, + }, + { + ID: 4, Header: models.Header{AuthorID: 2}, + PostContent: models.ContentDto{Text: "content from user 2", CreatedAt: createTime}, + }, + { + ID: 5, Header: models.Header{AuthorID: 3}, + PostContent: models.ContentDto{Text: "content from user 3", CreatedAt: createTime}, + }, + { + ID: 6, Header: models.Header{AuthorID: 3}, + PostContent: models.ContentDto{Text: "content from user 3", CreatedAt: createTime}, + }, + { + ID: 7, Header: models.Header{AuthorID: 6}, + PostContent: models.ContentDto{Text: "content from user 6", CreatedAt: createTime}, + }, + { + ID: 8, Header: models.Header{AuthorID: 4}, + PostContent: models.ContentDto{Text: "content from user 4", CreatedAt: createTime}, + }, + { + ID: 9, Header: models.Header{AuthorID: 2}, + PostContent: models.ContentDto{Text: "content from user 2", CreatedAt: createTime}, + }, + { + ID: 10, Header: models.Header{AuthorID: 1}, + PostContent: models.ContentDto{Text: "content from user 1", CreatedAt: createTime}, + }, + { + ID: 11, Header: models.Header{AuthorID: 2}, + PostContent: models.ContentDto{Text: "content from user 2", CreatedAt: createTime}, + }, } repo := NewAdapter(db) @@ -336,7 +411,10 @@ func TestGetPosts(t *testing.T) { for _, test := range tests { rows := sqlmock.NewRows([]string{"id", "author_id", "community_id", "content", "file_path", "created_at"}) for _, post := range test.wantPost { - rows.AddRow(post.ID, post.Header.AuthorID, post.Header.CommunityID, post.PostContent.Text, post.PostContent.File, post.PostContent.CreatedAt) + rows.AddRow( + post.ID, post.Header.AuthorID, post.Header.CommunityID, post.PostContent.Text, post.PostContent.File, + post.PostContent.CreatedAt, + ) } mock.ExpectQuery(regexp.QuoteMeta(getPostBatch)). WithArgs(test.lastID). @@ -374,7 +452,7 @@ func TestConvertSliceToString(t *testing.T) { type GetFriendsPosts struct { lastID uint32 friendsID []uint32 - wantPost []*models.Post + wantPost []*models.PostDto wantErr error dbErr error } @@ -388,18 +466,51 @@ func TestGetFriendsPosts(t *testing.T) { createTime := time.Now() - expect := []*models.Post{ - {ID: 1, Header: models.Header{AuthorID: 1}, PostContent: models.Content{Text: "content from user 1", CreatedAt: createTime}}, - {ID: 2, Header: models.Header{AuthorID: 1}, PostContent: models.Content{Text: "content from user 1", CreatedAt: createTime}}, - {ID: 3, Header: models.Header{AuthorID: 2}, PostContent: models.Content{Text: "content from user 2", CreatedAt: createTime}}, - {ID: 4, Header: models.Header{AuthorID: 2}, PostContent: models.Content{Text: "content from user 2", CreatedAt: createTime}}, - {ID: 5, Header: models.Header{AuthorID: 3}, PostContent: models.Content{Text: "content from user 3", CreatedAt: createTime}}, - {ID: 6, Header: models.Header{AuthorID: 3}, PostContent: models.Content{Text: "content from user 3", CreatedAt: createTime}}, - {ID: 7, Header: models.Header{AuthorID: 6}, PostContent: models.Content{Text: "content from user 6", CreatedAt: createTime}}, - {ID: 8, Header: models.Header{AuthorID: 4}, PostContent: models.Content{Text: "content from user 4", CreatedAt: createTime}}, - {ID: 9, Header: models.Header{AuthorID: 2}, PostContent: models.Content{Text: "content from user 2", CreatedAt: createTime}}, - {ID: 10, Header: models.Header{AuthorID: 1}, PostContent: models.Content{Text: "content from user 1", CreatedAt: createTime}}, - {ID: 11, Header: models.Header{AuthorID: 2}, PostContent: models.Content{Text: "content from user 2", CreatedAt: createTime}}, + expect := []*models.PostDto{ + { + ID: 1, Header: models.Header{AuthorID: 1}, + PostContent: models.ContentDto{Text: "content from user 1", CreatedAt: createTime}, + }, + { + ID: 2, Header: models.Header{AuthorID: 1}, + PostContent: models.ContentDto{Text: "content from user 1", CreatedAt: createTime}, + }, + { + ID: 3, Header: models.Header{AuthorID: 2}, + PostContent: models.ContentDto{Text: "content from user 2", CreatedAt: createTime}, + }, + { + ID: 4, Header: models.Header{AuthorID: 2}, + PostContent: models.ContentDto{Text: "content from user 2", CreatedAt: createTime}, + }, + { + ID: 5, Header: models.Header{AuthorID: 3}, + PostContent: models.ContentDto{Text: "content from user 3", CreatedAt: createTime}, + }, + { + ID: 6, Header: models.Header{AuthorID: 3}, + PostContent: models.ContentDto{Text: "content from user 3", CreatedAt: createTime}, + }, + { + ID: 7, Header: models.Header{AuthorID: 6}, + PostContent: models.ContentDto{Text: "content from user 6", CreatedAt: createTime}, + }, + { + ID: 8, Header: models.Header{AuthorID: 4}, + PostContent: models.ContentDto{Text: "content from user 4", CreatedAt: createTime}, + }, + { + ID: 9, Header: models.Header{AuthorID: 2}, + PostContent: models.ContentDto{Text: "content from user 2", CreatedAt: createTime}, + }, + { + ID: 10, Header: models.Header{AuthorID: 1}, + PostContent: models.ContentDto{Text: "content from user 1", CreatedAt: createTime}, + }, + { + ID: 11, Header: models.Header{AuthorID: 2}, + PostContent: models.ContentDto{Text: "content from user 2", CreatedAt: createTime}, + }, } repo := NewAdapter(db) @@ -416,7 +527,9 @@ func TestGetFriendsPosts(t *testing.T) { for _, test := range tests { rows := sqlmock.NewRows([]string{"id", "author_id", "content", "file_path", "created_at"}) for _, post := range test.wantPost { - rows.AddRow(post.ID, post.Header.AuthorID, post.PostContent.Text, post.PostContent.File, post.PostContent.CreatedAt) + rows.AddRow( + post.ID, post.Header.AuthorID, post.PostContent.Text, post.PostContent.File, post.PostContent.CreatedAt, + ) } mock.ExpectQuery(regexp.QuoteMeta(getFriendsPost)). WithArgs(test.lastID, convertSliceToString(test.friendsID)). diff --git a/internal/post/service/comment.go b/internal/post/service/comment.go index 5eabbbb4..5dd50a80 100644 --- a/internal/post/service/comment.go +++ b/internal/post/service/comment.go @@ -10,10 +10,10 @@ import ( //go:generate mockgen -destination=comment_mock.go -source=$GOFILE -package=${GOPACKAGE} type dbI interface { - CreateComment(ctx context.Context, comment *models.Content, userID, postID uint32) (uint32, error) + CreateComment(ctx context.Context, comment *models.ContentDto, userID, postID uint32) (uint32, error) DeleteComment(ctx context.Context, commentID uint32) error - UpdateComment(ctx context.Context, comment *models.Content, commentID uint32) error - GetComments(ctx context.Context, postID, lastID uint32, newest bool) ([]*models.Comment, error) + UpdateComment(ctx context.Context, comment *models.ContentDto, commentID uint32) error + GetComments(ctx context.Context, postID, lastID uint32, newest bool) ([]*models.CommentDto, error) GetCommentAuthor(ctx context.Context, commentID uint32) (uint32, error) } @@ -34,8 +34,8 @@ func NewCommentService(db dbI, profileRepo profileRepoI) *CommentService { } func (s *CommentService) Comment( - ctx context.Context, userID, postID uint32, comment *models.Content, -) (*models.Comment, error) { + ctx context.Context, userID, postID uint32, comment *models.ContentDto, +) (*models.CommentDto, error) { id, err := s.db.CreateComment(ctx, comment, userID, postID) if err != nil { return nil, fmt.Errorf("create comment: %w", err) @@ -46,7 +46,7 @@ func (s *CommentService) Comment( return nil, fmt.Errorf("get header: %w", err) } - newComment := &models.Comment{ + newComment := &models.CommentDto{ ID: id, Content: *comment, Header: *header, @@ -73,7 +73,7 @@ func (s *CommentService) DeleteComment(ctx context.Context, commentID, userID ui return nil } -func (s *CommentService) EditComment(ctx context.Context, commentID, userID uint32, comment *models.Content) error { +func (s *CommentService) EditComment(ctx context.Context, commentID, userID uint32, comment *models.ContentDto) error { authorID, err := s.db.GetCommentAuthor(ctx, commentID) if err != nil { return fmt.Errorf("get comment author: %w", err) @@ -93,7 +93,7 @@ func (s *CommentService) EditComment(ctx context.Context, commentID, userID uint func (s *CommentService) GetComments( ctx context.Context, postID, lastID uint32, newest bool, -) ([]*models.Comment, error) { +) ([]*models.CommentDto, error) { comments, err := s.db.GetComments(ctx, postID, lastID, newest) if err != nil { return nil, fmt.Errorf("get comments: %w", err) diff --git a/internal/post/service/comment_mock.go b/internal/post/service/comment_mock.go index 808b16c5..5168ea2d 100644 --- a/internal/post/service/comment_mock.go +++ b/internal/post/service/comment_mock.go @@ -42,7 +42,7 @@ func (m *MockdbI) EXPECT() *MockdbIMockRecorder { } // CreateComment mocks base method. -func (m *MockdbI) CreateComment(ctx context.Context, comment *models.Content, userID, postID uint32) (uint32, error) { +func (m *MockdbI) CreateComment(ctx context.Context, comment *models.ContentDto, userID, postID uint32) (uint32, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateComment", ctx, comment, userID, postID) ret0, _ := ret[0].(uint32) @@ -86,10 +86,10 @@ func (mr *MockdbIMockRecorder) GetCommentAuthor(ctx, commentID any) *gomock.Call } // GetComments mocks base method. -func (m *MockdbI) GetComments(ctx context.Context, postID, lastID uint32, newest bool) ([]*models.Comment, error) { +func (m *MockdbI) GetComments(ctx context.Context, postID, lastID uint32, newest bool) ([]*models.CommentDto, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetComments", ctx, postID, lastID, newest) - ret0, _ := ret[0].([]*models.Comment) + ret0, _ := ret[0].([]*models.CommentDto) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -101,7 +101,7 @@ func (mr *MockdbIMockRecorder) GetComments(ctx, postID, lastID, newest any) *gom } // UpdateComment mocks base method. -func (m *MockdbI) UpdateComment(ctx context.Context, comment *models.Content, commentID uint32) error { +func (m *MockdbI) UpdateComment(ctx context.Context, comment *models.ContentDto, commentID uint32) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateComment", ctx, comment, commentID) ret0, _ := ret[0].(error) diff --git a/internal/post/service/comment_test.go b/internal/post/service/comment_test.go index 990eeb48..56a6f0f6 100644 --- a/internal/post/service/comment_test.go +++ b/internal/post/service/comment_test.go @@ -29,7 +29,7 @@ func getCommentService(ctrl *gomock.Controller) (*CommentService, *commentMocks) type inputCreate struct { userID uint32 postID uint32 - comment *models.Content + comment *models.ContentDto } func TestNewCommentService(t *testing.T) { @@ -40,7 +40,7 @@ func TestNewCommentService(t *testing.T) { } func TestCommentService_Comment(t *testing.T) { - tests := []TableTest3[*models.Comment, inputCreate]{ + tests := []TableTest3[*models.CommentDto, inputCreate]{ { name: "1", SetupInput: func() (*inputCreate, error) { @@ -48,10 +48,10 @@ func TestCommentService_Comment(t *testing.T) { }, Run: func( ctx context.Context, implementation *CommentService, request inputCreate, - ) (*models.Comment, error) { + ) (*models.CommentDto, error) { return implementation.Comment(ctx, request.userID, request.postID, request.comment) }, - ExpectedResult: func() (*models.Comment, error) { + ExpectedResult: func() (*models.CommentDto, error) { return nil, nil }, ExpectedErr: errMock, @@ -67,10 +67,10 @@ func TestCommentService_Comment(t *testing.T) { }, Run: func( ctx context.Context, implementation *CommentService, request inputCreate, - ) (*models.Comment, error) { + ) (*models.CommentDto, error) { return implementation.Comment(ctx, request.userID, request.postID, request.comment) }, - ExpectedResult: func() (*models.Comment, error) { + ExpectedResult: func() (*models.CommentDto, error) { return nil, nil }, ExpectedErr: errMock, @@ -87,20 +87,20 @@ func TestCommentService_Comment(t *testing.T) { return &inputCreate{ userID: 1, postID: 1, - comment: &models.Content{ + comment: &models.ContentDto{ Text: "new comment", }, }, nil }, Run: func( ctx context.Context, implementation *CommentService, request inputCreate, - ) (*models.Comment, error) { + ) (*models.CommentDto, error) { return implementation.Comment(ctx, request.userID, request.postID, request.comment) }, - ExpectedResult: func() (*models.Comment, error) { - return &models.Comment{ + ExpectedResult: func() (*models.CommentDto, error) { + return &models.CommentDto{ ID: 1, - Content: models.Content{ + Content: models.ContentDto{ Text: "new comment", }, Header: models.Header{ @@ -278,7 +278,7 @@ func TestCommentService_Delete(t *testing.T) { type inputEdit struct { userID uint32 commentID uint32 - comment *models.Content + comment *models.ContentDto } func TestCommentService_Edit(t *testing.T) { @@ -403,7 +403,7 @@ type inputGet struct { } func TestCommentService_GetComments(t *testing.T) { - tests := []TableTest3[[]*models.Comment, inputGet]{ + tests := []TableTest3[[]*models.CommentDto, inputGet]{ { name: "1", SetupInput: func() (*inputGet, error) { @@ -411,10 +411,10 @@ func TestCommentService_GetComments(t *testing.T) { }, Run: func( ctx context.Context, implementation *CommentService, request inputGet, - ) ([]*models.Comment, error) { + ) ([]*models.CommentDto, error) { return implementation.GetComments(ctx, request.postID, request.lastID, request.newest) }, - ExpectedResult: func() ([]*models.Comment, error) { + ExpectedResult: func() ([]*models.CommentDto, error) { return nil, nil }, ExpectedErr: errMock, @@ -429,11 +429,11 @@ func TestCommentService_GetComments(t *testing.T) { }, Run: func( ctx context.Context, implementation *CommentService, request inputGet, - ) ([]*models.Comment, error) { + ) ([]*models.CommentDto, error) { return implementation.GetComments(ctx, request.postID, request.lastID, request.newest) }, - ExpectedResult: func() ([]*models.Comment, error) { - return []*models.Comment{ + ExpectedResult: func() ([]*models.CommentDto, error) { + return []*models.CommentDto{ { ID: 1, Header: models.Header{AuthorID: 1, Author: "Alexey Zemliakov"}, @@ -448,7 +448,7 @@ func TestCommentService_GetComments(t *testing.T) { SetupMock: func(request inputGet, m *commentMocks) { m.repo.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return( - []*models.Comment{ + []*models.CommentDto{ {ID: 1}, {ID: 2}, }, @@ -471,17 +471,17 @@ func TestCommentService_GetComments(t *testing.T) { }, Run: func( ctx context.Context, implementation *CommentService, request inputGet, - ) ([]*models.Comment, error) { + ) ([]*models.CommentDto, error) { return implementation.GetComments(ctx, request.postID, request.lastID, request.newest) }, - ExpectedResult: func() ([]*models.Comment, error) { + ExpectedResult: func() ([]*models.CommentDto, error) { return nil, nil }, ExpectedErr: errMock, SetupMock: func(request inputGet, m *commentMocks) { m.repo.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return( - []*models.Comment{ + []*models.CommentDto{ {ID: 1}, {ID: 2}, }, diff --git a/internal/post/service/mock.go b/internal/post/service/mock.go index d7c4032b..c219d6da 100644 --- a/internal/post/service/mock.go +++ b/internal/post/service/mock.go @@ -57,7 +57,7 @@ func (mr *MockDBMockRecorder) CheckLikes(ctx, postID, userID any) *gomock.Call { } // Create mocks base method. -func (m *MockDB) Create(ctx context.Context, post *models.Post) (uint32, error) { +func (m *MockDB) Create(ctx context.Context, post *models.PostDto) (uint32, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Create", ctx, post) ret0, _ := ret[0].(uint32) @@ -72,7 +72,7 @@ func (mr *MockDBMockRecorder) Create(ctx, post any) *gomock.Call { } // CreateCommunityPost mocks base method. -func (m *MockDB) CreateCommunityPost(ctx context.Context, post *models.Post, communityID uint32) (uint32, error) { +func (m *MockDB) CreateCommunityPost(ctx context.Context, post *models.PostDto, communityID uint32) (uint32, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateCommunityPost", ctx, post, communityID) ret0, _ := ret[0].(uint32) @@ -115,10 +115,10 @@ func (mr *MockDBMockRecorder) DeleteLikeFromPost(ctx, postID, userID any) *gomoc } // Get mocks base method. -func (m *MockDB) Get(ctx context.Context, postID uint32) (*models.Post, error) { +func (m *MockDB) Get(ctx context.Context, postID uint32) (*models.PostDto, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Get", ctx, postID) - ret0, _ := ret[0].(*models.Post) + ret0, _ := ret[0].(*models.PostDto) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -145,10 +145,10 @@ func (mr *MockDBMockRecorder) GetCommentCount(ctx, postID any) *gomock.Call { } // GetCommunityPosts mocks base method. -func (m *MockDB) GetCommunityPosts(ctx context.Context, communityID, lastID uint32) ([]*models.Post, error) { +func (m *MockDB) GetCommunityPosts(ctx context.Context, communityID, lastID uint32) ([]*models.PostDto, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetCommunityPosts", ctx, communityID, lastID) - ret0, _ := ret[0].([]*models.Post) + ret0, _ := ret[0].([]*models.PostDto) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -160,10 +160,10 @@ func (mr *MockDBMockRecorder) GetCommunityPosts(ctx, communityID, lastID any) *g } // GetFriendsPosts mocks base method. -func (m *MockDB) GetFriendsPosts(ctx context.Context, friendsID []uint32, lastID uint32) ([]*models.Post, error) { +func (m *MockDB) GetFriendsPosts(ctx context.Context, friendsID []uint32, lastID uint32) ([]*models.PostDto, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetFriendsPosts", ctx, friendsID, lastID) - ret0, _ := ret[0].([]*models.Post) + ret0, _ := ret[0].([]*models.PostDto) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -205,10 +205,10 @@ func (mr *MockDBMockRecorder) GetPostAuthor(ctx, postID any) *gomock.Call { } // GetPosts mocks base method. -func (m *MockDB) GetPosts(ctx context.Context, lastID uint32) ([]*models.Post, error) { +func (m *MockDB) GetPosts(ctx context.Context, lastID uint32) ([]*models.PostDto, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetPosts", ctx, lastID) - ret0, _ := ret[0].([]*models.Post) + ret0, _ := ret[0].([]*models.PostDto) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -234,7 +234,7 @@ func (mr *MockDBMockRecorder) SetLikeToPost(ctx, postID, userID any) *gomock.Cal } // Update mocks base method. -func (m *MockDB) Update(ctx context.Context, post *models.Post) error { +func (m *MockDB) Update(ctx context.Context, post *models.PostDto) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Update", ctx, post) ret0, _ := ret[0].(error) diff --git a/internal/post/service/mock_helper.go b/internal/post/service/mock_helper.go index 9eb80e89..7c016606 100644 --- a/internal/post/service/mock_helper.go +++ b/internal/post/service/mock_helper.go @@ -57,10 +57,10 @@ func (mr *MockPostProfileDBMockRecorder) CheckLikes(ctx, postID, userID any) *go } // GetAuthorPosts mocks base method. -func (m *MockPostProfileDB) GetAuthorPosts(ctx context.Context, header *models.Header) ([]*models.Post, error) { +func (m *MockPostProfileDB) GetAuthorPosts(ctx context.Context, header *models.Header) ([]*models.PostDto, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAuthorPosts", ctx, header) - ret0, _ := ret[0].([]*models.Post) + ret0, _ := ret[0].([]*models.PostDto) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/internal/post/service/post.go b/internal/post/service/post.go index 538f8c76..d2d2b8a2 100644 --- a/internal/post/service/post.go +++ b/internal/post/service/post.go @@ -11,16 +11,16 @@ import ( //go:generate mockgen -destination=mock.go -source=$GOFILE -package=${GOPACKAGE} type DB interface { - Create(ctx context.Context, post *models.Post) (uint32, error) - Get(ctx context.Context, postID uint32) (*models.Post, error) - Update(ctx context.Context, post *models.Post) error + Create(ctx context.Context, post *models.PostDto) (uint32, error) + Get(ctx context.Context, postID uint32) (*models.PostDto, error) + Update(ctx context.Context, post *models.PostDto) error Delete(ctx context.Context, postID uint32) error - GetPosts(ctx context.Context, lastID uint32) ([]*models.Post, error) - GetFriendsPosts(ctx context.Context, friendsID []uint32, lastID uint32) ([]*models.Post, error) + GetPosts(ctx context.Context, lastID uint32) ([]*models.PostDto, error) + GetFriendsPosts(ctx context.Context, friendsID []uint32, lastID uint32) ([]*models.PostDto, error) GetPostAuthor(ctx context.Context, postID uint32) (uint32, error) - CreateCommunityPost(ctx context.Context, post *models.Post, communityID uint32) (uint32, error) - GetCommunityPosts(ctx context.Context, communityID uint32, lastID uint32) ([]*models.Post, error) + CreateCommunityPost(ctx context.Context, post *models.PostDto, communityID uint32) (uint32, error) + GetCommunityPosts(ctx context.Context, communityID uint32, lastID uint32) ([]*models.PostDto, error) SetLikeToPost(ctx context.Context, postID uint32, userID uint32) error DeleteLikeFromPost(ctx context.Context, postID uint32, userID uint32) error @@ -54,7 +54,7 @@ func NewPostServiceImpl(db DB, profileRepo ProfileRepo, repo CommunityRepo) *Pos } } -func (s *PostServiceImpl) Create(ctx context.Context, post *models.Post) (uint32, error) { +func (s *PostServiceImpl) Create(ctx context.Context, post *models.PostDto) (uint32, error) { id, err := s.db.Create(ctx, post) if err != nil { return 0, fmt.Errorf("create post: %w", err) @@ -63,7 +63,7 @@ func (s *PostServiceImpl) Create(ctx context.Context, post *models.Post) (uint32 return id, nil } -func (s *PostServiceImpl) Get(ctx context.Context, postID, userID uint32) (*models.Post, error) { +func (s *PostServiceImpl) Get(ctx context.Context, postID, userID uint32) (*models.PostDto, error) { post, err := s.db.Get(ctx, postID) if err != nil { return nil, fmt.Errorf("get post: %w", err) @@ -85,7 +85,7 @@ func (s *PostServiceImpl) Delete(ctx context.Context, postID uint32) error { return nil } -func (s *PostServiceImpl) Update(ctx context.Context, post *models.Post) error { +func (s *PostServiceImpl) Update(ctx context.Context, post *models.PostDto) error { post.PostContent.UpdatedAt = time.Now() err := s.db.Update(ctx, post) @@ -96,7 +96,7 @@ func (s *PostServiceImpl) Update(ctx context.Context, post *models.Post) error { return nil } -func (s *PostServiceImpl) GetBatch(ctx context.Context, lastID, userID uint32) ([]*models.Post, error) { +func (s *PostServiceImpl) GetBatch(ctx context.Context, lastID, userID uint32) ([]*models.PostDto, error) { posts, err := s.db.GetPosts(ctx, lastID) if err != nil { return nil, fmt.Errorf("get posts: %w", err) @@ -113,7 +113,7 @@ func (s *PostServiceImpl) GetBatch(ctx context.Context, lastID, userID uint32) ( func (s *PostServiceImpl) GetBatchFromFriend( ctx context.Context, userID uint32, lastID uint32, -) ([]*models.Post, error) { +) ([]*models.PostDto, error) { friends, err := s.profileRepo.GetFriendsID(ctx, userID) if err != nil { return nil, fmt.Errorf("get friends: %w", err) @@ -146,7 +146,7 @@ func (s *PostServiceImpl) GetPostAuthorID(ctx context.Context, postID uint32) (u return id, nil } -func (s *PostServiceImpl) CreateCommunityPost(ctx context.Context, post *models.Post) (uint32, error) { +func (s *PostServiceImpl) CreateCommunityPost(ctx context.Context, post *models.PostDto) (uint32, error) { id, err := s.db.CreateCommunityPost(ctx, post, post.Header.CommunityID) if err != nil { return 0, fmt.Errorf("create post: %w", err) @@ -157,7 +157,7 @@ func (s *PostServiceImpl) CreateCommunityPost(ctx context.Context, post *models. func (s *PostServiceImpl) GetCommunityPost( ctx context.Context, communityID, userID, lastID uint32, -) ([]*models.Post, error) { +) ([]*models.PostDto, error) { posts, err := s.db.GetCommunityPosts(ctx, communityID, lastID) if err != nil { return nil, fmt.Errorf("get posts: %w", err) @@ -205,7 +205,7 @@ func (s *PostServiceImpl) CheckLikes(ctx context.Context, postID, userID uint32) return res, nil } -func (s *PostServiceImpl) setPostFields(ctx context.Context, post *models.Post, userID uint32) error { +func (s *PostServiceImpl) setPostFields(ctx context.Context, post *models.PostDto, userID uint32) error { var ( header *models.Header err error diff --git a/internal/post/service/post_profile.go b/internal/post/service/post_profile.go index 753a560c..9d6d03e4 100644 --- a/internal/post/service/post_profile.go +++ b/internal/post/service/post_profile.go @@ -9,7 +9,7 @@ import ( //go:generate mockgen -destination=mock_helper.go -source=$GOFILE -package=${GOPACKAGE} type PostProfileDB interface { - GetAuthorPosts(ctx context.Context, header *models.Header) ([]*models.Post, error) + GetAuthorPosts(ctx context.Context, header *models.Header) ([]*models.PostDto, error) GetLikesOnPost(ctx context.Context, postID uint32) (uint32, error) CheckLikes(ctx context.Context, postID, userID uint32) (bool, error) GetCommentCount(ctx context.Context, postID uint32) (uint32, error) @@ -52,6 +52,11 @@ func (p *PostProfileImpl) GetAuthorsPosts( } posts[i].CommentCount = commentCount } + res := make([]*models.Post, 0, len(posts)) + for _, post := range posts { + postFrom := post.FromDto() + res = append(res, &postFrom) + } - return posts, nil + return res, nil } diff --git a/internal/post/service/post_profile_test.go b/internal/post/service/post_profile_test.go index 6fa49a77..cfb3f9b8 100644 --- a/internal/post/service/post_profile_test.go +++ b/internal/post/service/post_profile_test.go @@ -60,7 +60,7 @@ func TestGetAuthorsPost(t *testing.T) { ExpectedErr: errMock, SetupMock: func(request input, m *mocksHelper) { m.repo.EXPECT().GetAuthorPosts(gomock.Any(), gomock.Any()).Return( - []*models.Post{ + []*models.PostDto{ { ID: 1, }, @@ -83,7 +83,7 @@ func TestGetAuthorsPost(t *testing.T) { ExpectedErr: errMock, SetupMock: func(request input, m *mocksHelper) { m.repo.EXPECT().GetAuthorPosts(gomock.Any(), gomock.Any()).Return( - []*models.Post{ + []*models.PostDto{ { ID: 1, }, @@ -114,7 +114,7 @@ func TestGetAuthorsPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request input, m *mocksHelper) { m.repo.EXPECT().GetAuthorPosts(gomock.Any(), gomock.Any()).Return( - []*models.Post{ + []*models.PostDto{ { ID: 1, }, @@ -139,7 +139,7 @@ func TestGetAuthorsPost(t *testing.T) { ExpectedErr: errMock, SetupMock: func(request input, m *mocksHelper) { m.repo.EXPECT().GetAuthorPosts(gomock.Any(), gomock.Any()).Return( - []*models.Post{ + []*models.PostDto{ { ID: 1, }, diff --git a/internal/post/service/post_test.go b/internal/post/service/post_test.go index a5e68d30..248344e2 100644 --- a/internal/post/service/post_test.go +++ b/internal/post/service/post_test.go @@ -38,36 +38,36 @@ func TestNewPostService(t *testing.T) { var errMock = errors.New("mock error") func TestCreate(t *testing.T) { - tests := []TableTest[uint32, models.Post]{ + tests := []TableTest[uint32, models.PostDto]{ { name: "1", - SetupInput: func() (*models.Post, error) { - return &models.Post{PostContent: models.Content{Text: "new post"}}, nil + SetupInput: func() (*models.PostDto, error) { + return &models.PostDto{PostContent: models.ContentDto{Text: "new post"}}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request models.Post) (uint32, error) { + Run: func(ctx context.Context, implementation *PostServiceImpl, request models.PostDto) (uint32, error) { return implementation.Create(ctx, &request) }, ExpectedResult: func() (uint32, error) { return 0, nil }, ExpectedErr: errMock, - SetupMock: func(request models.Post, m *mocks) { + SetupMock: func(request models.PostDto, m *mocks) { m.postRepo.EXPECT().Create(gomock.Any(), gomock.Any()).Return(uint32(0), errMock) }, }, { name: "2", - SetupInput: func() (*models.Post, error) { - return &models.Post{PostContent: models.Content{Text: "new real post"}}, nil + SetupInput: func() (*models.PostDto, error) { + return &models.PostDto{PostContent: models.ContentDto{Text: "new real post"}}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request models.Post) (uint32, error) { + Run: func(ctx context.Context, implementation *PostServiceImpl, request models.PostDto) (uint32, error) { return implementation.Create(ctx, &request) }, ExpectedResult: func() (uint32, error) { return 1, nil }, ExpectedErr: nil, - SetupMock: func(request models.Post, m *mocks) { + SetupMock: func(request models.PostDto, m *mocks) { m.postRepo.EXPECT().Create(gomock.Any(), gomock.Any()).Return(uint32(1), nil) }, }, @@ -110,7 +110,7 @@ type userAndPostIDs struct { } func TestGet(t *testing.T) { - tests := []TableTest[*models.Post, userAndPostIDs]{ + tests := []TableTest[*models.PostDto, userAndPostIDs]{ { name: "1", SetupInput: func() (*userAndPostIDs, error) { @@ -118,10 +118,10 @@ func TestGet(t *testing.T) { }, Run: func( ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs, - ) (*models.Post, error) { + ) (*models.PostDto, error) { return implementation.Get(ctx, request.postId, request.userID) }, - ExpectedResult: func() (*models.Post, error) { + ExpectedResult: func() (*models.PostDto, error) { return nil, nil }, ExpectedErr: errMock, @@ -136,16 +136,16 @@ func TestGet(t *testing.T) { }, Run: func( ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs, - ) (*models.Post, error) { + ) (*models.PostDto, error) { return implementation.Get(ctx, request.postId, request.userID) }, - ExpectedResult: func() (*models.Post, error) { + ExpectedResult: func() (*models.PostDto, error) { return nil, nil }, ExpectedErr: errMock, SetupMock: func(request userAndPostIDs, m *mocks) { m.postRepo.EXPECT().Get(gomock.Any(), gomock.Any()).Return( - &models.Post{ + &models.PostDto{ Header: models.Header{ CommunityID: 0, AuthorID: 1, @@ -163,16 +163,16 @@ func TestGet(t *testing.T) { }, Run: func( ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs, - ) (*models.Post, error) { + ) (*models.PostDto, error) { return implementation.Get(ctx, request.postId, request.userID) }, - ExpectedResult: func() (*models.Post, error) { + ExpectedResult: func() (*models.PostDto, error) { return nil, nil }, ExpectedErr: errMock, SetupMock: func(request userAndPostIDs, m *mocks) { m.postRepo.EXPECT().Get(gomock.Any(), gomock.Any()).Return( - &models.Post{ + &models.PostDto{ Header: models.Header{ CommunityID: 1, AuthorID: 0, @@ -190,16 +190,16 @@ func TestGet(t *testing.T) { }, Run: func( ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs, - ) (*models.Post, error) { + ) (*models.PostDto, error) { return implementation.Get(ctx, request.postId, request.userID) }, - ExpectedResult: func() (*models.Post, error) { + ExpectedResult: func() (*models.PostDto, error) { return nil, nil }, ExpectedErr: errMock, SetupMock: func(request userAndPostIDs, m *mocks) { m.postRepo.EXPECT().Get(gomock.Any(), gomock.Any()).Return( - &models.Post{ + &models.PostDto{ Header: models.Header{ CommunityID: 0, AuthorID: 1, @@ -224,16 +224,16 @@ func TestGet(t *testing.T) { }, Run: func( ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs, - ) (*models.Post, error) { + ) (*models.PostDto, error) { return implementation.Get(ctx, request.postId, request.userID) }, - ExpectedResult: func() (*models.Post, error) { + ExpectedResult: func() (*models.PostDto, error) { return nil, nil }, ExpectedErr: errMock, SetupMock: func(request userAndPostIDs, m *mocks) { m.postRepo.EXPECT().Get(gomock.Any(), gomock.Any()).Return( - &models.Post{ + &models.PostDto{ Header: models.Header{ CommunityID: 1, AuthorID: 0, @@ -259,11 +259,11 @@ func TestGet(t *testing.T) { }, Run: func( ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs, - ) (*models.Post, error) { + ) (*models.PostDto, error) { return implementation.Get(ctx, request.postId, request.userID) }, - ExpectedResult: func() (*models.Post, error) { - return &models.Post{ + ExpectedResult: func() (*models.PostDto, error) { + return &models.PostDto{ Header: models.Header{ CommunityID: 1, AuthorID: 0, @@ -276,7 +276,7 @@ func TestGet(t *testing.T) { ExpectedErr: nil, SetupMock: func(request userAndPostIDs, m *mocks) { m.postRepo.EXPECT().Get(gomock.Any(), gomock.Any()).Return( - &models.Post{ + &models.PostDto{ Header: models.Header{ CommunityID: 1, AuthorID: 0, @@ -303,16 +303,16 @@ func TestGet(t *testing.T) { }, Run: func( ctx context.Context, implementation *PostServiceImpl, request userAndPostIDs, - ) (*models.Post, error) { + ) (*models.PostDto, error) { return implementation.Get(ctx, request.postId, request.userID) }, - ExpectedResult: func() (*models.Post, error) { + ExpectedResult: func() (*models.PostDto, error) { return nil, nil }, ExpectedErr: errMock, SetupMock: func(request userAndPostIDs, m *mocks) { m.postRepo.EXPECT().Get(gomock.Any(), gomock.Any()).Return( - &models.Post{ + &models.PostDto{ Header: models.Header{ CommunityID: 1, AuthorID: 0, @@ -437,13 +437,13 @@ func TestDelete(t *testing.T) { } func TestUpdate(t *testing.T) { - tests := []TableTest[struct{}, models.Post]{ + tests := []TableTest[struct{}, models.PostDto]{ { name: "1", - SetupInput: func() (*models.Post, error) { - return &models.Post{}, nil + SetupInput: func() (*models.PostDto, error) { + return &models.PostDto{}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request models.Post) (struct{}, error) { + Run: func(ctx context.Context, implementation *PostServiceImpl, request models.PostDto) (struct{}, error) { err := implementation.Update(ctx, &request) return struct{}{}, err }, @@ -451,16 +451,16 @@ func TestUpdate(t *testing.T) { return struct{}{}, nil }, ExpectedErr: errMock, - SetupMock: func(request models.Post, m *mocks) { + SetupMock: func(request models.PostDto, m *mocks) { m.postRepo.EXPECT().Update(gomock.Any(), gomock.Any()).Return(errMock) }, }, { name: "2", - SetupInput: func() (*models.Post, error) { - return &models.Post{ID: 1, PostContent: models.Content{Text: "New post"}}, nil + SetupInput: func() (*models.PostDto, error) { + return &models.PostDto{ID: 1, PostContent: models.ContentDto{Text: "New post"}}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request models.Post) (struct{}, error) { + Run: func(ctx context.Context, implementation *PostServiceImpl, request models.PostDto) (struct{}, error) { err := implementation.Update(ctx, &request) return struct{}{}, err }, @@ -468,7 +468,7 @@ func TestUpdate(t *testing.T) { return struct{}{}, nil }, ExpectedErr: nil, - SetupMock: func(request models.Post, m *mocks) { + SetupMock: func(request models.PostDto, m *mocks) { m.postRepo.EXPECT().Update(gomock.Any(), gomock.Any()).Return(nil) }, }, @@ -511,7 +511,7 @@ type userAndLastIDs struct { } func TestGetBatch(t *testing.T) { - tests := []TableTest[[]*models.Post, userAndLastIDs]{ + tests := []TableTest[[]*models.PostDto, userAndLastIDs]{ { name: "1", SetupInput: func() (*userAndLastIDs, error) { @@ -519,10 +519,10 @@ func TestGetBatch(t *testing.T) { }, Run: func( ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, - ) ([]*models.Post, error) { + ) ([]*models.PostDto, error) { return implementation.GetBatch(ctx, request.LastId, request.UserID) }, - ExpectedResult: func() ([]*models.Post, error) { + ExpectedResult: func() ([]*models.PostDto, error) { return nil, nil }, ExpectedErr: errMock, @@ -537,16 +537,16 @@ func TestGetBatch(t *testing.T) { }, Run: func( ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, - ) ([]*models.Post, error) { + ) ([]*models.PostDto, error) { return implementation.GetBatch(ctx, request.LastId, request.UserID) }, - ExpectedResult: func() ([]*models.Post, error) { + ExpectedResult: func() ([]*models.PostDto, error) { return nil, nil }, ExpectedErr: errMock, SetupMock: func(request userAndLastIDs, m *mocks) { m.postRepo.EXPECT().GetPosts(gomock.Any(), gomock.Any()).Return( - []*models.Post{ + []*models.PostDto{ {ID: 1, Header: models.Header{CommunityID: 1}}, }, nil, ) @@ -560,11 +560,11 @@ func TestGetBatch(t *testing.T) { }, Run: func( ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, - ) ([]*models.Post, error) { + ) ([]*models.PostDto, error) { return implementation.GetBatch(ctx, request.LastId, request.UserID) }, - ExpectedResult: func() ([]*models.Post, error) { - return []*models.Post{ + ExpectedResult: func() ([]*models.PostDto, error) { + return []*models.PostDto{ { ID: 1, Header: models.Header{AuthorID: 1}, @@ -577,7 +577,7 @@ func TestGetBatch(t *testing.T) { ExpectedErr: nil, SetupMock: func(request userAndLastIDs, m *mocks) { m.postRepo.EXPECT().GetPosts(gomock.Any(), gomock.Any()).Return( - []*models.Post{ + []*models.PostDto{ {ID: 1, Header: models.Header{AuthorID: 1}}, }, nil, ) @@ -594,16 +594,16 @@ func TestGetBatch(t *testing.T) { }, Run: func( ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, - ) ([]*models.Post, error) { + ) ([]*models.PostDto, error) { return implementation.GetBatch(ctx, request.LastId, request.UserID) }, - ExpectedResult: func() ([]*models.Post, error) { + ExpectedResult: func() ([]*models.PostDto, error) { return nil, nil }, ExpectedErr: errMock, SetupMock: func(request userAndLastIDs, m *mocks) { m.postRepo.EXPECT().GetPosts(gomock.Any(), gomock.Any()).Return( - []*models.Post{ + []*models.PostDto{ {ID: 1, Header: models.Header{AuthorID: 1}}, }, nil, ) @@ -647,7 +647,7 @@ func TestGetBatch(t *testing.T) { } func TestGetBatchFromFriend(t *testing.T) { - tests := []TableTest[[]*models.Post, userAndLastIDs]{ + tests := []TableTest[[]*models.PostDto, userAndLastIDs]{ { name: "1", SetupInput: func() (*userAndLastIDs, error) { @@ -655,10 +655,10 @@ func TestGetBatchFromFriend(t *testing.T) { }, Run: func( ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, - ) ([]*models.Post, error) { + ) ([]*models.PostDto, error) { return implementation.GetBatchFromFriend(ctx, request.LastId, request.UserID) }, - ExpectedResult: func() ([]*models.Post, error) { + ExpectedResult: func() ([]*models.PostDto, error) { return nil, nil }, ExpectedErr: errMock, @@ -673,10 +673,10 @@ func TestGetBatchFromFriend(t *testing.T) { }, Run: func( ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, - ) ([]*models.Post, error) { + ) ([]*models.PostDto, error) { return implementation.GetBatchFromFriend(ctx, request.LastId, request.UserID) }, - ExpectedResult: func() ([]*models.Post, error) { + ExpectedResult: func() ([]*models.PostDto, error) { return nil, nil }, ExpectedErr: my_err.ErrNoMoreContent, @@ -691,10 +691,10 @@ func TestGetBatchFromFriend(t *testing.T) { }, Run: func( ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, - ) ([]*models.Post, error) { + ) ([]*models.PostDto, error) { return implementation.GetBatchFromFriend(ctx, request.LastId, request.UserID) }, - ExpectedResult: func() ([]*models.Post, error) { + ExpectedResult: func() ([]*models.PostDto, error) { return nil, nil }, ExpectedErr: errMock, @@ -710,17 +710,17 @@ func TestGetBatchFromFriend(t *testing.T) { }, Run: func( ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, - ) ([]*models.Post, error) { + ) ([]*models.PostDto, error) { return implementation.GetBatchFromFriend(ctx, request.LastId, request.UserID) }, - ExpectedResult: func() ([]*models.Post, error) { + ExpectedResult: func() ([]*models.PostDto, error) { return nil, nil }, ExpectedErr: errMock, SetupMock: func(request userAndLastIDs, m *mocks) { m.profileRepo.EXPECT().GetFriendsID(gomock.Any(), gomock.Any()).Return([]uint32{1, 2, 3}, nil) m.postRepo.EXPECT().GetFriendsPosts(gomock.Any(), gomock.Any(), gomock.Any()).Return( - []*models.Post{ + []*models.PostDto{ {ID: 1, Header: models.Header{CommunityID: 1}}, }, nil, ) @@ -734,11 +734,11 @@ func TestGetBatchFromFriend(t *testing.T) { }, Run: func( ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, - ) ([]*models.Post, error) { + ) ([]*models.PostDto, error) { return implementation.GetBatchFromFriend(ctx, request.LastId, request.UserID) }, - ExpectedResult: func() ([]*models.Post, error) { - return []*models.Post{ + ExpectedResult: func() ([]*models.PostDto, error) { + return []*models.PostDto{ { ID: 1, Header: models.Header{AuthorID: 1}, @@ -751,7 +751,7 @@ func TestGetBatchFromFriend(t *testing.T) { SetupMock: func(request userAndLastIDs, m *mocks) { m.profileRepo.EXPECT().GetFriendsID(gomock.Any(), gomock.Any()).Return([]uint32{1, 2, 3}, nil) m.postRepo.EXPECT().GetFriendsPosts(gomock.Any(), gomock.Any(), gomock.Any()).Return( - []*models.Post{ + []*models.PostDto{ {ID: 1, Header: models.Header{AuthorID: 1}}, }, nil, ) @@ -768,17 +768,17 @@ func TestGetBatchFromFriend(t *testing.T) { }, Run: func( ctx context.Context, implementation *PostServiceImpl, request userAndLastIDs, - ) ([]*models.Post, error) { + ) ([]*models.PostDto, error) { return implementation.GetBatchFromFriend(ctx, request.LastId, request.UserID) }, - ExpectedResult: func() ([]*models.Post, error) { + ExpectedResult: func() ([]*models.PostDto, error) { return nil, nil }, ExpectedErr: errMock, SetupMock: func(request userAndLastIDs, m *mocks) { m.profileRepo.EXPECT().GetFriendsID(gomock.Any(), gomock.Any()).Return([]uint32{1, 2, 3}, nil) m.postRepo.EXPECT().GetFriendsPosts(gomock.Any(), gomock.Any(), gomock.Any()).Return( - []*models.Post{ + []*models.PostDto{ {ID: 1, Header: models.Header{AuthorID: 1}}, }, nil, ) @@ -891,20 +891,20 @@ func TestGetPostAuthor(t *testing.T) { } func TestCreateCommunityPost(t *testing.T) { - tests := []TableTest[uint32, models.Post]{ + tests := []TableTest[uint32, models.PostDto]{ { name: "1", - SetupInput: func() (*models.Post, error) { - return &models.Post{}, nil + SetupInput: func() (*models.PostDto, error) { + return &models.PostDto{}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request models.Post) (uint32, error) { + Run: func(ctx context.Context, implementation *PostServiceImpl, request models.PostDto) (uint32, error) { return implementation.CreateCommunityPost(ctx, &request) }, ExpectedResult: func() (uint32, error) { return uint32(0), nil }, ExpectedErr: errMock, - SetupMock: func(request models.Post, m *mocks) { + SetupMock: func(request models.PostDto, m *mocks) { m.postRepo.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any(), gomock.Any()).Return( uint32(0), errMock, ) @@ -912,17 +912,17 @@ func TestCreateCommunityPost(t *testing.T) { }, { name: "2", - SetupInput: func() (*models.Post, error) { - return &models.Post{PostContent: models.Content{Text: "new post"}}, nil + SetupInput: func() (*models.PostDto, error) { + return &models.PostDto{PostContent: models.ContentDto{Text: "new post"}}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request models.Post) (uint32, error) { + Run: func(ctx context.Context, implementation *PostServiceImpl, request models.PostDto) (uint32, error) { return implementation.CreateCommunityPost(ctx, &request) }, ExpectedResult: func() (uint32, error) { return uint32(1), nil }, ExpectedErr: nil, - SetupMock: func(request models.Post, m *mocks) { + SetupMock: func(request models.PostDto, m *mocks) { m.postRepo.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(uint32(1), nil) }, }, @@ -966,16 +966,16 @@ type IDs struct { } func TestGetCommunityPost(t *testing.T) { - tests := []TableTest[[]*models.Post, IDs]{ + tests := []TableTest[[]*models.PostDto, IDs]{ { name: "1", SetupInput: func() (*IDs, error) { return &IDs{}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request IDs) ([]*models.Post, error) { + Run: func(ctx context.Context, implementation *PostServiceImpl, request IDs) ([]*models.PostDto, error) { return implementation.GetCommunityPost(ctx, request.communityID, request.userID, request.lastID) }, - ExpectedResult: func() ([]*models.Post, error) { + ExpectedResult: func() ([]*models.PostDto, error) { return nil, nil }, ExpectedErr: errMock, @@ -988,16 +988,16 @@ func TestGetCommunityPost(t *testing.T) { SetupInput: func() (*IDs, error) { return &IDs{userID: 1, lastID: 2, communityID: 1}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request IDs) ([]*models.Post, error) { + Run: func(ctx context.Context, implementation *PostServiceImpl, request IDs) ([]*models.PostDto, error) { return implementation.GetCommunityPost(ctx, request.lastID, request.userID, request.communityID) }, - ExpectedResult: func() ([]*models.Post, error) { + ExpectedResult: func() ([]*models.PostDto, error) { return nil, nil }, ExpectedErr: errMock, SetupMock: func(request IDs, m *mocks) { m.postRepo.EXPECT().GetCommunityPosts(gomock.Any(), gomock.Any(), gomock.Any()).Return( - []*models.Post{ + []*models.PostDto{ {ID: 1, Header: models.Header{CommunityID: 1}}, }, nil, ) @@ -1009,11 +1009,11 @@ func TestGetCommunityPost(t *testing.T) { SetupInput: func() (*IDs, error) { return &IDs{userID: 1, lastID: 2, communityID: 3}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request IDs) ([]*models.Post, error) { + Run: func(ctx context.Context, implementation *PostServiceImpl, request IDs) ([]*models.PostDto, error) { return implementation.GetCommunityPost(ctx, request.lastID, request.userID, request.communityID) }, - ExpectedResult: func() ([]*models.Post, error) { - return []*models.Post{ + ExpectedResult: func() ([]*models.PostDto, error) { + return []*models.PostDto{ { ID: 1, Header: models.Header{AuthorID: 1}, @@ -1025,7 +1025,7 @@ func TestGetCommunityPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request IDs, m *mocks) { m.postRepo.EXPECT().GetCommunityPosts(gomock.Any(), gomock.Any(), gomock.Any()).Return( - []*models.Post{ + []*models.PostDto{ {ID: 1, Header: models.Header{AuthorID: 1}}, }, nil, ) @@ -1040,16 +1040,16 @@ func TestGetCommunityPost(t *testing.T) { SetupInput: func() (*IDs, error) { return &IDs{userID: 1, lastID: 2, communityID: 3}, nil }, - Run: func(ctx context.Context, implementation *PostServiceImpl, request IDs) ([]*models.Post, error) { + Run: func(ctx context.Context, implementation *PostServiceImpl, request IDs) ([]*models.PostDto, error) { return implementation.GetCommunityPost(ctx, request.lastID, request.userID, request.communityID) }, - ExpectedResult: func() ([]*models.Post, error) { + ExpectedResult: func() ([]*models.PostDto, error) { return nil, nil }, ExpectedErr: errMock, SetupMock: func(request IDs, m *mocks) { m.postRepo.EXPECT().GetCommunityPosts(gomock.Any(), gomock.Any(), gomock.Any()).Return( - []*models.Post{ + []*models.PostDto{ {ID: 1, Header: models.Header{AuthorID: 1}}, }, nil, ) diff --git a/proto/post.proto b/proto/post.proto index ab67c3a7..26fef9a7 100644 --- a/proto/post.proto +++ b/proto/post.proto @@ -35,7 +35,7 @@ message Post { message Content { string Text = 1; - string File = 2; + repeated string File = 2; int64 CreatedAt = 3; int64 UpdatedAt = 4; } \ No newline at end of file From b7f94a524b23383bfd3ce361ce6cae75ab95ff8e Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Fri, 13 Dec 2024 23:08:09 +0300 Subject: [PATCH 067/135] feature: add custom errors --- internal/chat/controller/controller.go | 4 ++++ internal/post/controller/controller.go | 6 +++--- pkg/my_err/error.go | 3 ++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/internal/chat/controller/controller.go b/internal/chat/controller/controller.go index f505369c..fc5ff8fe 100644 --- a/internal/chat/controller/controller.go +++ b/internal/chat/controller/controller.go @@ -92,6 +92,10 @@ func (cc *ChatController) SetConnection(w http.ResponseWriter, r *http.Request) func (cc *ChatController) SendChatMsg(ctx context.Context, reqID string, w http.ResponseWriter) { for msg := range cc.Messages { + if len(msg.Content.FilePath) > 10 { + cc.responder.ErrorBadRequest(w, my_err.ErrToMuchFiles, reqID) + return + } msg := msg.ToDto() if msg.Content.StickerPath != "" && (msg.Content.FilePath != "" || msg.Content.Text != "") { cc.responder.ErrorBadRequest(w, my_err.ErrStickerHasAnotherContent, reqID) diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index 24c8acd2..3196097d 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -330,7 +330,7 @@ func (pc *PostController) getPostFromBody(r *http.Request) (*models.PostDto, err } if !validateContent(newPost.PostContent) { - return nil, my_err.ErrTextTooLong + return nil, my_err.ErrBadPostOrComment } sess, err := models.SessionFromContext(r.Context()) @@ -503,7 +503,7 @@ func (pc *PostController) Comment(w http.ResponseWriter, r *http.Request) { } if !validateContent(content) { - pc.responder.ErrorBadRequest(w, my_err.ErrTextTooLong, reqID) + pc.responder.ErrorBadRequest(w, my_err.ErrBadPostOrComment, reqID) return } @@ -580,7 +580,7 @@ func (pc *PostController) EditComment(w http.ResponseWriter, r *http.Request) { } if !validateContent(content) { - pc.responder.ErrorBadRequest(w, my_err.ErrTextTooLong, reqID) + pc.responder.ErrorBadRequest(w, my_err.ErrBadPostOrComment, reqID) return } diff --git a/pkg/my_err/error.go b/pkg/my_err/error.go index 0b504a34..d8a405b6 100644 --- a/pkg/my_err/error.go +++ b/pkg/my_err/error.go @@ -33,7 +33,8 @@ var ( ErrLikeAlreadyExists = errors.New("like already exists") ErrWrongCommunity = errors.New("wrong community") ErrWrongPost = errors.New("wrong post") - ErrTextTooLong = errors.New("text len is too big") + ErrBadPostOrComment = errors.New("content is bad") ErrWrongComment = errors.New("wrong comment") ErrStickerHasAnotherContent = errors.New("sticker has another content") + ErrToMuchFiles = errors.New("files more then 10") ) From 8a8d90a9c6bf6808101d73d1e9c71c03eb45513f Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Fri, 13 Dec 2024 23:31:36 +0300 Subject: [PATCH 068/135] bugfix with read data from oistgre --- internal/chat/repository/postgres/queryConst.go | 2 +- internal/chat/repository/postgres/repository.go | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/internal/chat/repository/postgres/queryConst.go b/internal/chat/repository/postgres/queryConst.go index c5c22f95..5da9bda9 100644 --- a/internal/chat/repository/postgres/queryConst.go +++ b/internal/chat/repository/postgres/queryConst.go @@ -36,7 +36,7 @@ ORDER BY last_messages.created_at DESC LIMIT 15;` - getLatestMessagesBatch = `SELECT sender, receiver, content, created_at + getLatestMessagesBatch = `SELECT sender, receiver, content, file_path, sticker_path, created_at FROM message WHERE ((sender = $1 AND receiver = $2) OR (sender = $2 AND receiver = $1)) AND created_at < $3 diff --git a/internal/chat/repository/postgres/repository.go b/internal/chat/repository/postgres/repository.go index b0d084ac..41ce2825 100644 --- a/internal/chat/repository/postgres/repository.go +++ b/internal/chat/repository/postgres/repository.go @@ -70,7 +70,14 @@ func (cr *Repo) GetMessages( for rows.Next() { msg := &models.MessageDto{} - if err := rows.Scan(&msg.Sender, &msg.Receiver, &msg.Content, &msg.CreatedAt); err != nil { + if err := rows.Scan( + &msg.Sender, + &msg.Receiver, + &msg.Content.Text, + &msg.Content.FilePath, + &msg.Content.StickerPath, + &msg.CreatedAt, + ); err != nil { return nil, fmt.Errorf("postgres get messages: %w", err) } messages = append(messages, msg) From f63f06799dcabe19225559dc4f05661826f59dba Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Fri, 13 Dec 2024 23:45:12 +0300 Subject: [PATCH 069/135] feat: add logs --- internal/chat/controller/client.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/internal/chat/controller/client.go b/internal/chat/controller/client.go index 5ae3558b..aef237e0 100644 --- a/internal/chat/controller/client.go +++ b/internal/chat/controller/client.go @@ -9,6 +9,8 @@ import ( "github.com/2024_2_BetterCallFirewall/internal/models" ) +const wc = "websocket" + type Client struct { Socket *websocket.Conn Receive chan *models.Message @@ -21,10 +23,12 @@ func (c *Client) Read(userID uint32) { msg := &models.Message{} _, jsonMessage, err := c.Socket.ReadMessage() if err != nil { + c.chatController.responder.LogError(err, wc) return } err = json.Unmarshal(jsonMessage, msg) if err != nil { + c.chatController.responder.LogError(err, wc) return } msg.Sender = userID @@ -38,10 +42,12 @@ func (c *Client) Write() { msg.CreatedAt = time.Now() jsonForSend, err := json.Marshal(msg) if err != nil { + c.chatController.responder.LogError(err, wc) return } err = c.Socket.WriteMessage(websocket.TextMessage, jsonForSend) if err != nil { + c.chatController.responder.LogError(err, wc) return } } From 3bcccae1ea24c5c31982e44c5e7e3a145fc055a3 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Wed, 11 Dec 2024 14:55:36 +0300 Subject: [PATCH 070/135] add files non image --- internal/fileService/controller/controller.go | 75 +- internal/fileService/controller/mock.go | 55 +- internal/fileService/service/fileService.go | 52 +- internal/post/controller/controller_test.go | 1230 ++++++++++------- internal/router/file/router.go | 2 + internal/router/file/router_test.go | 2 + 6 files changed, 862 insertions(+), 554 deletions(-) diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index 6cba831b..4a6b7484 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -6,6 +6,7 @@ import ( "fmt" "mime/multipart" "net/http" + "strings" "github.com/gorilla/mux" @@ -13,16 +14,19 @@ import ( ) var fileFormat = map[string]struct{}{ - "image/jpeg": {}, - "image/jpg": {}, - "image/png": {}, - "image/webp": {}, + "jpeg": {}, + "jpg": {}, + "png": {}, + "webp": {}, + "gif": {}, } //go:generate mockgen -destination=mock.go -source=$GOFILE -package=${GOPACKAGE} type fileService interface { Upload(ctx context.Context, name string) ([]byte, error) - Download(ctx context.Context, file multipart.File) (string, error) + Download(ctx context.Context, file multipart.File, format string) (string, error) + DownloadNonImage(ctx context.Context, file multipart.File, format string) (string, error) + UploadNonImage(ctx context.Context, name string) ([]byte, error) } type responder interface { @@ -45,6 +49,31 @@ func NewFileController(fileService fileService, responder responder) *FileContro } } +func (fc *FileController) UploadNonImage(w http.ResponseWriter, r *http.Request) { + var ( + reqID, ok = r.Context().Value("requestID").(string) + vars = mux.Vars(r) + name = vars["name"] + ) + + if !ok { + fc.responder.LogError(my_err.ErrInvalidContext, "") + } + + if name == "" { + fc.responder.ErrorBadRequest(w, errors.New("name is empty"), reqID) + return + } + + res, err := fc.fileService.UploadNonImage(r.Context(), name) + if err != nil { + fc.responder.ErrorBadRequest(w, fmt.Errorf("%w: %w", err, my_err.ErrWrongFile), reqID) + return + } + + fc.responder.OutputBytes(w, res, reqID) +} + func (fc *FileController) Upload(w http.ResponseWriter, r *http.Request) { var ( reqID, ok = r.Context().Value("requestID").(string) @@ -76,11 +105,11 @@ func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { fc.responder.LogError(my_err.ErrInvalidContext, "") } - err := r.ParseMultipartForm(10 << 20) // 10Mbyte + err := r.ParseMultipartForm(10 * (10 << 20)) // 100Mbyte defer func() { err = r.MultipartForm.RemoveAll() if err != nil { - panic(err) + fc.responder.LogError(err, reqID) } }() if err != nil { @@ -90,21 +119,35 @@ func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { file, header, err := r.FormFile("file") if err != nil { - file = nil - } else { - format := header.Header.Get("Content-Type") - if _, ok := fileFormat[format]; !ok { - fc.responder.ErrorBadRequest(w, my_err.ErrWrongFiletype, reqID) - return + fc.responder.ErrorBadRequest(w, err, reqID) + return + } + + defer func(file multipart.File) { + err = file.Close() + if err != nil { + fc.responder.LogError(err, reqID) } + }(file) + + formats := strings.Split(header.Header.Get("Content-Type"), "/") + if len(formats) != 2 { + fc.responder.ErrorBadRequest(w, my_err.ErrWrongFiletype, reqID) + return + } + var url string + format := formats[1] + + if _, ok := fileFormat[format]; ok { + url, err = fc.fileService.Download(r.Context(), file, format) + } else { + + url, err = fc.fileService.DownloadNonImage(r.Context(), file, format) } - defer file.Close() - url, err := fc.fileService.Download(r.Context(), file) if err != nil { fc.responder.ErrorBadRequest(w, err, reqID) return } - fc.responder.OutputJSON(w, url, reqID) } diff --git a/internal/fileService/controller/mock.go b/internal/fileService/controller/mock.go index ad31747d..ff73012b 100644 --- a/internal/fileService/controller/mock.go +++ b/internal/fileService/controller/mock.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: controller.go +// +// Generated by this command: +// +// mockgen -destination=mock.go -source=controller.go -package=controller +// // Package controller is a generated GoMock package. package controller @@ -17,6 +22,7 @@ import ( type MockfileService struct { ctrl *gomock.Controller recorder *MockfileServiceMockRecorder + isgomock struct{} } // MockfileServiceMockRecorder is the mock recorder for MockfileService. @@ -37,18 +43,33 @@ func (m *MockfileService) EXPECT() *MockfileServiceMockRecorder { } // Download mocks base method. -func (m *MockfileService) Download(ctx context.Context, file multipart.File) (string, error) { +func (m *MockfileService) Download(ctx context.Context, file multipart.File, format string) (string, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Download", ctx, file) + ret := m.ctrl.Call(m, "Download", ctx, file, format) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } // Download indicates an expected call of Download. -func (mr *MockfileServiceMockRecorder) Download(ctx, file interface{}) *gomock.Call { +func (mr *MockfileServiceMockRecorder) Download(ctx, file, format any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Download", reflect.TypeOf((*MockfileService)(nil).Download), ctx, file) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Download", reflect.TypeOf((*MockfileService)(nil).Download), ctx, file, format) +} + +// DownloadNonImage mocks base method. +func (m *MockfileService) DownloadNonImage(ctx context.Context, file multipart.File, format string) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DownloadNonImage", ctx, file, format) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DownloadNonImage indicates an expected call of DownloadNonImage. +func (mr *MockfileServiceMockRecorder) DownloadNonImage(ctx, file, format any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadNonImage", reflect.TypeOf((*MockfileService)(nil).DownloadNonImage), ctx, file, format) } // Upload mocks base method. @@ -61,15 +82,31 @@ func (m *MockfileService) Upload(ctx context.Context, name string) ([]byte, erro } // Upload indicates an expected call of Upload. -func (mr *MockfileServiceMockRecorder) Upload(ctx, name interface{}) *gomock.Call { +func (mr *MockfileServiceMockRecorder) Upload(ctx, name any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Upload", reflect.TypeOf((*MockfileService)(nil).Upload), ctx, name) } +// UploadNonImage mocks base method. +func (m *MockfileService) UploadNonImage(ctx context.Context, name string) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UploadNonImage", ctx, name) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UploadNonImage indicates an expected call of UploadNonImage. +func (mr *MockfileServiceMockRecorder) UploadNonImage(ctx, name any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UploadNonImage", reflect.TypeOf((*MockfileService)(nil).UploadNonImage), ctx, name) +} + // Mockresponder is a mock of responder interface. type Mockresponder struct { ctrl *gomock.Controller recorder *MockresponderMockRecorder + isgomock struct{} } // MockresponderMockRecorder is the mock recorder for Mockresponder. @@ -96,7 +133,7 @@ func (m *Mockresponder) ErrorBadRequest(w http.ResponseWriter, err error, reques } // ErrorBadRequest indicates an expected call of ErrorBadRequest. -func (mr *MockresponderMockRecorder) ErrorBadRequest(w, err, requestID interface{}) *gomock.Call { +func (mr *MockresponderMockRecorder) ErrorBadRequest(w, err, requestID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ErrorBadRequest", reflect.TypeOf((*Mockresponder)(nil).ErrorBadRequest), w, err, requestID) } @@ -108,7 +145,7 @@ func (m *Mockresponder) LogError(err error, requestID string) { } // LogError indicates an expected call of LogError. -func (mr *MockresponderMockRecorder) LogError(err, requestID interface{}) *gomock.Call { +func (mr *MockresponderMockRecorder) LogError(err, requestID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogError", reflect.TypeOf((*Mockresponder)(nil).LogError), err, requestID) } @@ -120,7 +157,7 @@ func (m *Mockresponder) OutputBytes(w http.ResponseWriter, data []byte, requestI } // OutputBytes indicates an expected call of OutputBytes. -func (mr *MockresponderMockRecorder) OutputBytes(w, data, requestID interface{}) *gomock.Call { +func (mr *MockresponderMockRecorder) OutputBytes(w, data, requestID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OutputBytes", reflect.TypeOf((*Mockresponder)(nil).OutputBytes), w, data, requestID) } @@ -132,7 +169,7 @@ func (m *Mockresponder) OutputJSON(w http.ResponseWriter, data any, requestId st } // OutputJSON indicates an expected call of OutputJSON. -func (mr *MockresponderMockRecorder) OutputJSON(w, data, requestId interface{}) *gomock.Call { +func (mr *MockresponderMockRecorder) OutputJSON(w, data, requestId any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OutputJSON", reflect.TypeOf((*Mockresponder)(nil).OutputJSON), w, data, requestId) } diff --git a/internal/fileService/service/fileService.go b/internal/fileService/service/fileService.go index 6a0b7d5e..700950b3 100644 --- a/internal/fileService/service/fileService.go +++ b/internal/fileService/service/fileService.go @@ -16,14 +16,16 @@ func NewFileService() *FileService { return &FileService{} } -func (f *FileService) Download(ctx context.Context, file multipart.File) (string, error) { +func (f *FileService) Download(ctx context.Context, file multipart.File, format string) (string, error) { var ( fileName = uuid.New().String() - filePath = fmt.Sprintf("/image/%s", fileName) + filePath = fmt.Sprintf("/image/%s.%s", fileName, format) dst, err = os.Create(filePath) ) - defer dst.Close() + defer func(dst *os.File) { + _ = dst.Close() + }(dst) if err != nil { return "", fmt.Errorf("save file: %w", err) } @@ -35,6 +37,25 @@ func (f *FileService) Download(ctx context.Context, file multipart.File) (string return filePath, nil } +func (f *FileService) DownloadNonImage(ctx context.Context, file multipart.File, format string) (string, error) { + var ( + fileName = uuid.New().String() + filePath = fmt.Sprintf("/file/%s.%s", fileName, format) + dst, err = os.Create(filePath) + ) + defer func(dst *os.File) { + _ = dst.Close() + }(dst) + if err != nil { + return "", fmt.Errorf("save file: %w", err) + } + if _, err := io.Copy(dst, file); err != nil { + return "", fmt.Errorf("save file: %w", err) + } + + return filePath, nil +} + func (f *FileService) Upload(ctx context.Context, name string) ([]byte, error) { var ( file, err = os.Open(fmt.Sprintf("/image/%s", name)) @@ -42,7 +63,30 @@ func (f *FileService) Upload(ctx context.Context, name string) ([]byte, error) { sl = make([]byte, 1024) ) - defer file.Close() + defer func(file *os.File) { + _ = file.Close() + }(file) + if err != nil { + return nil, fmt.Errorf("open file: %w", err) + } + + for n, err := file.Read(sl); err != io.EOF; n, err = file.Read(sl) { + res = append(res, sl[:n]...) + } + + return res, nil +} + +func (f *FileService) UploadNonImage(ctx context.Context, name string) ([]byte, error) { + var ( + file, err = os.Open(fmt.Sprintf("/file/%s", name)) + res []byte + sl = make([]byte, 1024) + ) + + defer func(file *os.File) { + _ = file.Close() + }(file) if err != nil { return nil, fmt.Errorf("open file: %w", err) } diff --git a/internal/post/controller/controller_test.go b/internal/post/controller/controller_test.go index 4edb1345..b69c00cb 100644 --- a/internal/post/controller/controller_test.go +++ b/internal/post/controller/controller_test.go @@ -18,11 +18,12 @@ import ( func getController(ctrl *gomock.Controller) (*PostController, *mocks) { m := &mocks{ - postService: NewMockPostService(ctrl), - responder: NewMockResponder(ctrl), + postService: NewMockPostService(ctrl), + responder: NewMockResponder(ctrl), + commentService: NewMockCommentService(ctrl), } - return NewPostController(m.postService, m.responder), m + return NewPostController(m.postService, m.commentService, m.responder), m } func TestNewPostController(t *testing.T) { @@ -53,19 +54,23 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "2", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() res := &Request{r: req, w: w} return res, nil @@ -81,19 +86,23 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "3", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -111,19 +120,23 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Create(gomock.Any(), gomock.Any()).Return(uint32(0), errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "4", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -141,19 +154,23 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Create(gomock.Any(), gomock.Any()).Return(uint32(2), nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "5", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=ljkhkg", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=ljkhkg", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -170,19 +187,23 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "6", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -200,19 +221,23 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(false) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "7", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -230,20 +255,26 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) - m.postService.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any()).Return(uint32(0), errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any()).Return( + uint32(0), errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "8", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -262,19 +293,23 @@ func TestCreate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.postService.EXPECT().CreateCommunityPost(gomock.Any(), gomock.Any()).Return(uint32(10), nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "9", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=10", + bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -291,42 +326,46 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -351,12 +390,14 @@ func TestGetOne(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -379,12 +420,14 @@ func TestGetOne(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -409,12 +452,14 @@ func TestGetOne(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, my_err.ErrPostNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -439,12 +484,14 @@ func TestGetOne(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -469,12 +516,14 @@ func TestGetOne(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -497,42 +546,46 @@ func TestGetOne(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -556,12 +609,14 @@ func TestUpdate(t *testing.T) { }, ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -584,12 +639,14 @@ func TestUpdate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -613,13 +670,17 @@ func TestUpdate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(0), errors.New("error")) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return( + uint32(0), errors.New("error"), + ) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -644,19 +705,23 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(10), nil) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "5", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -676,19 +741,23 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(my_err.ErrPostNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "6", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -708,19 +777,23 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "7", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -740,19 +813,23 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "8", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=nkljbkvhj", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=nkljbkvhj", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -770,19 +847,23 @@ func TestUpdate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "9", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -801,19 +882,23 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(false) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "10", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=10", - bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=10", + bytes.NewBuffer([]byte(`{"id":1}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -833,19 +918,23 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.postService.EXPECT().Update(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "11", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=10", - bytes.NewBuffer([]byte(`{"id"`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=10", + bytes.NewBuffer([]byte(`{"id"`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -864,19 +953,23 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "12", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/10?community=1", - bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/10?community=1", + bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -895,42 +988,46 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -955,12 +1052,14 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -983,12 +1082,14 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1014,12 +1115,14 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(my_err.ErrPostNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1045,12 +1148,14 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1076,12 +1181,14 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetPostAuthorID(gomock.Any(), gomock.Any()).Return(uint32(1), nil) m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1105,12 +1212,14 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, error, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, error, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1133,12 +1242,14 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, error, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, error, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1164,42 +1275,46 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().CheckAccessToCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.postService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, error, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, error, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1224,12 +1339,14 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1251,12 +1368,14 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1279,10 +1398,14 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, my_err.ErrNoMoreContent) - m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do(func(w, req any) { - request.w.WriteHeader(http.StatusNoContent) - }) + m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, my_err.ErrNoMoreContent, + ) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) }, }, { @@ -1305,13 +1428,17 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1335,12 +1462,14 @@ func TestGetBatchPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetBatch(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1362,12 +1491,14 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1392,12 +1523,14 @@ func TestGetBatchPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) m.postService.EXPECT().GetBatchFromFriend(gomock.Any(), gomock.Any(), gomock.Any()). Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1420,12 +1553,14 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1448,13 +1583,17 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.postService.EXPECT().GetCommunityPost(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().GetCommunityPost( + gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), + ).Return(nil, nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1477,42 +1616,46 @@ func TestGetBatchPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()).Do(func(err, req any) {}) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1537,12 +1680,14 @@ func TestSetLikeOnPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1565,12 +1710,14 @@ func TestSetLikeOnPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1595,12 +1742,14 @@ func TestSetLikeOnPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1624,13 +1773,17 @@ func TestSetLikeOnPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return( + false, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1655,13 +1808,17 @@ func TestSetLikeOnPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, nil) - m.postService.EXPECT().SetLikeToPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().SetLikeToPost( + gomock.Any(), gomock.Any(), gomock.Any(), + ).Return(errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1687,42 +1844,46 @@ func TestSetLikeOnPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, nil) m.postService.EXPECT().SetLikeToPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1747,12 +1908,14 @@ func TestDeleteLikeFromPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1775,12 +1938,14 @@ func TestDeleteLikeFromPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1805,12 +1970,14 @@ func TestDeleteLikeFromPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, nil) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1834,13 +2001,17 @@ func TestDeleteLikeFromPost(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return( + false, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1865,13 +2036,17 @@ func TestDeleteLikeFromPost(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) - m.postService.EXPECT().DeleteLikeFromPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.postService.EXPECT().DeleteLikeFromPost( + gomock.Any(), gomock.Any(), gomock.Any(), + ).Return(errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1897,48 +2072,53 @@ func TestDeleteLikeFromPost(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.postService.EXPECT().CheckLikes(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) m.postService.EXPECT().DeleteLikeFromPost(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - serv, mock := getController(ctrl) - ctx := context.Background() + serv, mock := getController(ctrl) + ctx := context.Background() - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } - v.SetupMock(*input, mock) + v.SetupMock(*input, mock) - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } type mocks struct { - postService *MockPostService - responder *MockResponder + postService *MockPostService + responder *MockResponder + commentService *MockCommentService } type Request struct { diff --git a/internal/router/file/router.go b/internal/router/file/router.go index c5ae529a..4337e9a3 100644 --- a/internal/router/file/router.go +++ b/internal/router/file/router.go @@ -21,6 +21,7 @@ type SessionManager interface { type FileController interface { Upload(w http.ResponseWriter, r *http.Request) Download(w http.ResponseWriter, r *http.Request) + UploadNonImage(w http.ResponseWriter, r *http.Request) } func NewRouter( @@ -30,6 +31,7 @@ func NewRouter( router.HandleFunc("/image/{name}", fc.Upload).Methods(http.MethodGet, http.MethodOptions) router.HandleFunc("/image", fc.Download).Methods(http.MethodPost, http.MethodOptions) + router.HandleFunc("/file/{name}", fc.UploadNonImage).Methods(http.MethodGet, http.MethodOptions) router.Handle("/api/v1/metrics", promhttp.Handler()) diff --git a/internal/router/file/router_test.go b/internal/router/file/router_test.go index 6af2200b..1d88b5c0 100644 --- a/internal/router/file/router_test.go +++ b/internal/router/file/router_test.go @@ -27,6 +27,8 @@ func (m mockSessionManager) Destroy(sess *models.Session) error { type mockFileController struct{} +func (m mockFileController) UploadNonImage(w http.ResponseWriter, r *http.Request) {} + func (m mockFileController) Upload(w http.ResponseWriter, r *http.Request) {} func (m mockFileController) Download(w http.ResponseWriter, r *http.Request) {} From fa0e77c7e6c8af5603e849f77b8bb21b809bbf7b Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Wed, 11 Dec 2024 14:59:25 +0300 Subject: [PATCH 071/135] return test for comment --- internal/post/controller/controller_test.go | 886 ++++++++++++++++++++ 1 file changed, 886 insertions(+) diff --git a/internal/post/controller/controller_test.go b/internal/post/controller/controller_test.go index b69c00cb..43eaeeab 100644 --- a/internal/post/controller/controller_test.go +++ b/internal/post/controller/controller_test.go @@ -2115,6 +2115,892 @@ func TestDeleteLikeFromPost(t *testing.T) { } } +func TestComment(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/api/v1/feed/2", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/api/v1/feed/2", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/api/v1/feed/2", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "4", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/api/v1/feed/2", bytes.NewBuffer([]byte(`{"id":1}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusInternalServerError, Body: "error"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().Comment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + _, _ = request.w.Write([]byte("error")) + }, + ) + }, + }, + { + name: "5", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/api/v1/feed/2", bytes.NewBuffer([]byte(`{"id":1}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().Comment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return( + &models.Comment{ + Content: models.Content{ + Text: "New comment", + }, + }, nil, + ) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + _, _ = request.w.Write([]byte("OK")) + }, + ) + }, + }, + { + name: "6", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed/2", + bytes.NewBuffer([]byte(`{"file":"очень большой текст, написанный в поле файл, как он сюда попал - честно говоря хз, надо проверить валидацию на файл длину"}`)), + ) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Comment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + } + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestGetComment(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/feed/2/comment", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.GetComments(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/feed/2/comment?id=fnf", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.GetComments(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/feed/2/comment?id=4", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.GetComments(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusInternalServerError, Body: "error"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + _, _ = request.w.Write([]byte("error")) + }, + ) + }, + }, + { + name: "4", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/feed/2/comment?sort=old", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.GetComments(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + _, _ = request.w.Write([]byte("OK")) + }, + ) + }, + }, + { + name: "5", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/feed/2/comment", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "2"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.GetComments(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusNoContent}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().GetComments(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, my_err.ErrNoMoreContent) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestEditComment(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "4", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", bytes.NewBuffer([]byte(`{"text":"1"}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().EditComment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(my_err.ErrAccessDenied) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "5", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", bytes.NewBuffer([]byte(`{"text":"1"}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().EditComment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(my_err.ErrWrongComment) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "6", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", bytes.NewBuffer([]byte(`{"text":"1"}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusInternalServerError, Body: "error"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().EditComment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(errors.New("err")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + _, _ = request.w.Write([]byte("error")) + }, + ) + }, + }, + { + name: "7", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPut, "/api/v1/feed/2/1", bytes.NewBuffer([]byte(`{"text":"1"}`))) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().EditComment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + _, _ = request.w.Write([]byte("OK")) + }, + ) + }, + }, + { + name: "8", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodPut, "/api/v1/feed/2/1", + bytes.NewBuffer([]byte(`{"file":"очень большой текст, написанный в поле файл, как он сюда попал - честно говоря хз, надо проверить валидацию на файл длину"}`)), + ) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.EditComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestDeleteComment(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().DeleteComment(gomock.Any(), gomock.Any(), gomock.Any()). + Return(my_err.ErrAccessDenied) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "4", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().DeleteComment(gomock.Any(), gomock.Any(), gomock.Any()). + Return(my_err.ErrWrongComment) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "5", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusInternalServerError, Body: "error"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().DeleteComment(gomock.Any(), gomock.Any(), gomock.Any()). + Return(errors.New("err")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + _, _ = request.w.Write([]byte("error")) + }, + ) + }, + }, + { + name: "6", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodDelete, "/api/v1/feed/2/1", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{commentIDKey: "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.DeleteComment(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.commentService.EXPECT().DeleteComment(gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + _, _ = request.w.Write([]byte("OK")) + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + type mocks struct { postService *MockPostService responder *MockResponder From e579c713780588bb8a0a635dcca284f615e60c58 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 12 Dec 2024 15:13:07 +0300 Subject: [PATCH 072/135] bugfix --- docker-compose.yml | 1 + internal/fileService/service/fileService.go | 4 +- internal/middleware/fileMetrics.go | 64 +++++++++++---------- internal/router/file/router.go | 2 +- 4 files changed, 39 insertions(+), 32 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 42a290c6..6317f10d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -50,6 +50,7 @@ services: image: slashlight/file:latest volumes: - ./image:/image + - ./files:/files restart: always ports: - "8083:8083" diff --git a/internal/fileService/service/fileService.go b/internal/fileService/service/fileService.go index 700950b3..2b26d7d8 100644 --- a/internal/fileService/service/fileService.go +++ b/internal/fileService/service/fileService.go @@ -40,7 +40,7 @@ func (f *FileService) Download(ctx context.Context, file multipart.File, format func (f *FileService) DownloadNonImage(ctx context.Context, file multipart.File, format string) (string, error) { var ( fileName = uuid.New().String() - filePath = fmt.Sprintf("/file/%s.%s", fileName, format) + filePath = fmt.Sprintf("/files/%s.%s", fileName, format) dst, err = os.Create(filePath) ) defer func(dst *os.File) { @@ -79,7 +79,7 @@ func (f *FileService) Upload(ctx context.Context, name string) ([]byte, error) { func (f *FileService) UploadNonImage(ctx context.Context, name string) ([]byte, error) { var ( - file, err = os.Open(fmt.Sprintf("/file/%s", name)) + file, err = os.Open(fmt.Sprintf("/files/%s", name)) res []byte sl = make([]byte, 1024) ) diff --git a/internal/middleware/fileMetrics.go b/internal/middleware/fileMetrics.go index 9a55a646..315d47ad 100644 --- a/internal/middleware/fileMetrics.go +++ b/internal/middleware/fileMetrics.go @@ -41,35 +41,41 @@ func (rw *fileResponseWriter) Write(b []byte) (int, error) { } func FileMetricsMiddleware(metr *metrics.FileMetrics, next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - start := time.Now() - respWithCode := NewFileResponseWriter(w) - next.ServeHTTP(respWithCode, r) - statusCode := respWithCode.statusCode - path := r.URL.Path - method := r.Method - var ( - err error - format string - size int64 - ) - if r.Method == http.MethodPost { - format, size, err = getFormatAndSize(r) - } else if r.Method == http.MethodGet { - file := respWithCode.file - format = http.DetectContentType(file[:512]) - size = int64(len(file)) - } - if err != nil { - format = "error" - size = 0 - } - if statusCode != http.StatusOK && statusCode != http.StatusNoContent { - metr.IncErrors(path, strconv.Itoa(statusCode), method, format, size) - } - metr.IncHits(path, strconv.Itoa(statusCode), method, format, size) - metr.ObserveTiming(path, strconv.Itoa(statusCode), method, format, size, time.Since(start).Seconds()) - }) + return http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + start := time.Now() + respWithCode := NewFileResponseWriter(w) + next.ServeHTTP(respWithCode, r) + statusCode := respWithCode.statusCode + path := r.URL.Path + method := r.Method + var ( + err error + format string + size int64 + ) + if r.Method == http.MethodPost { + format, size, err = getFormatAndSize(r) + } else if r.Method == http.MethodGet { + file := respWithCode.file + size = int64(len(file)) + if size <= 512 { + format = http.DetectContentType(file[:size]) + } else { + format = http.DetectContentType(file[:512]) + } + } + if err != nil { + format = "error" + size = 0 + } + if statusCode != http.StatusOK && statusCode != http.StatusNoContent { + metr.IncErrors(path, strconv.Itoa(statusCode), method, format, size) + } + metr.IncHits(path, strconv.Itoa(statusCode), method, format, size) + metr.ObserveTiming(path, strconv.Itoa(statusCode), method, format, size, time.Since(start).Seconds()) + }, + ) } func getFormatAndSize(r *http.Request) (string, int64, error) { diff --git a/internal/router/file/router.go b/internal/router/file/router.go index 4337e9a3..3beebf22 100644 --- a/internal/router/file/router.go +++ b/internal/router/file/router.go @@ -31,7 +31,7 @@ func NewRouter( router.HandleFunc("/image/{name}", fc.Upload).Methods(http.MethodGet, http.MethodOptions) router.HandleFunc("/image", fc.Download).Methods(http.MethodPost, http.MethodOptions) - router.HandleFunc("/file/{name}", fc.UploadNonImage).Methods(http.MethodGet, http.MethodOptions) + router.HandleFunc("/files/{name}", fc.UploadNonImage).Methods(http.MethodGet, http.MethodOptions) router.Handle("/api/v1/metrics", promhttp.Handler()) From 8903f83324898665ce527c93ff78b38e05aeab17 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 12 Dec 2024 17:28:43 +0300 Subject: [PATCH 073/135] bugfix: requestID key --- internal/auth/controller/controller.go | 15 ++++++--- internal/chat/controller/controller.go | 7 ++-- internal/community/controller/controller.go | 19 ++++++----- internal/fileService/controller/controller.go | 5 +-- internal/middleware/accesslog.go | 21 +++++++----- internal/post/controller/controller.go | 23 ++++++------- internal/profile/controller/controller.go | 33 ++++++++++--------- 7 files changed, 69 insertions(+), 54 deletions(-) diff --git a/internal/auth/controller/controller.go b/internal/auth/controller/controller.go index 18cb4777..60eceb25 100644 --- a/internal/auth/controller/controller.go +++ b/internal/auth/controller/controller.go @@ -11,6 +11,7 @@ import ( "golang.org/x/crypto/bcrypt" "github.com/2024_2_BetterCallFirewall/internal/auth" + "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/pkg/my_err" @@ -35,7 +36,9 @@ type AuthController struct { SessionManager auth.SessionManager } -func NewAuthController(responder Responder, serviceAuth AuthService, sessionManager auth.SessionManager) *AuthController { +func NewAuthController( + responder Responder, serviceAuth AuthService, sessionManager auth.SessionManager, +) *AuthController { return &AuthController{ responder: responder, serviceAuth: serviceAuth, @@ -44,7 +47,7 @@ func NewAuthController(responder Responder, serviceAuth AuthService, sessionMana } func (c *AuthController) Register(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -57,7 +60,9 @@ func (c *AuthController) Register(w http.ResponseWriter, r *http.Request) { } user.ID, err = c.serviceAuth.Register(user, r.Context()) - if errors.Is(err, my_err.ErrUserAlreadyExists) || errors.Is(err, my_err.ErrNonValidEmail) || errors.Is(err, bcrypt.ErrPasswordTooLong) { + if errors.Is(err, my_err.ErrUserAlreadyExists) || errors.Is(err, my_err.ErrNonValidEmail) || errors.Is( + err, bcrypt.ErrPasswordTooLong, + ) { c.responder.ErrorBadRequest(w, err, reqID) return } @@ -87,7 +92,7 @@ func (c *AuthController) Register(w http.ResponseWriter, r *http.Request) { } func (c *AuthController) Auth(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -129,7 +134,7 @@ func (c *AuthController) Auth(w http.ResponseWriter, r *http.Request) { } func (c *AuthController) Logout(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } diff --git a/internal/chat/controller/controller.go b/internal/chat/controller/controller.go index 4cb7220c..efd28ede 100644 --- a/internal/chat/controller/controller.go +++ b/internal/chat/controller/controller.go @@ -12,6 +12,7 @@ import ( "github.com/gorilla/websocket" "github.com/2024_2_BetterCallFirewall/internal/chat" + "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/pkg/my_err" ) @@ -55,7 +56,7 @@ var ( ) func (cc *ChatController) SetConnection(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { cc.responder.LogError(my_err.ErrInvalidContext, "") return @@ -107,7 +108,7 @@ func (cc *ChatController) SendChatMsg(ctx context.Context, reqID string) { func (cc *ChatController) GetAllChats(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) lastTimeQuery = r.URL.Query().Get("lastTime") lastTime time.Time err error @@ -166,7 +167,7 @@ func GetIdFromURL(r *http.Request) (uint32, error) { func (cc *ChatController) GetChat(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) lastTimeQuery = r.URL.Query().Get("lastTime") lastTime time.Time err error diff --git a/internal/community/controller/controller.go b/internal/community/controller/controller.go index aaf0cf6f..82e178cb 100644 --- a/internal/community/controller/controller.go +++ b/internal/community/controller/controller.go @@ -10,6 +10,7 @@ import ( "github.com/gorilla/mux" + "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/pkg/my_err" ) @@ -50,7 +51,7 @@ func NewCommunityController(responder responder, service communityService) *Cont } func (c *Controller) GetOne(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -78,7 +79,7 @@ func (c *Controller) GetOne(w http.ResponseWriter, r *http.Request) { func (c *Controller) GetAll(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) lastID = r.URL.Query().Get("id") intLastID uint64 err error @@ -119,7 +120,7 @@ func (c *Controller) GetAll(w http.ResponseWriter, r *http.Request) { } func (c *Controller) Update(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -157,7 +158,7 @@ func (c *Controller) Update(w http.ResponseWriter, r *http.Request) { } func (c *Controller) Delete(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -189,7 +190,7 @@ func (c *Controller) Delete(w http.ResponseWriter, r *http.Request) { } func (c *Controller) Create(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -216,7 +217,7 @@ func (c *Controller) Create(w http.ResponseWriter, r *http.Request) { } func (c *Controller) JoinToCommunity(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -243,7 +244,7 @@ func (c *Controller) JoinToCommunity(w http.ResponseWriter, r *http.Request) { } func (c *Controller) LeaveFromCommunity(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -270,7 +271,7 @@ func (c *Controller) LeaveFromCommunity(w http.ResponseWriter, r *http.Request) } func (c *Controller) AddAdmin(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { c.responder.LogError(my_err.ErrInvalidContext, "") } @@ -314,7 +315,7 @@ func (c *Controller) AddAdmin(w http.ResponseWriter, r *http.Request) { func (c *Controller) SearchCommunity(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) subStr = r.URL.Query().Get("q") lastID = r.URL.Query().Get("id") id uint64 diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index 4a6b7484..8b95ec4f 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -10,6 +10,7 @@ import ( "github.com/gorilla/mux" + "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/pkg/my_err" ) @@ -76,7 +77,7 @@ func (fc *FileController) UploadNonImage(w http.ResponseWriter, r *http.Request) func (fc *FileController) Upload(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) vars = mux.Vars(r) name = vars["name"] ) @@ -100,7 +101,7 @@ func (fc *FileController) Upload(w http.ResponseWriter, r *http.Request) { } func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { fc.responder.LogError(my_err.ErrInvalidContext, "") } diff --git a/internal/middleware/accesslog.go b/internal/middleware/accesslog.go index fce8b070..9da97f26 100644 --- a/internal/middleware/accesslog.go +++ b/internal/middleware/accesslog.go @@ -11,14 +11,19 @@ import ( type requestID string -var requestKey requestID = "requestID" +var RequestKey requestID = "requestID" func AccessLog(logger *log.Logger, next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - id := uuid.New().String() - ctx := context.WithValue(r.Context(), requestKey, id) - start := time.Now() - next.ServeHTTP(w, r.WithContext(ctx)) - logger.Infof("New request:%s\n \tMethod: %v\n\tRemote addr: %v\n\tURL: %v\n\tTime: %v", id, r.Method, r.RemoteAddr, r.URL.String(), time.Since(start)) - }) + return http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + id := uuid.New().String() + ctx := context.WithValue(r.Context(), RequestKey, id) + start := time.Now() + next.ServeHTTP(w, r.WithContext(ctx)) + logger.Infof( + "New request:%s\n \tMethod: %v\n\tRemote addr: %v\n\tURL: %v\n\tTime: %v", id, r.Method, r.RemoteAddr, + r.URL.String(), time.Since(start), + ) + }, + ) } diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index 14a4c117..2c0ec656 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -13,6 +13,7 @@ import ( "github.com/gorilla/mux" + "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/pkg/my_err" ) @@ -74,7 +75,7 @@ func NewPostController(service PostService, commentService CommentService, respo func (pc *PostController) Create(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) comunity = r.URL.Query().Get("community") id uint32 err error @@ -125,7 +126,7 @@ func (pc *PostController) Create(w http.ResponseWriter, r *http.Request) { } func (pc *PostController) GetOne(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { pc.responder.LogError(my_err.ErrInvalidContext, "") } @@ -159,7 +160,7 @@ func (pc *PostController) GetOne(w http.ResponseWriter, r *http.Request) { func (pc *PostController) Update(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) id, err = getIDFromURL(r, postIDkey) community = r.URL.Query().Get("community") ) @@ -216,7 +217,7 @@ func (pc *PostController) Update(w http.ResponseWriter, r *http.Request) { func (pc *PostController) Delete(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) postID, err = getIDFromURL(r, postIDkey) community = r.URL.Query().Get("community") ) @@ -261,7 +262,7 @@ func (pc *PostController) Delete(w http.ResponseWriter, r *http.Request) { func (pc *PostController) GetBatchPosts(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) section = r.URL.Query().Get("section") communityID = r.URL.Query().Get("community") posts []*models.Post @@ -401,7 +402,7 @@ func (pc *PostController) checkAccessToCommunity(r *http.Request, communityID ui } func (pc *PostController) SetLikeOnPost(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { pc.responder.LogError(my_err.ErrInvalidContext, "") } @@ -439,7 +440,7 @@ func (pc *PostController) SetLikeOnPost(w http.ResponseWriter, r *http.Request) } func (pc *PostController) DeleteLikeFromPost(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { pc.responder.LogError(my_err.ErrInvalidContext, "") } @@ -476,7 +477,7 @@ func (pc *PostController) DeleteLikeFromPost(w http.ResponseWriter, r *http.Requ } func (pc *PostController) Comment(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { pc.responder.LogError(my_err.ErrInvalidContext, "") } @@ -515,7 +516,7 @@ func (pc *PostController) Comment(w http.ResponseWriter, r *http.Request) { } func (pc *PostController) DeleteComment(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { pc.responder.LogError(my_err.ErrInvalidContext, "") } @@ -552,7 +553,7 @@ func (pc *PostController) DeleteComment(w http.ResponseWriter, r *http.Request) } func (pc *PostController) EditComment(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { pc.responder.LogError(my_err.ErrInvalidContext, "") } @@ -599,7 +600,7 @@ func (pc *PostController) EditComment(w http.ResponseWriter, r *http.Request) { } func (pc *PostController) GetComments(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { pc.responder.LogError(my_err.ErrInvalidContext, "") } diff --git a/internal/profile/controller/controller.go b/internal/profile/controller/controller.go index f3475488..d731d941 100644 --- a/internal/profile/controller/controller.go +++ b/internal/profile/controller/controller.go @@ -11,6 +11,7 @@ import ( "github.com/gorilla/mux" "golang.org/x/crypto/bcrypt" + "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/internal/profile" "github.com/2024_2_BetterCallFirewall/pkg/my_err" @@ -39,7 +40,7 @@ func NewProfileController(manager profile.ProfileUsecase, responder Responder) * } func (h *ProfileHandlerImplementation) GetHeader(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { h.Responder.LogError(my_err.ErrInvalidContext, "") } @@ -65,7 +66,7 @@ func (h *ProfileHandlerImplementation) GetHeader(w http.ResponseWriter, r *http. } func (h *ProfileHandlerImplementation) GetProfile(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { h.Responder.LogError(my_err.ErrInvalidContext, "") } @@ -94,7 +95,7 @@ func (h *ProfileHandlerImplementation) GetProfile(w http.ResponseWriter, r *http } func (h *ProfileHandlerImplementation) UpdateProfile(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { h.Responder.LogError(my_err.ErrInvalidContext, "") } @@ -133,7 +134,7 @@ func (h *ProfileHandlerImplementation) getNewProfile(r *http.Request) (*models.F func (h *ProfileHandlerImplementation) DeleteProfile(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) sess, err = models.SessionFromContext(r.Context()) ) @@ -175,7 +176,7 @@ func GetIdFromURL(r *http.Request) (uint32, error) { func (h *ProfileHandlerImplementation) GetProfileById(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) id, err = GetIdFromURL(r) ) @@ -215,7 +216,7 @@ func GetLastId(r *http.Request) (uint32, error) { func (h *ProfileHandlerImplementation) GetAll(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) sess, err = models.SessionFromContext(r.Context()) ) @@ -262,7 +263,7 @@ func GetReceiverAndSender(r *http.Request) (uint32, uint32, error) { func (h *ProfileHandlerImplementation) SendFriendReq(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) receiver, sender, err = GetReceiverAndSender(r) ) @@ -286,7 +287,7 @@ func (h *ProfileHandlerImplementation) SendFriendReq(w http.ResponseWriter, r *h func (h *ProfileHandlerImplementation) AcceptFriendReq(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) whose, who, err = GetReceiverAndSender(r) ) @@ -308,7 +309,7 @@ func (h *ProfileHandlerImplementation) AcceptFriendReq(w http.ResponseWriter, r func (h *ProfileHandlerImplementation) RemoveFromFriends(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) whose, who, err = GetReceiverAndSender(r) ) @@ -330,7 +331,7 @@ func (h *ProfileHandlerImplementation) RemoveFromFriends(w http.ResponseWriter, func (h *ProfileHandlerImplementation) Unsubscribe(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) ) if !ok { @@ -352,7 +353,7 @@ func (h *ProfileHandlerImplementation) Unsubscribe(w http.ResponseWriter, r *htt func (h *ProfileHandlerImplementation) GetAllFriends(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) id, err = GetIdFromURL(r) ) @@ -386,7 +387,7 @@ func (h *ProfileHandlerImplementation) GetAllFriends(w http.ResponseWriter, r *h func (h *ProfileHandlerImplementation) GetAllSubs(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) id, err = GetIdFromURL(r) ) @@ -418,7 +419,7 @@ func (h *ProfileHandlerImplementation) GetAllSubs(w http.ResponseWriter, r *http func (h *ProfileHandlerImplementation) GetAllSubscriptions(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) id, err = GetIdFromURL(r) ) @@ -452,7 +453,7 @@ func (h *ProfileHandlerImplementation) GetAllSubscriptions(w http.ResponseWriter func (h *ProfileHandlerImplementation) GetCommunitySubs(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) id, err = GetIdFromURL(r) ) @@ -487,7 +488,7 @@ func (h *ProfileHandlerImplementation) GetCommunitySubs(w http.ResponseWriter, r func (h *ProfileHandlerImplementation) SearchProfile(w http.ResponseWriter, r *http.Request) { var ( - reqID, ok = r.Context().Value("requestID").(string) + reqID, ok = r.Context().Value(middleware.RequestKey).(string) subStr = r.URL.Query().Get("q") lastID = r.URL.Query().Get("id") id uint64 @@ -528,7 +529,7 @@ func (h *ProfileHandlerImplementation) SearchProfile(w http.ResponseWriter, r *h } func (h *ProfileHandlerImplementation) ChangePassword(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { h.Responder.LogError(my_err.ErrInvalidContext, "") } From 0a551aa40e3ba473676f740e1b80dfe54917d06d Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 12 Dec 2024 17:18:30 +0300 Subject: [PATCH 074/135] fix panic --- internal/fileService/controller/controller.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index 8b95ec4f..a6b87b1b 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -107,16 +107,16 @@ func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { } err := r.ParseMultipartForm(10 * (10 << 20)) // 100Mbyte + if err != nil { + fc.responder.ErrorBadRequest(w, my_err.ErrToLargeFile, reqID) + return + } defer func() { err = r.MultipartForm.RemoveAll() if err != nil { fc.responder.LogError(err, reqID) } }() - if err != nil { - fc.responder.ErrorBadRequest(w, my_err.ErrToLargeFile, reqID) - return - } file, header, err := r.FormFile("file") if err != nil { From 19a9f4ccc498b3a3e42cded0fc18ed7e409a195d Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 12 Dec 2024 17:54:53 +0300 Subject: [PATCH 075/135] fix tests --- .../fileService/controller/controller_test.go | 317 +++++++++++++++--- 1 file changed, 274 insertions(+), 43 deletions(-) diff --git a/internal/fileService/controller/controller_test.go b/internal/fileService/controller/controller_test.go index 35976ea9..cb536d54 100644 --- a/internal/fileService/controller/controller_test.go +++ b/internal/fileService/controller/controller_test.go @@ -3,6 +3,7 @@ package controller import ( "context" "errors" + "mime/multipart" "net/http" "net/http/httptest" "testing" @@ -56,12 +57,14 @@ func TestUpload(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -85,12 +88,14 @@ func TestUpload(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.fileService.EXPECT().Upload(gomock.Any(), gomock.Any()).Return(nil, errMock) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -114,42 +119,268 @@ func TestUpload(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.fileService.EXPECT().Upload(gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputBytes(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputBytes(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestUploadNonImage(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/files/default", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *FileController, request Request) (Response, error) { + implementation.UploadNonImage(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/files/default", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"name": "default"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *FileController, request Request) (Response, error) { + implementation.UploadNonImage(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.fileService.EXPECT().UploadNonImage(gomock.Any(), gomock.Any()).Return(nil, errMock) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/files/default", nil) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"name": "default"}) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *FileController, request Request) (Response, error) { + implementation.UploadNonImage(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.fileService.EXPECT().UploadNonImage(gomock.Any(), gomock.Any()).Return(nil, nil) + m.responder.EXPECT().OutputBytes(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestDownload(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/image", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *FileController, request Request) (Response, error) { + implementation.Download(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/image", nil) + w := httptest.NewRecorder() + req.MultipartForm = &multipart.Form{ + File: make(map[string][]*multipart.FileHeader), + } + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *FileController, request Request) (Response, error) { + implementation.Download(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } From 985e1cc5bfb43c2b2a8dc22fad12e5d1bbb6da13 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 12 Dec 2024 18:53:02 +0300 Subject: [PATCH 076/135] fix: responder --- internal/router/responder.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/internal/router/responder.go b/internal/router/responder.go index 29ce8895..fb7dab96 100644 --- a/internal/router/responder.go +++ b/internal/router/responder.go @@ -60,8 +60,15 @@ func (r *Respond) OutputNoMoreContentJSON(w http.ResponseWriter, requestID strin } func (r *Respond) OutputBytes(w http.ResponseWriter, data []byte, requestID string) { - w.Header().Set("Content-Type", "image/avif,image/webp") - w.Header().Set("Access-Control-Allow-Origin", "http://185.241.194.197:8000") + var format string + if len(data) < 512 { + format = http.DetectContentType(data) + } else { + format = http.DetectContentType(data[:512]) + } + + w.Header().Set("Content-Type", format) + w.Header().Set("Access-Control-Allow-Origin", "http://vilka.online") w.Header().Set("Access-Control-Allow-Credentials", "true") w.WriteHeader(http.StatusOK) From c573ac75fe95d2d8efd541e2d205c0cb8923bb4b Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Thu, 12 Dec 2024 20:52:17 +0300 Subject: [PATCH 077/135] Update go.yml --- .github/workflows/go.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 70dbf5c5..f3694ec7 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -45,7 +45,6 @@ jobs: run: go test -v ./... build: - needs: [tests, linter] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From bdc1a7e0045882bdf7350579b2b7b04451e2d561 Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:13:43 +0300 Subject: [PATCH 078/135] Update go.yml --- .github/workflows/go.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index f3694ec7..d96b809f 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -45,6 +45,7 @@ jobs: run: go test -v ./... build: + needs: tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From c31e8bb4d474871867ca71aa049b843aef65b702 Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:22:43 +0300 Subject: [PATCH 079/135] Update go.yml --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index d96b809f..70dbf5c5 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -45,7 +45,7 @@ jobs: run: go test -v ./... build: - needs: tests + needs: [tests, linter] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From 59d255d614cc9175e5efdd851ab9976d7fec0262 Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:45:35 +0300 Subject: [PATCH 080/135] Update docker-compose.yml --- docker-compose.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 6317f10d..42a290c6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -50,7 +50,6 @@ services: image: slashlight/file:latest volumes: - ./image:/image - - ./files:/files restart: always ports: - "8083:8083" From f2601116580287aabe074e2b7da8da9add3a1ee1 Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:48:18 +0300 Subject: [PATCH 081/135] Update docker-compose.yml --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 42a290c6..6317f10d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -50,6 +50,7 @@ services: image: slashlight/file:latest volumes: - ./image:/image + - ./files:/files restart: always ports: - "8083:8083" From 63fc26df3994e50cb2fbdeea953bbf891646ad26 Mon Sep 17 00:00:00 2001 From: Alexeyzem <92686279+Alexeyzem@users.noreply.github.com> Date: Fri, 13 Dec 2024 16:13:17 +0300 Subject: [PATCH 082/135] Update controller.go --- internal/post/controller/controller.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index 2c0ec656..4c0ee3b5 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -21,7 +21,8 @@ import ( const ( postIDkey = "id" commentIDKey = "comment_id" - filePrefix = "/image/" + imagePrefix = "/image/" + filePrefix = "/files/" ) //go:generate mockgen -destination=mock.go -source=$GOFILE -package=${GOPACKAGE} @@ -644,5 +645,5 @@ func validateContent(content models.Content) bool { } func validateFile(filepath models.Picture) bool { - return len(filepath) < 100 && (len(filepath) == 0 || strings.HasPrefix(string(filepath), filePrefix)) + return len(filepath) < 100 && (len(filepath) == 0 || strings.HasPrefix(string(filepath), filePrefix) || strings.HasPrefix(string(filepath), imagePrefix)) } From afaac35f7d9d7e3ad0cda3a8e31ac9fa5cc8393a Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sat, 14 Dec 2024 13:03:23 +0300 Subject: [PATCH 083/135] add tests for controller --- internal/stickers/controller/controller.go | 26 +- .../stickers/controller/controller_test.go | 540 ++++++++++++++++++ internal/stickers/controller/mock.go | 172 ++++++ internal/stickers/sticker_controller.go | 11 - pkg/my_err/error.go | 1 + 5 files changed, 734 insertions(+), 16 deletions(-) create mode 100644 internal/stickers/controller/controller_test.go create mode 100644 internal/stickers/controller/mock.go delete mode 100644 internal/stickers/sticker_controller.go diff --git a/internal/stickers/controller/controller.go b/internal/stickers/controller/controller.go index 1c02c4d7..e00c8fdd 100644 --- a/internal/stickers/controller/controller.go +++ b/internal/stickers/controller/controller.go @@ -1,14 +1,20 @@ package controller import ( + "encoding/json" "errors" + "fmt" "net/http" + "strings" "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/internal/stickers" "github.com/2024_2_BetterCallFirewall/pkg/my_err" ) +const imagePrefix = "/image/" + +//go:generate mockgen -destination=mock.go -source=$GOFILE -package=${GOPACKAGE} type Responder interface { OutputJSON(w http.ResponseWriter, data any, requestID string) OutputNoMoreContentJSON(w http.ResponseWriter, requestID string) @@ -37,15 +43,21 @@ func (s StickersHandlerImplementation) AddNewSticker(w http.ResponseWriter, r *h s.Responder.LogError(my_err.ErrInvalidContext, "") } - filePath := r.URL.Query().Get("file_path") - if filePath == "" { - s.Responder.ErrorBadRequest(w, my_err.ErrInvalidQuery, reqID) + filePath := "" + if err := json.NewDecoder(r.Body).Decode(&filePath); err != nil { + s.Responder.ErrorBadRequest(w, my_err.ErrNoFile, reqID) + fmt.Println(err) + return + } + + if !validate(filePath) { + s.Responder.ErrorBadRequest(w, my_err.ErrNoImage, reqID) return } sess, err := models.SessionFromContext(r.Context()) if err != nil { - s.Responder.ErrorInternal(w, err, reqID) + s.Responder.ErrorBadRequest(w, err, reqID) return } @@ -87,7 +99,7 @@ func (s StickersHandlerImplementation) GetMineStickers(w http.ResponseWriter, r sess, err := models.SessionFromContext(r.Context()) if err != nil { - s.Responder.ErrorInternal(w, err, reqID) + s.Responder.ErrorBadRequest(w, err, reqID) return } @@ -103,3 +115,7 @@ func (s StickersHandlerImplementation) GetMineStickers(w http.ResponseWriter, r s.Responder.OutputJSON(w, res, reqID) } + +func validate(filepath string) bool { + return len(filepath) < 100 && strings.HasPrefix(filepath, imagePrefix) +} diff --git a/internal/stickers/controller/controller_test.go b/internal/stickers/controller/controller_test.go new file mode 100644 index 00000000..987b2cbe --- /dev/null +++ b/internal/stickers/controller/controller_test.go @@ -0,0 +1,540 @@ +package controller + +import ( + "bytes" + "context" + "errors" + "net/http" + "net/http/httptest" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/2024_2_BetterCallFirewall/internal/models" + "github.com/2024_2_BetterCallFirewall/pkg/my_err" +) + +var errMock = errors.New("mock error") + +func getController(ctrl *gomock.Controller) (*StickersHandlerImplementation, *mocks) { + m := &mocks{ + stickerService: NewMockUsecase(ctrl), + responder: NewMockResponder(ctrl), + } + + return NewStickerController(m.stickerService, m.responder), m +} + +func TestNewPostController(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + handler, _ := getController(ctrl) + assert.NotNil(t, handler) +} + +func TestAddNewSticker(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/api/v1/stickers", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *StickersHandlerImplementation, request Request, + ) (Response, error) { + implementation.AddNewSticker(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodPost, "/api/v1/stickers", bytes.NewBuffer([]byte(`"files"`))) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *StickersHandlerImplementation, request Request, + ) (Response, error) { + implementation.AddNewSticker(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodPost, "/api/v1/stickers", bytes.NewBuffer([]byte(`"/image/someimage"`)), + ) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *StickersHandlerImplementation, request Request, + ) (Response, error) { + implementation.AddNewSticker(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "4", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodPost, "/api/v1/stickers", bytes.NewBuffer([]byte(`"/image/someimage"`)), + ) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *StickersHandlerImplementation, request Request, + ) (Response, error) { + implementation.AddNewSticker(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusInternalServerError, Body: "error"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.stickerService.EXPECT().AddNewSticker(gomock.Any(), gomock.Any(), gomock.Any()).Return(errMock) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + _, _ = request.w.Write([]byte("error")) + }, + ) + }, + }, + { + name: "5", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodPost, "/api/v1/stickers", bytes.NewBuffer([]byte(`"/image/someimage"`)), + ) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *StickersHandlerImplementation, request Request, + ) (Response, error) { + implementation.AddNewSticker(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.stickerService.EXPECT().AddNewSticker(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + _, _ = request.w.Write([]byte("OK")) + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestGetAllSticker(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/stickers/all", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *StickersHandlerImplementation, request Request, + ) (Response, error) { + implementation.GetAllStickers(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusNoContent}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.stickerService.EXPECT().GetAllStickers(gomock.Any()).Return(nil, my_err.ErrNoStickers) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/stickers/all", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *StickersHandlerImplementation, request Request, + ) (Response, error) { + implementation.GetAllStickers(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusInternalServerError, Body: "error"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.stickerService.EXPECT().GetAllStickers(gomock.Any()).Return(nil, errMock) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + _, _ = request.w.Write([]byte("error")) + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/stickers/all", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *StickersHandlerImplementation, request Request, + ) (Response, error) { + implementation.GetAllStickers(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + pic := models.Picture("/image/sticker1") + m.stickerService.EXPECT().GetAllStickers(gomock.Any()).Return([]*models.Picture{&pic}, nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + _, _ = request.w.Write([]byte("OK")) + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestGetMineSticker(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/stickers", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *StickersHandlerImplementation, request Request, + ) (Response, error) { + implementation.GetMineStickers(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/stickers", nil) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *StickersHandlerImplementation, request Request, + ) (Response, error) { + implementation.GetMineStickers(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusInternalServerError, Body: "error"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.stickerService.EXPECT().GetMineStickers(gomock.Any(), gomock.Any()).Return(nil, errMock) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + _, _ = request.w.Write([]byte("error")) + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/stickers", nil) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *StickersHandlerImplementation, request Request, + ) (Response, error) { + implementation.GetMineStickers(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + pic := models.Picture("/image/sticker1") + m.stickerService.EXPECT().GetMineStickers(gomock.Any(), gomock.Any()).Return( + []*models.Picture{&pic}, nil, + ) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + _, _ = request.w.Write([]byte("OK")) + }, + ) + }, + }, + { + name: "4", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/stickers", nil) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *StickersHandlerImplementation, request Request, + ) (Response, error) { + implementation.GetMineStickers(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusNoContent}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.stickerService.EXPECT().GetMineStickers(gomock.Any(), gomock.Any()).Return( + nil, my_err.ErrNoStickers, + ) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +type mocks struct { + stickerService *MockUsecase + responder *MockResponder +} + +type Request struct { + w *httptest.ResponseRecorder + r *http.Request +} + +type Response struct { + StatusCode int + Body string +} + +type TableTest[T, In any] struct { + name string + SetupInput func() (*In, error) + Run func(context.Context, *StickersHandlerImplementation, In) (T, error) + ExpectedResult func() (T, error) + ExpectedErr error + SetupMock func(In, *mocks) +} diff --git a/internal/stickers/controller/mock.go b/internal/stickers/controller/mock.go new file mode 100644 index 00000000..cabb0cfa --- /dev/null +++ b/internal/stickers/controller/mock.go @@ -0,0 +1,172 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: controller.go +// +// Generated by this command: +// +// mockgen -destination=mock.go -source=controller.go -package=controller +// + +// Package controller is a generated GoMock package. +package controller + +import ( + context "context" + http "net/http" + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + + models "github.com/2024_2_BetterCallFirewall/internal/models" +) + +// MockUsecase is a mock of Usecase interface. +type MockUsecase struct { + ctrl *gomock.Controller + recorder *MockUsecaseMockRecorder + isgomock struct{} +} + +// MockUsecaseMockRecorder is the mock recorder for MockUsecase. +type MockUsecaseMockRecorder struct { + mock *MockUsecase +} + +// NewMockUsecase creates a new mock instance. +func NewMockUsecase(ctrl *gomock.Controller) *MockUsecase { + mock := &MockUsecase{ctrl: ctrl} + mock.recorder = &MockUsecaseMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockUsecase) EXPECT() *MockUsecaseMockRecorder { + return m.recorder +} + +// AddNewSticker mocks base method. +func (m *MockUsecase) AddNewSticker(ctx context.Context, filepath string, userID uint32) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddNewSticker", ctx, filepath, userID) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddNewSticker indicates an expected call of AddNewSticker. +func (mr *MockUsecaseMockRecorder) AddNewSticker(ctx, filepath, userID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddNewSticker", reflect.TypeOf((*MockUsecase)(nil).AddNewSticker), ctx, filepath, userID) +} + +// GetAllStickers mocks base method. +func (m *MockUsecase) GetAllStickers(ctx context.Context) ([]*models.Picture, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAllStickers", ctx) + ret0, _ := ret[0].([]*models.Picture) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAllStickers indicates an expected call of GetAllStickers. +func (mr *MockUsecaseMockRecorder) GetAllStickers(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllStickers", reflect.TypeOf((*MockUsecase)(nil).GetAllStickers), ctx) +} + +// GetMineStickers mocks base method. +func (m *MockUsecase) GetMineStickers(ctx context.Context, userID uint32) ([]*models.Picture, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetMineStickers", ctx, userID) + ret0, _ := ret[0].([]*models.Picture) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetMineStickers indicates an expected call of GetMineStickers. +func (mr *MockUsecaseMockRecorder) GetMineStickers(ctx, userID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMineStickers", reflect.TypeOf((*MockUsecase)(nil).GetMineStickers), ctx, userID) +} + +// MockResponder is a mock of Responder interface. +type MockResponder struct { + ctrl *gomock.Controller + recorder *MockResponderMockRecorder + isgomock struct{} +} + +// MockResponderMockRecorder is the mock recorder for MockResponder. +type MockResponderMockRecorder struct { + mock *MockResponder +} + +// NewMockResponder creates a new mock instance. +func NewMockResponder(ctrl *gomock.Controller) *MockResponder { + mock := &MockResponder{ctrl: ctrl} + mock.recorder = &MockResponderMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockResponder) EXPECT() *MockResponderMockRecorder { + return m.recorder +} + +// ErrorBadRequest mocks base method. +func (m *MockResponder) ErrorBadRequest(w http.ResponseWriter, err error, requestID string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ErrorBadRequest", w, err, requestID) +} + +// ErrorBadRequest indicates an expected call of ErrorBadRequest. +func (mr *MockResponderMockRecorder) ErrorBadRequest(w, err, requestID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ErrorBadRequest", reflect.TypeOf((*MockResponder)(nil).ErrorBadRequest), w, err, requestID) +} + +// ErrorInternal mocks base method. +func (m *MockResponder) ErrorInternal(w http.ResponseWriter, err error, requestID string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ErrorInternal", w, err, requestID) +} + +// ErrorInternal indicates an expected call of ErrorInternal. +func (mr *MockResponderMockRecorder) ErrorInternal(w, err, requestID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ErrorInternal", reflect.TypeOf((*MockResponder)(nil).ErrorInternal), w, err, requestID) +} + +// LogError mocks base method. +func (m *MockResponder) LogError(err error, requestID string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "LogError", err, requestID) +} + +// LogError indicates an expected call of LogError. +func (mr *MockResponderMockRecorder) LogError(err, requestID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogError", reflect.TypeOf((*MockResponder)(nil).LogError), err, requestID) +} + +// OutputJSON mocks base method. +func (m *MockResponder) OutputJSON(w http.ResponseWriter, data any, requestID string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "OutputJSON", w, data, requestID) +} + +// OutputJSON indicates an expected call of OutputJSON. +func (mr *MockResponderMockRecorder) OutputJSON(w, data, requestID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OutputJSON", reflect.TypeOf((*MockResponder)(nil).OutputJSON), w, data, requestID) +} + +// OutputNoMoreContentJSON mocks base method. +func (m *MockResponder) OutputNoMoreContentJSON(w http.ResponseWriter, requestID string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "OutputNoMoreContentJSON", w, requestID) +} + +// OutputNoMoreContentJSON indicates an expected call of OutputNoMoreContentJSON. +func (mr *MockResponderMockRecorder) OutputNoMoreContentJSON(w, requestID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OutputNoMoreContentJSON", reflect.TypeOf((*MockResponder)(nil).OutputNoMoreContentJSON), w, requestID) +} diff --git a/internal/stickers/sticker_controller.go b/internal/stickers/sticker_controller.go deleted file mode 100644 index c722c7d2..00000000 --- a/internal/stickers/sticker_controller.go +++ /dev/null @@ -1,11 +0,0 @@ -package stickers - -import ( - "net/http" -) - -type Controller interface { - AddNewSticker(w http.ResponseWriter, r *http.Request) - GetAllStickers(w http.ResponseWriter, r *http.Request) - GetMineStickers(w http.ResponseWriter, r *http.Request) -} diff --git a/pkg/my_err/error.go b/pkg/my_err/error.go index 0004aa74..53e774a5 100644 --- a/pkg/my_err/error.go +++ b/pkg/my_err/error.go @@ -36,4 +36,5 @@ var ( ErrTextTooLong = errors.New("text len is too big") ErrWrongComment = errors.New("wrong comment") ErrNoStickers = errors.New("no stickers found") + ErrNoImage = errors.New("file is no image") ) From 9c3cb48f6d17391fcb9b34545416de2f79c7a465 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sat, 14 Dec 2024 13:19:55 +0300 Subject: [PATCH 084/135] feature: test for sticker service --- internal/stickers/service/mock.go | 86 +++++++ internal/stickers/service/usecase_test.go | 262 ++++++++++++++++++++++ 2 files changed, 348 insertions(+) create mode 100644 internal/stickers/service/mock.go create mode 100644 internal/stickers/service/usecase_test.go diff --git a/internal/stickers/service/mock.go b/internal/stickers/service/mock.go new file mode 100644 index 00000000..6c63501b --- /dev/null +++ b/internal/stickers/service/mock.go @@ -0,0 +1,86 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: usecase.go +// +// Generated by this command: +// +// mockgen -destination=mock.go -source=usecase.go -package=service +// + +// Package service is a generated GoMock package. +package service + +import ( + context "context" + reflect "reflect" + + models "github.com/2024_2_BetterCallFirewall/internal/models" + gomock "github.com/golang/mock/gomock" +) + +// MockRepository is a mock of Repository interface. +type MockRepository struct { + ctrl *gomock.Controller + recorder *MockRepositoryMockRecorder + isgomock struct{} +} + +// MockRepositoryMockRecorder is the mock recorder for MockRepository. +type MockRepositoryMockRecorder struct { + mock *MockRepository +} + +// NewMockRepository creates a new mock instance. +func NewMockRepository(ctrl *gomock.Controller) *MockRepository { + mock := &MockRepository{ctrl: ctrl} + mock.recorder = &MockRepositoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { + return m.recorder +} + +// AddNewSticker mocks base method. +func (m *MockRepository) AddNewSticker(ctx context.Context, filepath string, userID uint32) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddNewSticker", ctx, filepath, userID) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddNewSticker indicates an expected call of AddNewSticker. +func (mr *MockRepositoryMockRecorder) AddNewSticker(ctx, filepath, userID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddNewSticker", reflect.TypeOf((*MockRepository)(nil).AddNewSticker), ctx, filepath, userID) +} + +// GetAllStickers mocks base method. +func (m *MockRepository) GetAllStickers(ctx context.Context) ([]*models.Picture, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAllStickers", ctx) + ret0, _ := ret[0].([]*models.Picture) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAllStickers indicates an expected call of GetAllStickers. +func (mr *MockRepositoryMockRecorder) GetAllStickers(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllStickers", reflect.TypeOf((*MockRepository)(nil).GetAllStickers), ctx) +} + +// GetMineStickers mocks base method. +func (m *MockRepository) GetMineStickers(ctx context.Context, userID uint32) ([]*models.Picture, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetMineStickers", ctx, userID) + ret0, _ := ret[0].([]*models.Picture) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetMineStickers indicates an expected call of GetMineStickers. +func (mr *MockRepositoryMockRecorder) GetMineStickers(ctx, userID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMineStickers", reflect.TypeOf((*MockRepository)(nil).GetMineStickers), ctx, userID) +} diff --git a/internal/stickers/service/usecase_test.go b/internal/stickers/service/usecase_test.go new file mode 100644 index 00000000..5258a714 --- /dev/null +++ b/internal/stickers/service/usecase_test.go @@ -0,0 +1,262 @@ +package service + +import ( + "context" + "errors" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/2024_2_BetterCallFirewall/internal/models" +) + +var ( + errMock = errors.New("mock error") + pic = models.Picture("/image/sticker") +) + +func getUseCase(ctrl *gomock.Controller) (*StickerUsecaseImplementation, *mocks) { + m := &mocks{ + repository: NewMockRepository(ctrl), + } + + return NewStickerUsecase(m.repository), m +} + +type input struct { + userID uint32 + filepath string +} + +func TestAddNewSticker(t *testing.T) { + tests := []TableTest[struct{}, input]{ + { + name: "1", + SetupInput: func() (*input, error) { + return &input{filepath: "", userID: 0}, nil + }, + Run: func( + ctx context.Context, implementation *StickerUsecaseImplementation, request input, + ) (struct{}, error) { + err := implementation.AddNewSticker(ctx, request.filepath, request.userID) + return struct{}{}, err + }, + ExpectedResult: func() (struct{}, error) { + return struct{}{}, nil + }, + ExpectedErr: errMock, + SetupMock: func(request input, m *mocks) { + m.repository.EXPECT().AddNewSticker(gomock.Any(), gomock.Any(), gomock.Any()). + Return(errMock) + }, + }, + { + name: "2", + SetupInput: func() (*input, error) { + return &input{filepath: "/image/sticker", userID: 1}, nil + }, + Run: func( + ctx context.Context, implementation *StickerUsecaseImplementation, request input, + ) (struct{}, error) { + err := implementation.AddNewSticker(ctx, request.filepath, request.userID) + return struct{}{}, err + }, + ExpectedResult: func() (struct{}, error) { + return struct{}{}, nil + }, + ExpectedErr: nil, + SetupMock: func(request input, m *mocks) { + m.repository.EXPECT().AddNewSticker(gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getUseCase(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestGetMineSticker(t *testing.T) { + tests := []TableTest[[]*models.Picture, uint32]{ + { + name: "1", + SetupInput: func() (*uint32, error) { + req := uint32(0) + return &req, nil + }, + Run: func( + ctx context.Context, implementation *StickerUsecaseImplementation, request uint32, + ) ([]*models.Picture, error) { + return implementation.GetMineStickers(ctx, request) + }, + ExpectedResult: func() ([]*models.Picture, error) { + return nil, nil + }, + ExpectedErr: errMock, + SetupMock: func(request uint32, m *mocks) { + m.repository.EXPECT().GetMineStickers(gomock.Any(), gomock.Any()).Return(nil, errMock) + }, + }, + { + name: "2", + SetupInput: func() (*uint32, error) { + req := uint32(10) + return &req, nil + }, + Run: func( + ctx context.Context, implementation *StickerUsecaseImplementation, request uint32, + ) ([]*models.Picture, error) { + return implementation.GetMineStickers(ctx, request) + }, + ExpectedResult: func() ([]*models.Picture, error) { + return []*models.Picture{&pic}, nil + }, + ExpectedErr: nil, + SetupMock: func(request uint32, m *mocks) { + m.repository.EXPECT().GetMineStickers(gomock.Any(), gomock.Any()).Return([]*models.Picture{&pic}, nil) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getUseCase(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestGetAllSticker(t *testing.T) { + tests := []TableTest[[]*models.Picture, struct{}]{ + { + name: "1", + SetupInput: func() (*struct{}, error) { + return &struct{}{}, nil + }, + Run: func( + ctx context.Context, implementation *StickerUsecaseImplementation, request struct{}, + ) ([]*models.Picture, error) { + return implementation.GetAllStickers(ctx) + }, + ExpectedResult: func() ([]*models.Picture, error) { + return nil, nil + }, + ExpectedErr: errMock, + SetupMock: func(request struct{}, m *mocks) { + m.repository.EXPECT().GetAllStickers(gomock.Any()).Return(nil, errMock) + }, + }, + { + name: "2", + SetupInput: func() (*struct{}, error) { + return &struct{}{}, nil + }, + Run: func( + ctx context.Context, implementation *StickerUsecaseImplementation, request struct{}, + ) ([]*models.Picture, error) { + return implementation.GetAllStickers(ctx) + }, + ExpectedResult: func() ([]*models.Picture, error) { + return []*models.Picture{&pic}, nil + }, + ExpectedErr: nil, + SetupMock: func(request struct{}, m *mocks) { + m.repository.EXPECT().GetAllStickers(gomock.Any()).Return([]*models.Picture{&pic}, nil) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getUseCase(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +type TableTest[T, In any] struct { + name string + SetupInput func() (*In, error) + Run func(context.Context, *StickerUsecaseImplementation, In) (T, error) + ExpectedResult func() (T, error) + ExpectedErr error + SetupMock func(In, *mocks) +} + +type mocks struct { + repository *MockRepository +} From bc9e36b1d4998a94b05fd838f878483bccfe8cf9 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sat, 14 Dec 2024 13:22:14 +0300 Subject: [PATCH 085/135] add test for sticker router --- internal/router/stickers/touter_test.go | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 internal/router/stickers/touter_test.go diff --git a/internal/router/stickers/touter_test.go b/internal/router/stickers/touter_test.go new file mode 100644 index 00000000..ba5de64a --- /dev/null +++ b/internal/router/stickers/touter_test.go @@ -0,0 +1,38 @@ +package stickers + +import ( + "net/http" + "testing" + + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + + "github.com/2024_2_BetterCallFirewall/internal/models" +) + +type mockSessionManager struct{} + +func (m mockSessionManager) Check(s string) (*models.Session, error) { + return nil, nil +} + +func (m mockSessionManager) Create(userID uint32) (*models.Session, error) { + return nil, nil +} + +func (m mockSessionManager) Destroy(sess *models.Session) error { + return nil +} + +type mockStickerController struct{} + +func (m mockStickerController) GetAllStickers(w http.ResponseWriter, r *http.Request) {} + +func (m mockStickerController) AddNewSticker(w http.ResponseWriter, r *http.Request) {} + +func (m mockStickerController) GetMineStickers(w http.ResponseWriter, r *http.Request) {} + +func TestNewRouter(t *testing.T) { + r := NewRouter(mockStickerController{}, mockSessionManager{}, logrus.New()) + assert.NotNil(t, r) +} From 2c0c4cb89a4a8da7ad4e9a66261383824f2bdbbc Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sat, 14 Dec 2024 16:52:31 +0300 Subject: [PATCH 086/135] feat: validation to create post and controller --- internal/post/controller/controller.go | 4 + internal/post/controller/controller_test.go | 94 ++++++++++++++++++--- 2 files changed, 86 insertions(+), 12 deletions(-) diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index 3196097d..a49a29e7 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -649,6 +649,10 @@ func (pc *PostController) GetComments(w http.ResponseWriter, r *http.Request) { } func validateContent(content models.Content) bool { + if len(content.File) == 0 && len(content.Text) == 0 { + return false + } + return validateFile(content.File) && len(content.Text) < 500 } diff --git a/internal/post/controller/controller_test.go b/internal/post/controller/controller_test.go index 4a6692b1..4efe3cec 100644 --- a/internal/post/controller/controller_test.go +++ b/internal/post/controller/controller_test.go @@ -69,7 +69,7 @@ func TestCreate(t *testing.T) { SetupInput: func() (*Request, error) { req := httptest.NewRequest( http.MethodPost, "/api/v1/feed", - bytes.NewBuffer([]byte(`{"id":1}`)), + bytes.NewBuffer([]byte(`{"id":1, "post_content":{"text":"text"}}`)), ) w := httptest.NewRecorder() res := &Request{r: req, w: w} @@ -101,7 +101,7 @@ func TestCreate(t *testing.T) { SetupInput: func() (*Request, error) { req := httptest.NewRequest( http.MethodPost, "/api/v1/feed", - bytes.NewBuffer([]byte(`{"id":1}`)), + bytes.NewBuffer([]byte(`{"id":1, "post_content":{"text":"text"}}`)), ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -135,7 +135,7 @@ func TestCreate(t *testing.T) { SetupInput: func() (*Request, error) { req := httptest.NewRequest( http.MethodPost, "/api/v1/feed", - bytes.NewBuffer([]byte(`{"id":1}`)), + bytes.NewBuffer([]byte(`{"id":1, "post_content":{"text":"text"}}`)), ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -202,7 +202,7 @@ func TestCreate(t *testing.T) { SetupInput: func() (*Request, error) { req := httptest.NewRequest( http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"id":1}`)), + bytes.NewBuffer([]byte(`{"id":1, "post_content":{"text":"text"}}`)), ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -236,7 +236,7 @@ func TestCreate(t *testing.T) { SetupInput: func() (*Request, error) { req := httptest.NewRequest( http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"id":1}`)), + bytes.NewBuffer([]byte(`{"id":1, "post_content":{"text":"text"}}`)), ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -273,7 +273,7 @@ func TestCreate(t *testing.T) { SetupInput: func() (*Request, error) { req := httptest.NewRequest( http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"id":1}`)), + bytes.NewBuffer([]byte(`{"id":1, "post_content":{"text":"text"}}`)), ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -336,6 +336,72 @@ func TestCreate(t *testing.T) { ) }, }, + { + name: "10", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=10", + bytes.NewBuffer([]byte(`{"post_content":{"text":""}}`)), + ) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Create(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "11", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed?community=text", + bytes.NewBuffer([]byte(`{"post_content":{"text":"text"}}`)), + ) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *PostController, request Request) (Response, error) { + implementation.Create(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, } for _, v := range tests { @@ -720,7 +786,7 @@ func TestUpdate(t *testing.T) { SetupInput: func() (*Request, error) { req := httptest.NewRequest( http.MethodPut, "/api/v1/feed/10", - bytes.NewBuffer([]byte(`{"id":1}`)), + bytes.NewBuffer([]byte(`{"id":1, "post_content":{"text":"text"}}`)), ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) @@ -756,7 +822,7 @@ func TestUpdate(t *testing.T) { SetupInput: func() (*Request, error) { req := httptest.NewRequest( http.MethodPut, "/api/v1/feed/10", - bytes.NewBuffer([]byte(`{"id":1}`)), + bytes.NewBuffer([]byte(`{"id":1, "post_content":{"text":"text"}}`)), ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) @@ -792,7 +858,7 @@ func TestUpdate(t *testing.T) { SetupInput: func() (*Request, error) { req := httptest.NewRequest( http.MethodPut, "/api/v1/feed/10", - bytes.NewBuffer([]byte(`{"id":1}`)), + bytes.NewBuffer([]byte(`{"id":1, "post_content":{"text":"text"}}`)), ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) @@ -897,7 +963,7 @@ func TestUpdate(t *testing.T) { SetupInput: func() (*Request, error) { req := httptest.NewRequest( http.MethodPut, "/api/v1/feed/10?community=10", - bytes.NewBuffer([]byte(`{"id":1}`)), + bytes.NewBuffer([]byte(`{"id":1, "post_content":{"text":"text"}}`)), ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) @@ -2210,7 +2276,9 @@ func TestComment(t *testing.T) { { name: "4", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed/2", bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed/2", bytes.NewBuffer([]byte(`{"id":1, "text":"text"}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "2"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -2241,7 +2309,9 @@ func TestComment(t *testing.T) { { name: "5", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/feed/2", bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/feed/2", bytes.NewBuffer([]byte(`{"id":1, "text":"text"}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "2"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) From 50ed5d397b6fb11a1034f829a321842c832a3863 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sat, 14 Dec 2024 18:07:58 +0300 Subject: [PATCH 087/135] add validation for community --- internal/community/controller/controller.go | 11 + .../community/controller/controller_test.go | 1196 ++++++++++------- pkg/my_err/error.go | 6 +- 3 files changed, 700 insertions(+), 513 deletions(-) diff --git a/internal/community/controller/controller.go b/internal/community/controller/controller.go index 82e178cb..2bfa9cfa 100644 --- a/internal/community/controller/controller.go +++ b/internal/community/controller/controller.go @@ -363,6 +363,9 @@ func (c *Controller) getCommunityFromBody(r *http.Request) (models.Community, er if err != nil { return models.Community{}, err } + if !validate(res) { + return models.Community{}, my_err.ErrBadCommunity + } return res, nil } @@ -382,3 +385,11 @@ func getIDFromQuery(r *http.Request) (uint32, error) { return uint32(uid), nil } + +func validate(data models.Community) bool { + if len(data.Name) < 3 || len(data.Name) >= 30 || len(data.About) >= 60 { + return false + } + + return true +} diff --git a/internal/community/controller/controller_test.go b/internal/community/controller/controller_test.go index 87195a24..bfde7f58 100644 --- a/internal/community/controller/controller_test.go +++ b/internal/community/controller/controller_test.go @@ -58,12 +58,14 @@ func TestGetOne(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -87,13 +89,17 @@ func TestGetOne(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.communityService.EXPECT().GetOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.communityService.EXPECT().GetOne(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -117,12 +123,14 @@ func TestGetOne(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -147,12 +155,14 @@ func TestGetOne(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().GetOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -175,42 +185,46 @@ func TestGetOne(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -235,12 +249,14 @@ func TestGetAll(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -263,13 +279,17 @@ func TestGetAll(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.communityService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.communityService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -293,9 +313,11 @@ func TestGetAll(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do(func(w, req any) { - request.w.WriteHeader(http.StatusNoContent) - }) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) }, }, { @@ -320,13 +342,16 @@ func TestGetAll(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return( []*models.CommunityCard{{ID: 1}}, - nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + nil, + ) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -348,42 +373,46 @@ func TestGetAll(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -408,12 +437,14 @@ func TestUpdate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -436,12 +467,14 @@ func TestUpdate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -465,18 +498,22 @@ func TestUpdate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "4", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/community/1", bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/community/1", bytes.NewBuffer([]byte(`{"id":1, "name":"name"}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "1"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -495,18 +532,22 @@ func TestUpdate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().CheckAccess(gomock.Any(), gomock.Any(), gomock.Any()).Return(false) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "5", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/community/1", bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/community/1", bytes.NewBuffer([]byte(`{"id":1, "name":"name"}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "1"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -526,18 +567,22 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().CheckAccess(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.communityService.EXPECT().Update(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "6", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/community/1", bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/community/1", bytes.NewBuffer([]byte(`{"id":1, "name":"name"}`)), + ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "1"}) req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -557,42 +602,79 @@ func TestUpdate(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().CheckAccess(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.communityService.EXPECT().Update(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "7", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodPut, "/api/v1/community/1", bytes.NewBuffer([]byte(`{"id":1, "name":"a"}`)), + ) + w := httptest.NewRecorder() + req = mux.SetURLVars(req, map[string]string{"id": "1"}) + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func(ctx context.Context, implementation *Controller, request Request) (Response, error) { + implementation.Update(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -617,12 +699,14 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -645,12 +729,14 @@ func TestDelete(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -675,12 +761,14 @@ func TestDelete(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().CheckAccess(gomock.Any(), gomock.Any(), gomock.Any()).Return(false) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -706,12 +794,14 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().CheckAccess(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.communityService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -737,42 +827,46 @@ func TestDelete(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().CheckAccess(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.communityService.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -797,12 +891,14 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -825,18 +921,22 @@ func TestCreate(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "3", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/community/1", bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/community/1", bytes.NewBuffer([]byte(`{"id":1, "name":"name"}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -854,18 +954,22 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "4", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/community/1", bytes.NewBuffer([]byte(`{"id":1}`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/community/1", bytes.NewBuffer([]byte(`{"id":1, "name":"name"}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} @@ -883,42 +987,46 @@ func TestCreate(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -943,12 +1051,14 @@ func TestJoinToCommunity(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -971,12 +1081,14 @@ func TestJoinToCommunity(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1000,13 +1112,17 @@ func TestJoinToCommunity(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.communityService.EXPECT().JoinCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.communityService.EXPECT().JoinCommunity( + gomock.Any(), gomock.Any(), gomock.Any(), + ).Return(errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1031,42 +1147,46 @@ func TestJoinToCommunity(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().JoinCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1091,12 +1211,14 @@ func TestLeaveFromCommunity(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1119,12 +1241,14 @@ func TestLeaveFromCommunity(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1148,13 +1272,17 @@ func TestLeaveFromCommunity(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.communityService.EXPECT().LeaveCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.communityService.EXPECT().LeaveCommunity( + gomock.Any(), gomock.Any(), gomock.Any(), + ).Return(errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1179,42 +1307,46 @@ func TestLeaveFromCommunity(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().LeaveCommunity(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1239,12 +1371,14 @@ func TestAddAdmin(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1267,12 +1401,14 @@ func TestAddAdmin(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1297,18 +1433,22 @@ func TestAddAdmin(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().CheckAccess(gomock.Any(), gomock.Any(), gomock.Any()).Return(false) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "4", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/community/1/add_admin", bytes.NewBuffer([]byte(`{kj`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/community/1/add_admin", bytes.NewBuffer([]byte(`{kj`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) req = mux.SetURLVars(req, map[string]string{"id": "1"}) @@ -1328,18 +1468,22 @@ func TestAddAdmin(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().CheckAccess(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "5", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/community/1/add_admin", bytes.NewBuffer([]byte(`1`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/community/1/add_admin", bytes.NewBuffer([]byte(`1`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) req = mux.SetURLVars(req, map[string]string{"id": "1"}) @@ -1358,19 +1502,25 @@ func TestAddAdmin(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().CheckAccess(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) - m.communityService.EXPECT().AddAdmin(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.communityService.EXPECT().AddAdmin( + gomock.Any(), gomock.Any(), gomock.Any(), + ).Return(errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "6", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/community/1/add_admin", bytes.NewBuffer([]byte(`1`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/community/1/add_admin", bytes.NewBuffer([]byte(`1`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) req = mux.SetURLVars(req, map[string]string{"id": "1"}) @@ -1390,18 +1540,22 @@ func TestAddAdmin(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().CheckAccess(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) m.communityService.EXPECT().AddAdmin(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "7", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPost, "/api/v1/community/1/add_admin", bytes.NewBuffer([]byte(`1`))) + req := httptest.NewRequest( + http.MethodPost, "/api/v1/community/1/add_admin", bytes.NewBuffer([]byte(`1`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) req = mux.SetURLVars(req, map[string]string{"id": "1"}) @@ -1420,43 +1574,49 @@ func TestAddAdmin(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.communityService.EXPECT().CheckAccess(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) - m.communityService.EXPECT().AddAdmin(gomock.Any(), gomock.Any(), gomock.Any()).Return(my_err.ErrWrongCommunity) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.communityService.EXPECT().AddAdmin( + gomock.Any(), gomock.Any(), gomock.Any(), + ).Return(my_err.ErrWrongCommunity) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1481,12 +1641,14 @@ func TestSearch(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1509,13 +1671,17 @@ func TestSearch(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.communityService.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.communityService.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1538,13 +1704,17 @@ func TestSearch(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.communityService.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.communityService.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, nil, + ) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1567,12 +1737,14 @@ func TestSearch(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1594,41 +1766,45 @@ func TestSearch(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } diff --git a/pkg/my_err/error.go b/pkg/my_err/error.go index 2f6ffb76..fe32420d 100644 --- a/pkg/my_err/error.go +++ b/pkg/my_err/error.go @@ -37,7 +37,7 @@ var ( ErrWrongComment = errors.New("wrong comment") ErrStickerHasAnotherContent = errors.New("sticker has another content") ErrToMuchFiles = errors.New("files more then 10") - ErrNoStickers = errors.New("no stickers found") - ErrNoImage = errors.New("file is no image") - + ErrNoStickers = errors.New("no stickers found") + ErrNoImage = errors.New("file is no image") + ErrBadCommunity = errors.New("bad community data") ) From 9f93551adb97858e9bc997ac07c1fa94d0ab0ad5 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sat, 14 Dec 2024 18:15:19 +0300 Subject: [PATCH 088/135] add validation for chat --- internal/chat/controller/controller.go | 22 +++++--- pkg/my_err/error.go | 69 +++++++++++++------------- 2 files changed, 50 insertions(+), 41 deletions(-) diff --git a/internal/chat/controller/controller.go b/internal/chat/controller/controller.go index fc5ff8fe..23a8bee0 100644 --- a/internal/chat/controller/controller.go +++ b/internal/chat/controller/controller.go @@ -90,17 +90,27 @@ func (cc *ChatController) SetConnection(w http.ResponseWriter, r *http.Request) cc.SendChatMsg(ctx, reqID, w) } +func validate(content models.MessageContent) bool { + if len(content.FilePath) > 10 { + return false + } + if content.StickerPath != "" && (len(content.FilePath) > 0 || content.Text != "") { + return false + } + if content.Text == "" && content.StickerPath == "" && len(content.FilePath) == 0 { + return false + } + + return true +} + func (cc *ChatController) SendChatMsg(ctx context.Context, reqID string, w http.ResponseWriter) { for msg := range cc.Messages { - if len(msg.Content.FilePath) > 10 { - cc.responder.ErrorBadRequest(w, my_err.ErrToMuchFiles, reqID) + if !validate(msg.Content) { + cc.responder.ErrorBadRequest(w, my_err.ErrBadMessageContent, reqID) return } msg := msg.ToDto() - if msg.Content.StickerPath != "" && (msg.Content.FilePath != "" || msg.Content.Text != "") { - cc.responder.ErrorBadRequest(w, my_err.ErrStickerHasAnotherContent, reqID) - return - } err := cc.chatService.SendNewMessage(ctx, msg.Receiver, msg.Sender, &msg.Content) if err != nil { cc.responder.ErrorInternal(w, err, reqID) diff --git a/pkg/my_err/error.go b/pkg/my_err/error.go index fe32420d..2629485a 100644 --- a/pkg/my_err/error.go +++ b/pkg/my_err/error.go @@ -5,39 +5,38 @@ import ( ) var ( - ErrUserNotFound = errors.New("user not found") - ErrUserAlreadyExists = errors.New("user already exists") - ErrNoAuth = errors.New("no auth") - ErrWrongEmailOrPassword = errors.New("wrong email or password") - ErrNonValidEmail = errors.New("invalid email") - ErrSessionNotFound = errors.New("session not found") - ErrSessionAlreadyExists = errors.New("session already exists") - ErrToLargeFile = errors.New("file too large") - ErrNoMoreContent = errors.New("no more content") - ErrWrongFiletype = errors.New("wrong type of file") - ErrPostNotFound = errors.New("post not found") - ErrAccessDenied = errors.New("access denied") - ErrInternal = errors.New("internal error") - ErrWrongOwner = errors.New("wrong owner") - ErrSameUser = errors.New("same user") - ErrEmptyId = errors.New("empty id") - ErrBigId = errors.New("id is too big") - ErrProfileNotFound = errors.New("profile not found") - ErrAnotherService = errors.New("another service") - ErrInvalidQuery = errors.New("invalid query parameter") - ErrInvalidContext = errors.New("invalid context parameter") - ErrWrongDateFormat = errors.New("wrong date format") - ErrWrongFile = errors.New("wrong file name") - ErrNoFile = errors.New("file not found") - ErrResNotOK = errors.New("res not OK") - ErrLikeAlreadyExists = errors.New("like already exists") - ErrWrongCommunity = errors.New("wrong community") - ErrWrongPost = errors.New("wrong post") - ErrBadPostOrComment = errors.New("content is bad") - ErrWrongComment = errors.New("wrong comment") - ErrStickerHasAnotherContent = errors.New("sticker has another content") - ErrToMuchFiles = errors.New("files more then 10") - ErrNoStickers = errors.New("no stickers found") - ErrNoImage = errors.New("file is no image") - ErrBadCommunity = errors.New("bad community data") + ErrUserNotFound = errors.New("user not found") + ErrUserAlreadyExists = errors.New("user already exists") + ErrNoAuth = errors.New("no auth") + ErrWrongEmailOrPassword = errors.New("wrong email or password") + ErrNonValidEmail = errors.New("invalid email") + ErrSessionNotFound = errors.New("session not found") + ErrSessionAlreadyExists = errors.New("session already exists") + ErrToLargeFile = errors.New("file too large") + ErrNoMoreContent = errors.New("no more content") + ErrWrongFiletype = errors.New("wrong type of file") + ErrPostNotFound = errors.New("post not found") + ErrAccessDenied = errors.New("access denied") + ErrInternal = errors.New("internal error") + ErrWrongOwner = errors.New("wrong owner") + ErrSameUser = errors.New("same user") + ErrEmptyId = errors.New("empty id") + ErrBigId = errors.New("id is too big") + ErrProfileNotFound = errors.New("profile not found") + ErrAnotherService = errors.New("another service") + ErrInvalidQuery = errors.New("invalid query parameter") + ErrInvalidContext = errors.New("invalid context parameter") + ErrWrongDateFormat = errors.New("wrong date format") + ErrWrongFile = errors.New("wrong file name") + ErrNoFile = errors.New("file not found") + ErrResNotOK = errors.New("res not OK") + ErrLikeAlreadyExists = errors.New("like already exists") + ErrWrongCommunity = errors.New("wrong community") + ErrWrongPost = errors.New("wrong post") + ErrBadPostOrComment = errors.New("content is bad") + ErrWrongComment = errors.New("wrong comment") + ErrBadMessageContent = errors.New("bad message content") + ErrNoStickers = errors.New("no stickers found") + ErrNoImage = errors.New("file is no image") + ErrBadCommunity = errors.New("bad community data") ) From 7f349817966945eeac5086e3acad0cdd2fa15830 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sat, 14 Dec 2024 18:28:16 +0300 Subject: [PATCH 089/135] add validation to auth --- internal/auth/controller/controller.go | 19 +++++++++++++ internal/auth/controller/controller_test.go | 30 +++++++++++++++------ pkg/my_err/error.go | 1 + 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/internal/auth/controller/controller.go b/internal/auth/controller/controller.go index 60eceb25..98d1560c 100644 --- a/internal/auth/controller/controller.go +++ b/internal/auth/controller/controller.go @@ -58,6 +58,10 @@ func (c *AuthController) Register(w http.ResponseWriter, r *http.Request) { c.responder.ErrorBadRequest(w, fmt.Errorf("router register: %w", err), reqID) return } + if !validate(user) { + c.responder.ErrorBadRequest(w, my_err.ErrBadUserInfo, reqID) + return + } user.ID, err = c.serviceAuth.Register(user, r.Context()) if errors.Is(err, my_err.ErrUserAlreadyExists) || errors.Is(err, my_err.ErrNonValidEmail) || errors.Is( @@ -83,6 +87,7 @@ func (c *AuthController) Register(w http.ResponseWriter, r *http.Request) { Value: sess.ID, Path: "/", HttpOnly: true, + Secure: true, Expires: time.Now().AddDate(0, 0, 1), } @@ -103,6 +108,10 @@ func (c *AuthController) Auth(w http.ResponseWriter, r *http.Request) { c.responder.ErrorBadRequest(w, fmt.Errorf("router auth: %w", err), reqID) return } + if !validate(user) { + c.responder.ErrorBadRequest(w, my_err.ErrBadUserInfo, reqID) + return + } id, err := c.serviceAuth.Auth(user, r.Context()) @@ -126,6 +135,7 @@ func (c *AuthController) Auth(w http.ResponseWriter, r *http.Request) { Value: sess.ID, Path: "/", HttpOnly: true, + Secure: true, Expires: time.Now().AddDate(0, 0, 1), } http.SetCookie(w, cookie) @@ -162,9 +172,18 @@ func (c *AuthController) Logout(w http.ResponseWriter, r *http.Request) { Value: sess.ID, Path: "/", HttpOnly: true, + Secure: true, Expires: time.Now().AddDate(0, 0, -1), } http.SetCookie(w, cookie) c.responder.OutputJSON(w, "user logout", reqID) } + +func validate(user models.User) bool { + if len(user.FirstName) < 3 || len(user.LastName) < 3 || len(user.Password) < 6 || + len(user.FirstName) > 30 || len(user.LastName) > 30 { + return false + } + return true +} diff --git a/internal/auth/controller/controller_test.go b/internal/auth/controller/controller_test.go index 200c50b6..1a98425d 100644 --- a/internal/auth/controller/controller_test.go +++ b/internal/auth/controller/controller_test.go @@ -110,12 +110,19 @@ type TestCase struct { func TestRegister(t *testing.T) { controller := NewAuthController(&MockResponder{}, MockAuthService{}, MockSessionManager{}) - jsonUser0, _ := json.Marshal(models.User{ID: 0}) - jsonUser1, _ := json.Marshal(models.User{ID: 1}) - jsonUser2, _ := json.Marshal(models.User{ID: 2}) - jsonUser3, _ := json.Marshal(models.User{ID: 3}) + jsonUser0, _ := json.Marshal(models.User{ID: 0, FirstName: "Alex", LastName: "Zem", Password: "password"}) + jsonUser1, _ := json.Marshal(models.User{ID: 1, FirstName: "Alex", LastName: "Zem", Password: "password"}) + jsonUser2, _ := json.Marshal(models.User{ID: 2, FirstName: "Alex", LastName: "Zem", Password: "password"}) + jsonUser3, _ := json.Marshal(models.User{ID: 3, FirstName: "Alex", LastName: "Zem", Password: "password"}) + jsonUser, _ := json.Marshal(models.User{ID: 3}) testCases := []TestCase{ + { + w: httptest.NewRecorder(), + r: httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer(jsonUser)), + wantCode: http.StatusBadRequest, + wantBody: "bad request error", + }, { w: httptest.NewRecorder(), r: httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer([]byte("wrong json"))), @@ -161,12 +168,19 @@ func TestRegister(t *testing.T) { func TestAuth(t *testing.T) { controller := NewAuthController(&MockResponder{}, MockAuthService{}, MockSessionManager{}) - jsonUser0, _ := json.Marshal(models.User{ID: 0}) - jsonUser1, _ := json.Marshal(models.User{ID: 1}) - jsonUser2, _ := json.Marshal(models.User{ID: 2}) - jsonUser3, _ := json.Marshal(models.User{ID: 3}) + jsonUser0, _ := json.Marshal(models.User{ID: 0, FirstName: "Alex", LastName: "Zem", Password: "password"}) + jsonUser1, _ := json.Marshal(models.User{ID: 1, FirstName: "Alex", LastName: "Zem", Password: "password"}) + jsonUser2, _ := json.Marshal(models.User{ID: 2, FirstName: "Alex", LastName: "Zem", Password: "password"}) + jsonUser3, _ := json.Marshal(models.User{ID: 3, FirstName: "Alex", LastName: "Zem", Password: "password"}) + jsonUser, _ := json.Marshal(models.User{ID: 3}) testCases := []TestCase{ + { + w: httptest.NewRecorder(), + r: httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer(jsonUser)), + wantCode: http.StatusBadRequest, + wantBody: "bad request error", + }, { w: httptest.NewRecorder(), r: httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer([]byte("wrong json"))), diff --git a/pkg/my_err/error.go b/pkg/my_err/error.go index 2629485a..ab339a95 100644 --- a/pkg/my_err/error.go +++ b/pkg/my_err/error.go @@ -39,4 +39,5 @@ var ( ErrNoStickers = errors.New("no stickers found") ErrNoImage = errors.New("file is no image") ErrBadCommunity = errors.New("bad community data") + ErrBadUserInfo = errors.New("bad username or password") ) From 9857b4db5341a8ab9eb5e05923189809b6caf310 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sat, 14 Dec 2024 18:29:08 +0300 Subject: [PATCH 090/135] cookie is secure now --- internal/middleware/auth.go | 78 +++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/internal/middleware/auth.go b/internal/middleware/auth.go index 8e07a7a3..c3a2b060 100644 --- a/internal/middleware/auth.go +++ b/internal/middleware/auth.go @@ -21,52 +21,55 @@ type SessionManager interface { } func Auth(sm SessionManager, next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if _, ok := noAuthUrls[r.URL.Path]; ok { - logout(w, r, sm) - next.ServeHTTP(w, r) - return - } - - sessionCookie, err := r.Cookie("session_id") - if err != nil { - unauthorized(w, r, err) - return - } - - sess, err := sm.Check(sessionCookie.Value) - if err != nil { - unauthorized(w, r, err) - return - } - - if sess.CreatedAt <= time.Now().Add(-time.Hour).Unix() { - if err := sm.Destroy(sess); err != nil { - log.Println(r.Context().Value("requestID"), err) - internalErr(w) + return http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + if _, ok := noAuthUrls[r.URL.Path]; ok { + logout(w, r, sm) + next.ServeHTTP(w, r) return } - sess, err = sm.Create(sess.UserID) + sessionCookie, err := r.Cookie("session_id") if err != nil { - log.Println(r.Context().Value("requestID"), err) - internalErr(w) + unauthorized(w, r, err) return } - cookie := &http.Cookie{ - Name: "session_id", - Value: sess.ID, - Path: "/", - HttpOnly: true, - Expires: time.Now().AddDate(0, 0, 1), + sess, err := sm.Check(sessionCookie.Value) + if err != nil { + unauthorized(w, r, err) + return + } + + if sess.CreatedAt <= time.Now().Add(-time.Hour).Unix() { + if err := sm.Destroy(sess); err != nil { + log.Println(r.Context().Value("requestID"), err) + internalErr(w) + return + } + + sess, err = sm.Create(sess.UserID) + if err != nil { + log.Println(r.Context().Value("requestID"), err) + internalErr(w) + return + } + + cookie := &http.Cookie{ + Name: "session_id", + Value: sess.ID, + Path: "/", + HttpOnly: true, + Secure: true, + Expires: time.Now().AddDate(0, 0, 1), + } + http.SetCookie(w, cookie) } - http.SetCookie(w, cookie) - } - ctx := models.ContextWithSession(r.Context(), sess) - next.ServeHTTP(w, r.WithContext(ctx)) - }) + ctx := models.ContextWithSession(r.Context(), sess) + next.ServeHTTP(w, r.WithContext(ctx)) + }, + ) } func logout(w http.ResponseWriter, r *http.Request, sm SessionManager) { @@ -90,6 +93,7 @@ func logout(w http.ResponseWriter, r *http.Request, sm SessionManager) { Value: sess.ID, Path: "/", HttpOnly: true, + Secure: true, Expires: time.Now().AddDate(0, 0, -1), } From eae12670f667870a461f8f2ec03fccfade87b522 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sat, 14 Dec 2024 18:30:53 +0300 Subject: [PATCH 091/135] validate text in message --- internal/chat/controller/controller.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/chat/controller/controller.go b/internal/chat/controller/controller.go index 23a8bee0..569c3d54 100644 --- a/internal/chat/controller/controller.go +++ b/internal/chat/controller/controller.go @@ -91,7 +91,7 @@ func (cc *ChatController) SetConnection(w http.ResponseWriter, r *http.Request) } func validate(content models.MessageContent) bool { - if len(content.FilePath) > 10 { + if len(content.FilePath) > 10 || len(content.StickerPath) > 100 || len(content.Text) > 500 { return false } if content.StickerPath != "" && (len(content.FilePath) > 0 || content.Text != "") { From 863bb61ce0c748f6bc52b0fbf92d2c9956951848 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sat, 14 Dec 2024 18:48:39 +0300 Subject: [PATCH 092/135] add validation for profile --- internal/profile/controller/controller.go | 18 + .../profile/controller/controller_test.go | 2358 +++++++++++------ 2 files changed, 1522 insertions(+), 854 deletions(-) diff --git a/internal/profile/controller/controller.go b/internal/profile/controller/controller.go index d731d941..54f16efb 100644 --- a/internal/profile/controller/controller.go +++ b/internal/profile/controller/controller.go @@ -129,6 +129,12 @@ func (h *ProfileHandlerImplementation) getNewProfile(r *http.Request) (*models.F return nil, err } + if len(newProfile.FirstName) < 3 || len(newProfile.FirstName) > 30 || + len(newProfile.LastName) < 3 || len(newProfile.LastName) > 30 || + len(newProfile.Bio) > 60 || len(newProfile.Avatar) > 100 { + return nil, errors.New("invalid profile") + } + return &newProfile, nil } @@ -545,6 +551,10 @@ func (h *ProfileHandlerImplementation) ChangePassword(w http.ResponseWriter, r * h.Responder.ErrorBadRequest(w, err, reqID) return } + if !validate(request) { + h.Responder.ErrorBadRequest(w, errors.New("too small password or old and new same"), reqID) + return + } if err = h.ProfileManager.ChangePassword( r.Context(), sess.UserID, request.OldPassword, request.NewPassword, @@ -562,3 +572,11 @@ func (h *ProfileHandlerImplementation) ChangePassword(w http.ResponseWriter, r * h.Responder.OutputJSON(w, "password change", reqID) } + +func validate(request models.ChangePasswordReq) bool { + if len(request.OldPassword) < 6 || len(request.NewPassword) < 6 || request.OldPassword == request.NewPassword { + return false + } + + return true +} diff --git a/internal/profile/controller/controller_test.go b/internal/profile/controller/controller_test.go index 3c296984..a2b94f21 100644 --- a/internal/profile/controller/controller_test.go +++ b/internal/profile/controller/controller_test.go @@ -47,7 +47,9 @@ func TestGetHeader(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetHeader(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -58,12 +60,14 @@ func TestGetHeader(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -75,7 +79,9 @@ func TestGetHeader(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetHeader(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -87,12 +93,14 @@ func TestGetHeader(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(nil, my_err.ErrProfileNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -104,7 +112,9 @@ func TestGetHeader(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetHeader(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -116,12 +126,14 @@ func TestGetHeader(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("internal error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("internal error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -133,7 +145,9 @@ func TestGetHeader(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetHeader(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -145,42 +159,46 @@ func TestGetHeader(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetHeader(gomock.Any(), gomock.Any()).Return(&models.Header{}, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, header, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, header, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -194,7 +212,9 @@ func TestGetProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -205,12 +225,14 @@ func TestGetProfile(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -222,7 +244,9 @@ func TestGetProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -233,13 +257,17 @@ func TestGetProfile(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, my_err.ErrProfileNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return( + &models.FullProfile{}, my_err.ErrProfileNotFound, + ) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -251,7 +279,9 @@ func TestGetProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -262,10 +292,14 @@ func TestGetProfile(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, my_err.ErrNoMoreContent) - m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do(func(w, req any) { - request.w.WriteHeader(http.StatusNoContent) - }) + m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return( + &models.FullProfile{}, my_err.ErrNoMoreContent, + ) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) }, }, { @@ -277,7 +311,9 @@ func TestGetProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -288,13 +324,17 @@ func TestGetProfile(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return( + &models.FullProfile{}, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -306,7 +346,9 @@ func TestGetProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -318,42 +360,46 @@ func TestGetProfile(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -367,7 +413,9 @@ func TestUpdateProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.UpdateProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -378,12 +426,14 @@ func TestUpdateProfile(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -395,7 +445,9 @@ func TestUpdateProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.UpdateProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -406,25 +458,31 @@ func TestUpdateProfile(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "3", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/profile", - bytes.NewBuffer([]byte(`{"id":0, "first_name":"Alexey"}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/profile", + bytes.NewBuffer([]byte(`{"id":0, "first_name":"Alexey", "last_name":"Zemliakov"}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.UpdateProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -436,25 +494,31 @@ func TestUpdateProfile(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().UpdateProfile(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { name: "4", SetupInput: func() (*Request, error) { - req := httptest.NewRequest(http.MethodPut, "/api/v1/profile", - bytes.NewBuffer([]byte(`{"id":1, "first_name":"Alexey"}`))) + req := httptest.NewRequest( + http.MethodPut, "/api/v1/profile", + bytes.NewBuffer([]byte(`{"id":1, "first_name":"Alexey", "last_name":"Zemliakov"}`)), + ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.UpdateProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -466,42 +530,79 @@ func TestUpdateProfile(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().UpdateProfile(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "5", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodPut, "/api/v1/profile", + bytes.NewBuffer([]byte(`{"id":0, "first_name":"Alexey", "last_name":""}`)), + ) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { + implementation.UpdateProfile(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + _, _ = request.w.Write([]byte("bad request")) + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -515,7 +616,9 @@ func TestDeleteProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.DeleteProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -526,12 +629,14 @@ func TestDeleteProfile(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -543,7 +648,9 @@ func TestDeleteProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.DeleteProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -555,12 +662,14 @@ func TestDeleteProfile(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().DeleteProfile(gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -572,7 +681,9 @@ func TestDeleteProfile(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.DeleteProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -584,42 +695,46 @@ func TestDeleteProfile(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().DeleteProfile(gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -633,7 +748,9 @@ func TestGetProfileByID(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfileById(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -644,12 +761,14 @@ func TestGetProfileByID(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -661,7 +780,9 @@ func TestGetProfileByID(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfileById(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -672,12 +793,14 @@ func TestGetProfileByID(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -689,7 +812,9 @@ func TestGetProfileByID(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfileById(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -700,12 +825,14 @@ func TestGetProfileByID(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -717,7 +844,9 @@ func TestGetProfileByID(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfileById(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -728,13 +857,17 @@ func TestGetProfileByID(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, my_err.ErrProfileNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return( + &models.FullProfile{}, my_err.ErrProfileNotFound, + ) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -746,7 +879,9 @@ func TestGetProfileByID(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfileById(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -757,13 +892,17 @@ func TestGetProfileByID(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return( + &models.FullProfile{}, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -775,7 +914,9 @@ func TestGetProfileByID(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetProfileById(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -787,42 +928,46 @@ func TestGetProfileByID(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetProfileById(gomock.Any(), gomock.Any()).Return(&models.FullProfile{}, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -836,7 +981,9 @@ func TestGetAll(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAll(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -847,12 +994,14 @@ func TestGetAll(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -864,7 +1013,9 @@ func TestGetAll(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAll(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -875,12 +1026,14 @@ func TestGetAll(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -892,7 +1045,9 @@ func TestGetAll(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAll(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -903,13 +1058,17 @@ func TestGetAll(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetAll(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.profileManager.EXPECT().GetAll(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -921,7 +1080,9 @@ func TestGetAll(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAll(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -933,9 +1094,11 @@ func TestGetAll(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetAll(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do(func(w, req any) { - request.w.WriteHeader(http.StatusNoContent) - }) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) }, }, { @@ -947,7 +1110,9 @@ func TestGetAll(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAll(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -960,43 +1125,48 @@ func TestGetAll(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetAll(gomock.Any(), gomock.Any(), gomock.Any()).Return( []*models.ShortProfile{{ID: 1}}, - nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + nil, + ) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1010,7 +1180,9 @@ func TestSendFriendReq(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SendFriendReq(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1021,12 +1193,14 @@ func TestSendFriendReq(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1038,7 +1212,9 @@ func TestSendFriendReq(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SendFriendReq(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1049,12 +1225,14 @@ func TestSendFriendReq(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1067,7 +1245,9 @@ func TestSendFriendReq(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SendFriendReq(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1079,12 +1259,14 @@ func TestSendFriendReq(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().SendFriendReq(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1097,7 +1279,9 @@ func TestSendFriendReq(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SendFriendReq(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1109,42 +1293,46 @@ func TestSendFriendReq(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().SendFriendReq(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1158,7 +1346,9 @@ func TestAcceptFriendReq(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.AcceptFriendReq(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1169,12 +1359,14 @@ func TestAcceptFriendReq(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1186,7 +1378,9 @@ func TestAcceptFriendReq(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.AcceptFriendReq(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1197,12 +1391,14 @@ func TestAcceptFriendReq(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1215,7 +1411,9 @@ func TestAcceptFriendReq(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.AcceptFriendReq(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1227,12 +1425,14 @@ func TestAcceptFriendReq(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().AcceptFriendReq(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1245,7 +1445,9 @@ func TestAcceptFriendReq(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.AcceptFriendReq(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1257,42 +1459,46 @@ func TestAcceptFriendReq(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().AcceptFriendReq(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1306,7 +1512,9 @@ func TestRemoveFromFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.RemoveFromFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1317,12 +1525,14 @@ func TestRemoveFromFriends(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1334,7 +1544,9 @@ func TestRemoveFromFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.RemoveFromFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1345,12 +1557,14 @@ func TestRemoveFromFriends(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1363,7 +1577,9 @@ func TestRemoveFromFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.RemoveFromFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1375,12 +1591,14 @@ func TestRemoveFromFriends(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().RemoveFromFriends(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1393,7 +1611,9 @@ func TestRemoveFromFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.RemoveFromFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1405,42 +1625,46 @@ func TestRemoveFromFriends(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().RemoveFromFriends(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1454,7 +1678,9 @@ func TestUnsubscribe(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.Unsubscribe(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1465,12 +1691,14 @@ func TestUnsubscribe(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1482,7 +1710,9 @@ func TestUnsubscribe(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.Unsubscribe(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1493,12 +1723,14 @@ func TestUnsubscribe(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1511,7 +1743,9 @@ func TestUnsubscribe(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.Unsubscribe(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1523,12 +1757,14 @@ func TestUnsubscribe(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().Unsubscribe(gomock.Any(), gomock.Any()).Return(errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1541,7 +1777,9 @@ func TestUnsubscribe(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.Unsubscribe(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1553,42 +1791,46 @@ func TestUnsubscribe(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().Unsubscribe(gomock.Any(), gomock.Any()).Return(nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1602,7 +1844,9 @@ func TestGetAllFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1613,12 +1857,14 @@ func TestGetAllFriends(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1630,7 +1876,9 @@ func TestGetAllFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1641,12 +1889,14 @@ func TestGetAllFriends(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1658,7 +1908,9 @@ func TestGetAllFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1669,13 +1921,17 @@ func TestGetAllFriends(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetAllFriends(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.profileManager.EXPECT().GetAllFriends(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1687,7 +1943,9 @@ func TestGetAllFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1699,9 +1957,11 @@ func TestGetAllFriends(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetAllFriends(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do(func(w, req any) { - request.w.WriteHeader(http.StatusNoContent) - }) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) }, }, { @@ -1713,7 +1973,9 @@ func TestGetAllFriends(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllFriends(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1726,43 +1988,48 @@ func TestGetAllFriends(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetAllFriends(gomock.Any(), gomock.Any(), gomock.Any()).Return( []*models.ShortProfile{{ID: 1}}, - nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + nil, + ) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1776,7 +2043,9 @@ func TestGetAllSubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1787,12 +2056,14 @@ func TestGetAllSubs(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1804,7 +2075,9 @@ func TestGetAllSubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1815,12 +2088,14 @@ func TestGetAllSubs(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1832,7 +2107,9 @@ func TestGetAllSubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1843,13 +2120,17 @@ func TestGetAllSubs(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetAllSubs(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.profileManager.EXPECT().GetAllSubs(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1861,7 +2142,9 @@ func TestGetAllSubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1873,9 +2156,11 @@ func TestGetAllSubs(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetAllSubs(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do(func(w, req any) { - request.w.WriteHeader(http.StatusNoContent) - }) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) }, }, { @@ -1887,7 +2172,9 @@ func TestGetAllSubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1900,43 +2187,48 @@ func TestGetAllSubs(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetAllSubs(gomock.Any(), gomock.Any(), gomock.Any()).Return( []*models.ShortProfile{{ID: 1}}, - nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + nil, + ) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -1950,7 +2242,9 @@ func TestGetAllSubscriptions(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubscriptions(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1961,12 +2255,14 @@ func TestGetAllSubscriptions(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -1978,7 +2274,9 @@ func TestGetAllSubscriptions(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubscriptions(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -1989,12 +2287,14 @@ func TestGetAllSubscriptions(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -2006,7 +2306,9 @@ func TestGetAllSubscriptions(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubscriptions(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2017,13 +2319,17 @@ func TestGetAllSubscriptions(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetAllSubscriptions(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.profileManager.EXPECT().GetAllSubscriptions(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -2035,7 +2341,9 @@ func TestGetAllSubscriptions(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubscriptions(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2047,9 +2355,11 @@ func TestGetAllSubscriptions(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetAllSubscriptions(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do(func(w, req any) { - request.w.WriteHeader(http.StatusNoContent) - }) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) }, }, { @@ -2061,7 +2371,9 @@ func TestGetAllSubscriptions(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetAllSubscriptions(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2074,43 +2386,48 @@ func TestGetAllSubscriptions(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetAllSubscriptions(gomock.Any(), gomock.Any(), gomock.Any()).Return( []*models.ShortProfile{{ID: 1}}, - nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + nil, + ) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -2124,7 +2441,9 @@ func TestGetCommunitySubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetCommunitySubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2135,12 +2454,14 @@ func TestGetCommunitySubs(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -2152,7 +2473,9 @@ func TestGetCommunitySubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetCommunitySubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2163,12 +2486,14 @@ func TestGetCommunitySubs(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -2180,7 +2505,9 @@ func TestGetCommunitySubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetCommunitySubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2191,13 +2518,17 @@ func TestGetCommunitySubs(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().GetCommunitySubs(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.profileManager.EXPECT().GetCommunitySubs(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -2209,7 +2540,9 @@ func TestGetCommunitySubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetCommunitySubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2221,9 +2554,11 @@ func TestGetCommunitySubs(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetCommunitySubs(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do(func(w, req any) { - request.w.WriteHeader(http.StatusNoContent) - }) + m.responder.EXPECT().OutputNoMoreContentJSON(request.w, gomock.Any()).Do( + func(w, req any) { + request.w.WriteHeader(http.StatusNoContent) + }, + ) }, }, { @@ -2235,7 +2570,9 @@ func TestGetCommunitySubs(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.GetCommunitySubs(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2248,43 +2585,48 @@ func TestGetCommunitySubs(t *testing.T) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().GetCommunitySubs(gomock.Any(), gomock.Any(), gomock.Any()).Return( []*models.ShortProfile{{ID: 1}}, - nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + nil, + ) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } @@ -2298,7 +2640,9 @@ func TestSearch(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SearchProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2309,12 +2653,14 @@ func TestSearch(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -2325,7 +2671,9 @@ func TestSearch(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SearchProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2336,13 +2684,17 @@ func TestSearch(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")) - m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusInternalServerError) - if _, err1 := request.w.Write([]byte("error")); err1 != nil { - panic(err1) - } - }) + m.profileManager.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, errors.New("error"), + ) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -2353,7 +2705,9 @@ func TestSearch(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SearchProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2364,12 +2718,14 @@ func TestSearch(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -2380,7 +2736,9 @@ func TestSearch(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SearchProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2392,12 +2750,14 @@ func TestSearch(t *testing.T) { SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) m.profileManager.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) - m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do(func(w, data, req any) { - request.w.WriteHeader(http.StatusOK) - if _, err1 := request.w.Write([]byte("OK")); err1 != nil { - panic(err1) - } - }) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) }, }, { @@ -2408,7 +2768,9 @@ func TestSearch(t *testing.T) { res := &Request{r: req, w: w} return res, nil }, - Run: func(ctx context.Context, implementation *ProfileHandlerImplementation, request Request) (Response, error) { + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { implementation.SearchProfile(request.w, request.r) res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} return res, nil @@ -2419,43 +2781,331 @@ func TestSearch(t *testing.T) { ExpectedErr: nil, SetupMock: func(request Request, m *mocks) { m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) - m.profileManager.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, my_err.ErrSessionNotFound) - m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do(func(w, err, req any) { - request.w.WriteHeader(http.StatusBadRequest) - if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { - panic(err1) - } - }) + m.profileManager.EXPECT().Search(gomock.Any(), gomock.Any(), gomock.Any()).Return( + nil, my_err.ErrSessionNotFound, + ) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) }, }, } for _, v := range tests { - t.Run(v.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - serv, mock := getController(ctrl) - ctx := context.Background() - - input, err := v.SetupInput() - if err != nil { - t.Error(err) - } - - v.SetupMock(*input, mock) - - res, err := v.ExpectedResult() - if err != nil { - t.Error(err) - } - - actual, err := v.Run(ctx, serv, *input) - assert.Equal(t, res, actual) - if !errors.Is(err, v.ExpectedErr) { - t.Errorf("expect %v, got %v", v.ExpectedErr, err) - } - }) + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) + } +} + +func TestChangePassword(t *testing.T) { + tests := []TableTest[Response, Request]{ + { + name: "1", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest(http.MethodGet, "/api/v1/profile/password", nil) + w := httptest.NewRecorder() + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { + implementation.ChangePassword(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "2", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodGet, "/api/v1/profile/password", + bytes.NewBuffer([]byte("dejfoh")), + ) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { + implementation.ChangePassword(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "3", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodGet, "/api/v1/profile/password", + bytes.NewBuffer([]byte(`{"old_password":"password"}`)), + ) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { + implementation.ChangePassword(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "4", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodGet, "/api/v1/profile/password", + bytes.NewBuffer([]byte(`{"old_password":"password", "new_password":"password"}`)), + ) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { + implementation.ChangePassword(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "5", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodGet, "/api/v1/profile/password", + bytes.NewBuffer([]byte(`{"old_password":"password", "new_password":"password1"}`)), + ) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { + implementation.ChangePassword(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusBadRequest, Body: "bad request"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.profileManager.EXPECT().ChangePassword(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(my_err.ErrUserNotFound) + m.responder.EXPECT().ErrorBadRequest(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusBadRequest) + if _, err1 := request.w.Write([]byte("bad request")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "6", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodGet, "/api/v1/profile/password", + bytes.NewBuffer([]byte(`{"old_password":"password", "new_password":"password1"}`)), + ) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { + implementation.ChangePassword(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusInternalServerError, Body: "error"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.profileManager.EXPECT().ChangePassword(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(errors.New("error")) + m.responder.EXPECT().ErrorInternal(request.w, gomock.Any(), gomock.Any()).Do( + func(w, err, req any) { + request.w.WriteHeader(http.StatusInternalServerError) + if _, err1 := request.w.Write([]byte("error")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + { + name: "7", + SetupInput: func() (*Request, error) { + req := httptest.NewRequest( + http.MethodGet, "/api/v1/profile/password", + bytes.NewBuffer([]byte(`{"old_password":"password", "new_password":"password1"}`)), + ) + w := httptest.NewRecorder() + req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) + res := &Request{r: req, w: w} + return res, nil + }, + Run: func( + ctx context.Context, implementation *ProfileHandlerImplementation, request Request, + ) (Response, error) { + implementation.ChangePassword(request.w, request.r) + res := Response{StatusCode: request.w.Code, Body: request.w.Body.String()} + return res, nil + }, + ExpectedResult: func() (Response, error) { + return Response{StatusCode: http.StatusOK, Body: "OK"}, nil + }, + ExpectedErr: nil, + SetupMock: func(request Request, m *mocks) { + m.responder.EXPECT().LogError(gomock.Any(), gomock.Any()) + m.profileManager.EXPECT().ChangePassword(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + m.responder.EXPECT().OutputJSON(request.w, gomock.Any(), gomock.Any()).Do( + func(w, data, req any) { + request.w.WriteHeader(http.StatusOK) + if _, err1 := request.w.Write([]byte("OK")); err1 != nil { + panic(err1) + } + }, + ) + }, + }, + } + + for _, v := range tests { + t.Run( + v.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + serv, mock := getController(ctrl) + ctx := context.Background() + + input, err := v.SetupInput() + if err != nil { + t.Error(err) + } + + v.SetupMock(*input, mock) + + res, err := v.ExpectedResult() + if err != nil { + t.Error(err) + } + + actual, err := v.Run(ctx, serv, *input) + assert.Equal(t, res, actual) + if !errors.Is(err, v.ExpectedErr) { + t.Errorf("expect %v, got %v", v.ExpectedErr, err) + } + }, + ) } } From 567490e95dbb280e6a7d18be64f96dc76fcf9b10 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sat, 14 Dec 2024 19:19:15 +0300 Subject: [PATCH 093/135] fix validate for auth --- internal/auth/controller/controller.go | 12 +++++++++++- internal/auth/controller/controller_test.go | 8 ++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/internal/auth/controller/controller.go b/internal/auth/controller/controller.go index 98d1560c..091ef697 100644 --- a/internal/auth/controller/controller.go +++ b/internal/auth/controller/controller.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "net/http" + "regexp" "time" "golang.org/x/crypto/bcrypt" @@ -108,7 +109,7 @@ func (c *AuthController) Auth(w http.ResponseWriter, r *http.Request) { c.responder.ErrorBadRequest(w, fmt.Errorf("router auth: %w", err), reqID) return } - if !validate(user) { + if !validateAuth(user) { c.responder.ErrorBadRequest(w, my_err.ErrBadUserInfo, reqID) return } @@ -187,3 +188,12 @@ func validate(user models.User) bool { } return true } + +func validateAuth(user models.User) bool { + emailRegex := regexp.MustCompile(`^[\w-.]+@([\w-]+\.)\w{2,4}$`) + if len(user.Password) < 6 || !emailRegex.MatchString(user.Email) { + return false + } + + return true +} diff --git a/internal/auth/controller/controller_test.go b/internal/auth/controller/controller_test.go index 1a98425d..46753dd7 100644 --- a/internal/auth/controller/controller_test.go +++ b/internal/auth/controller/controller_test.go @@ -168,10 +168,10 @@ func TestRegister(t *testing.T) { func TestAuth(t *testing.T) { controller := NewAuthController(&MockResponder{}, MockAuthService{}, MockSessionManager{}) - jsonUser0, _ := json.Marshal(models.User{ID: 0, FirstName: "Alex", LastName: "Zem", Password: "password"}) - jsonUser1, _ := json.Marshal(models.User{ID: 1, FirstName: "Alex", LastName: "Zem", Password: "password"}) - jsonUser2, _ := json.Marshal(models.User{ID: 2, FirstName: "Alex", LastName: "Zem", Password: "password"}) - jsonUser3, _ := json.Marshal(models.User{ID: 3, FirstName: "Alex", LastName: "Zem", Password: "password"}) + jsonUser0, _ := json.Marshal(models.User{ID: 0, Email: "test@test.ru", Password: "password"}) + jsonUser1, _ := json.Marshal(models.User{ID: 1, Email: "test@test.ru", Password: "password"}) + jsonUser2, _ := json.Marshal(models.User{ID: 2, Email: "test@test.ru", Password: "password"}) + jsonUser3, _ := json.Marshal(models.User{ID: 3, Email: "test@test.ru", Password: "password"}) jsonUser, _ := json.Marshal(models.User{ID: 3}) testCases := []TestCase{ From ca062a9e6b760d5b0bb0b721e2a20530ba5a1b3b Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sat, 14 Dec 2024 20:00:41 +0300 Subject: [PATCH 094/135] regexp in global var --- internal/auth/controller/controller.go | 3 ++- internal/auth/service/auth.go | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/auth/controller/controller.go b/internal/auth/controller/controller.go index 091ef697..b0e53af1 100644 --- a/internal/auth/controller/controller.go +++ b/internal/auth/controller/controller.go @@ -18,6 +18,8 @@ import ( "github.com/2024_2_BetterCallFirewall/pkg/my_err" ) +var emailRegex = regexp.MustCompile(`^[\w-.]+@([\w-]+\.)\w{2,4}$`) + type AuthService interface { Register(user models.User, ctx context.Context) (uint32, error) Auth(user models.User, ctx context.Context) (uint32, error) @@ -190,7 +192,6 @@ func validate(user models.User) bool { } func validateAuth(user models.User) bool { - emailRegex := regexp.MustCompile(`^[\w-.]+@([\w-]+\.)\w{2,4}$`) if len(user.Password) < 6 || !emailRegex.MatchString(user.Email) { return false } diff --git a/internal/auth/service/auth.go b/internal/auth/service/auth.go index abe73157..f4c0aad9 100644 --- a/internal/auth/service/auth.go +++ b/internal/auth/service/auth.go @@ -13,6 +13,8 @@ import ( "github.com/2024_2_BetterCallFirewall/pkg/my_err" ) +var emailRegex = regexp.MustCompile(`^[\w-.]+@([\w-]+\.)\w{2,4}$`) + type UserRepo interface { Create(ctx context.Context, user *models.User) (uint32, error) GetByEmail(ctx context.Context, email string) (*models.User, error) @@ -70,6 +72,5 @@ func (a *AuthServiceImpl) Auth(user models.User, ctx context.Context) (uint32, e } func (a *AuthServiceImpl) validateEmail(email string) bool { - emailRegex := regexp.MustCompile(`^[\w-.]+@([\w-]+\.)\w{2,4}$`) return emailRegex.MatchString(email) } From 4e9769e3e5455d647fa372f3343dda7b451ed2fd Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sat, 14 Dec 2024 23:37:13 +0300 Subject: [PATCH 095/135] fix: validate for name --- internal/auth/controller/controller.go | 4 ++-- internal/community/controller/controller.go | 2 +- internal/profile/controller/controller.go | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/auth/controller/controller.go b/internal/auth/controller/controller.go index b0e53af1..4acbbc0f 100644 --- a/internal/auth/controller/controller.go +++ b/internal/auth/controller/controller.go @@ -184,7 +184,7 @@ func (c *AuthController) Logout(w http.ResponseWriter, r *http.Request) { } func validate(user models.User) bool { - if len(user.FirstName) < 3 || len(user.LastName) < 3 || len(user.Password) < 6 || + if len([]rune(user.FirstName)) < 3 || len([]rune(user.LastName)) < 3 || len([]rune(user.Password)) < 6 || len(user.FirstName) > 30 || len(user.LastName) > 30 { return false } @@ -192,7 +192,7 @@ func validate(user models.User) bool { } func validateAuth(user models.User) bool { - if len(user.Password) < 6 || !emailRegex.MatchString(user.Email) { + if len([]rune(user.Password)) < 6 || !emailRegex.MatchString(user.Email) { return false } diff --git a/internal/community/controller/controller.go b/internal/community/controller/controller.go index 2bfa9cfa..6609aad6 100644 --- a/internal/community/controller/controller.go +++ b/internal/community/controller/controller.go @@ -387,7 +387,7 @@ func getIDFromQuery(r *http.Request) (uint32, error) { } func validate(data models.Community) bool { - if len(data.Name) < 3 || len(data.Name) >= 30 || len(data.About) >= 60 { + if len([]rune(data.Name)) < 3 || len(data.Name) >= 50 || len([]rune(data.About)) >= 60 { return false } diff --git a/internal/profile/controller/controller.go b/internal/profile/controller/controller.go index 54f16efb..19259217 100644 --- a/internal/profile/controller/controller.go +++ b/internal/profile/controller/controller.go @@ -129,9 +129,9 @@ func (h *ProfileHandlerImplementation) getNewProfile(r *http.Request) (*models.F return nil, err } - if len(newProfile.FirstName) < 3 || len(newProfile.FirstName) > 30 || - len(newProfile.LastName) < 3 || len(newProfile.LastName) > 30 || - len(newProfile.Bio) > 60 || len(newProfile.Avatar) > 100 { + if len([]rune(newProfile.FirstName)) < 3 || len(newProfile.FirstName) > 30 || + len([]rune(newProfile.LastName)) < 3 || len(newProfile.LastName) > 30 || + len(newProfile.Bio) > 100 || len(newProfile.Avatar) > 100 { return nil, errors.New("invalid profile") } From f543839ad1d634e3f8fc1d9bc964705f65181bad Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sat, 14 Dec 2024 23:39:00 +0300 Subject: [PATCH 096/135] add validate for email len --- internal/auth/service/auth.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/auth/service/auth.go b/internal/auth/service/auth.go index f4c0aad9..3c3bf7e7 100644 --- a/internal/auth/service/auth.go +++ b/internal/auth/service/auth.go @@ -72,5 +72,5 @@ func (a *AuthServiceImpl) Auth(user models.User, ctx context.Context) (uint32, e } func (a *AuthServiceImpl) validateEmail(email string) bool { - return emailRegex.MatchString(email) + return emailRegex.MatchString(email) && len(email) < 50 } From 15d59d12616e47f7730ff554d055ae3782f470db Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sun, 15 Dec 2024 01:14:26 +0300 Subject: [PATCH 097/135] generated easyjson --- Makefile | 5 +- go.mod | 2 + go.sum | 4 + internal/models/chat.go | 5 + internal/models/chat_easyjson.go | 365 ++++++++++++++++++++++ internal/models/chat_test.go | 2 + internal/models/community.go | 2 + internal/models/community_easyjson.go | 221 ++++++++++++++ internal/models/content.go | 2 + internal/models/content_easyjson.go | 140 +++++++++ internal/models/content_test.go | 1 + internal/models/post.go | 5 + internal/models/post_easyjson.go | 301 ++++++++++++++++++ internal/models/post_test.go | 2 + internal/models/profile.go | 3 + internal/models/profile_easyjson.go | 419 ++++++++++++++++++++++++++ internal/models/session.go | 1 + internal/models/session_easyjson.go | 18 ++ internal/models/user.go | 1 + internal/models/user_easyjson.go | 120 ++++++++ 20 files changed, 1618 insertions(+), 1 deletion(-) create mode 100644 internal/models/chat_easyjson.go create mode 100644 internal/models/community_easyjson.go create mode 100644 internal/models/content_easyjson.go create mode 100644 internal/models/post_easyjson.go create mode 100644 internal/models/profile_easyjson.go create mode 100644 internal/models/session_easyjson.go create mode 100644 internal/models/user_easyjson.go diff --git a/Makefile b/Makefile index 9be8968d..fd4add19 100644 --- a/Makefile +++ b/Makefile @@ -16,4 +16,7 @@ gen-proto: proto/*.proto lint: - golangci-lint run \ No newline at end of file + golangci-lint run + +gen-easy-json: + easyjson -all internal/models/*.go \ No newline at end of file diff --git a/go.mod b/go.mod index f28e9261..79cc766e 100644 --- a/go.mod +++ b/go.mod @@ -33,8 +33,10 @@ require ( github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.17.9 // indirect github.com/kr/text v0.2.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/go.sum b/go.sum index ff66a4f6..c669881d 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,8 @@ github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= @@ -51,6 +53,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= diff --git a/internal/models/chat.go b/internal/models/chat.go index e5dd5b7a..41a25bd8 100644 --- a/internal/models/chat.go +++ b/internal/models/chat.go @@ -5,12 +5,14 @@ import ( "time" ) +//easyjson:json type Chat struct { LastMessage string `json:"last_message"` LastDate time.Time `json:"last_date"` Receiver Header `json:"receiver"` } +//easyjson:json type Message struct { Sender uint32 `json:"sender"` Receiver uint32 `json:"receiver"` @@ -18,6 +20,7 @@ type Message struct { CreatedAt time.Time `json:"created_at"` } +//easyjson:skip type MessageDto struct { Sender uint32 Receiver uint32 @@ -43,12 +46,14 @@ func (m *MessageDto) FromDto() Message { } } +//easyjson:json type MessageContent struct { Text string `json:"text"` FilePath []string `json:"file_path"` StickerPath string `json:"sticker_path"` } +//easyjson:skip type MessageContentDto struct { Text string FilePath string diff --git a/internal/models/chat_easyjson.go b/internal/models/chat_easyjson.go new file mode 100644 index 00000000..ca2d3f8a --- /dev/null +++ b/internal/models/chat_easyjson.go @@ -0,0 +1,365 @@ +// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. + +package models + +import ( + json "encoding/json" + easyjson "github.com/mailru/easyjson" + jlexer "github.com/mailru/easyjson/jlexer" + jwriter "github.com/mailru/easyjson/jwriter" +) + +// suppress unused package warning +var ( + _ *json.RawMessage + _ *jlexer.Lexer + _ *jwriter.Writer + _ easyjson.Marshaler +) + +func easyjson9b8f5552DecodeGithubCom20242BetterCallFirewallInternalModels(in *jlexer.Lexer, out *MessageContent) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "text": + out.Text = string(in.String()) + case "file_path": + if in.IsNull() { + in.Skip() + out.FilePath = nil + } else { + in.Delim('[') + if out.FilePath == nil { + if !in.IsDelim(']') { + out.FilePath = make([]string, 0, 4) + } else { + out.FilePath = []string{} + } + } else { + out.FilePath = (out.FilePath)[:0] + } + for !in.IsDelim(']') { + var v1 string + v1 = string(in.String()) + out.FilePath = append(out.FilePath, v1) + in.WantComma() + } + in.Delim(']') + } + case "sticker_path": + out.StickerPath = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson9b8f5552EncodeGithubCom20242BetterCallFirewallInternalModels(out *jwriter.Writer, in MessageContent) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"text\":" + out.RawString(prefix[1:]) + out.String(string(in.Text)) + } + { + const prefix string = ",\"file_path\":" + out.RawString(prefix) + if in.FilePath == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { + out.RawString("null") + } else { + out.RawByte('[') + for v2, v3 := range in.FilePath { + if v2 > 0 { + out.RawByte(',') + } + out.String(string(v3)) + } + out.RawByte(']') + } + } + { + const prefix string = ",\"sticker_path\":" + out.RawString(prefix) + out.String(string(in.StickerPath)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v MessageContent) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson9b8f5552EncodeGithubCom20242BetterCallFirewallInternalModels(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v MessageContent) MarshalEasyJSON(w *jwriter.Writer) { + easyjson9b8f5552EncodeGithubCom20242BetterCallFirewallInternalModels(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *MessageContent) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson9b8f5552DecodeGithubCom20242BetterCallFirewallInternalModels(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *MessageContent) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson9b8f5552DecodeGithubCom20242BetterCallFirewallInternalModels(l, v) +} +func easyjson9b8f5552DecodeGithubCom20242BetterCallFirewallInternalModels1(in *jlexer.Lexer, out *Message) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "sender": + out.Sender = uint32(in.Uint32()) + case "receiver": + out.Receiver = uint32(in.Uint32()) + case "content": + (out.Content).UnmarshalEasyJSON(in) + case "created_at": + if data := in.Raw(); in.Ok() { + in.AddError((out.CreatedAt).UnmarshalJSON(data)) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson9b8f5552EncodeGithubCom20242BetterCallFirewallInternalModels1(out *jwriter.Writer, in Message) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"sender\":" + out.RawString(prefix[1:]) + out.Uint32(uint32(in.Sender)) + } + { + const prefix string = ",\"receiver\":" + out.RawString(prefix) + out.Uint32(uint32(in.Receiver)) + } + { + const prefix string = ",\"content\":" + out.RawString(prefix) + (in.Content).MarshalEasyJSON(out) + } + { + const prefix string = ",\"created_at\":" + out.RawString(prefix) + out.Raw((in.CreatedAt).MarshalJSON()) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v Message) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson9b8f5552EncodeGithubCom20242BetterCallFirewallInternalModels1(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Message) MarshalEasyJSON(w *jwriter.Writer) { + easyjson9b8f5552EncodeGithubCom20242BetterCallFirewallInternalModels1(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *Message) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson9b8f5552DecodeGithubCom20242BetterCallFirewallInternalModels1(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Message) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson9b8f5552DecodeGithubCom20242BetterCallFirewallInternalModels1(l, v) +} +func easyjson9b8f5552DecodeGithubCom20242BetterCallFirewallInternalModels2(in *jlexer.Lexer, out *Chat) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "last_message": + out.LastMessage = string(in.String()) + case "last_date": + if data := in.Raw(); in.Ok() { + in.AddError((out.LastDate).UnmarshalJSON(data)) + } + case "receiver": + easyjson9b8f5552DecodeGithubCom20242BetterCallFirewallInternalModels3(in, &out.Receiver) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson9b8f5552EncodeGithubCom20242BetterCallFirewallInternalModels2(out *jwriter.Writer, in Chat) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"last_message\":" + out.RawString(prefix[1:]) + out.String(string(in.LastMessage)) + } + { + const prefix string = ",\"last_date\":" + out.RawString(prefix) + out.Raw((in.LastDate).MarshalJSON()) + } + { + const prefix string = ",\"receiver\":" + out.RawString(prefix) + easyjson9b8f5552EncodeGithubCom20242BetterCallFirewallInternalModels3(out, in.Receiver) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v Chat) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson9b8f5552EncodeGithubCom20242BetterCallFirewallInternalModels2(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Chat) MarshalEasyJSON(w *jwriter.Writer) { + easyjson9b8f5552EncodeGithubCom20242BetterCallFirewallInternalModels2(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *Chat) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson9b8f5552DecodeGithubCom20242BetterCallFirewallInternalModels2(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Chat) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson9b8f5552DecodeGithubCom20242BetterCallFirewallInternalModels2(l, v) +} +func easyjson9b8f5552DecodeGithubCom20242BetterCallFirewallInternalModels3(in *jlexer.Lexer, out *Header) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "author_id": + out.AuthorID = uint32(in.Uint32()) + case "community_id": + out.CommunityID = uint32(in.Uint32()) + case "author": + out.Author = string(in.String()) + case "avatar": + out.Avatar = Picture(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson9b8f5552EncodeGithubCom20242BetterCallFirewallInternalModels3(out *jwriter.Writer, in Header) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"author_id\":" + out.RawString(prefix[1:]) + out.Uint32(uint32(in.AuthorID)) + } + { + const prefix string = ",\"community_id\":" + out.RawString(prefix) + out.Uint32(uint32(in.CommunityID)) + } + { + const prefix string = ",\"author\":" + out.RawString(prefix) + out.String(string(in.Author)) + } + { + const prefix string = ",\"avatar\":" + out.RawString(prefix) + out.String(string(in.Avatar)) + } + out.RawByte('}') +} diff --git a/internal/models/chat_test.go b/internal/models/chat_test.go index 2004900c..ce068669 100644 --- a/internal/models/chat_test.go +++ b/internal/models/chat_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/assert" ) +//easyjson:skip type TestCaseMessageContent struct { content MessageContent contentDto MessageContentDto @@ -49,6 +50,7 @@ func TestToDtoMessageContent(t *testing.T) { } } +//easyjson:skip type TestCaseMessage struct { message Message messageDto MessageDto diff --git a/internal/models/community.go b/internal/models/community.go index f87dbe45..8630c16a 100644 --- a/internal/models/community.go +++ b/internal/models/community.go @@ -1,5 +1,6 @@ package models +//easyjson:json type Community struct { ID uint32 `json:"id"` Name string `json:"name"` @@ -10,6 +11,7 @@ type Community struct { IsFollowed bool `json:"is_followed,omitempty"` } +//easyjson:json type CommunityCard struct { ID uint32 `json:"id"` Name string `json:"name"` diff --git a/internal/models/community_easyjson.go b/internal/models/community_easyjson.go new file mode 100644 index 00000000..4d9699ac --- /dev/null +++ b/internal/models/community_easyjson.go @@ -0,0 +1,221 @@ +// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. + +package models + +import ( + json "encoding/json" + easyjson "github.com/mailru/easyjson" + jlexer "github.com/mailru/easyjson/jlexer" + jwriter "github.com/mailru/easyjson/jwriter" +) + +// suppress unused package warning +var ( + _ *json.RawMessage + _ *jlexer.Lexer + _ *jwriter.Writer + _ easyjson.Marshaler +) + +func easyjson798dd0c9DecodeGithubCom20242BetterCallFirewallInternalModels(in *jlexer.Lexer, out *CommunityCard) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "id": + out.ID = uint32(in.Uint32()) + case "name": + out.Name = string(in.String()) + case "avatar": + out.Avatar = Picture(in.String()) + case "about": + out.About = string(in.String()) + case "is_followed": + out.IsFollowed = bool(in.Bool()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson798dd0c9EncodeGithubCom20242BetterCallFirewallInternalModels(out *jwriter.Writer, in CommunityCard) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"id\":" + out.RawString(prefix[1:]) + out.Uint32(uint32(in.ID)) + } + { + const prefix string = ",\"name\":" + out.RawString(prefix) + out.String(string(in.Name)) + } + { + const prefix string = ",\"avatar\":" + out.RawString(prefix) + out.String(string(in.Avatar)) + } + { + const prefix string = ",\"about\":" + out.RawString(prefix) + out.String(string(in.About)) + } + if in.IsFollowed { + const prefix string = ",\"is_followed\":" + out.RawString(prefix) + out.Bool(bool(in.IsFollowed)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v CommunityCard) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson798dd0c9EncodeGithubCom20242BetterCallFirewallInternalModels(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v CommunityCard) MarshalEasyJSON(w *jwriter.Writer) { + easyjson798dd0c9EncodeGithubCom20242BetterCallFirewallInternalModels(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *CommunityCard) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson798dd0c9DecodeGithubCom20242BetterCallFirewallInternalModels(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *CommunityCard) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson798dd0c9DecodeGithubCom20242BetterCallFirewallInternalModels(l, v) +} +func easyjson798dd0c9DecodeGithubCom20242BetterCallFirewallInternalModels1(in *jlexer.Lexer, out *Community) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "id": + out.ID = uint32(in.Uint32()) + case "name": + out.Name = string(in.String()) + case "avatar": + out.Avatar = Picture(in.String()) + case "about": + out.About = string(in.String()) + case "count_subscribers": + out.CountSubscribers = uint32(in.Uint32()) + case "is_admin": + out.IsAdmin = bool(in.Bool()) + case "is_followed": + out.IsFollowed = bool(in.Bool()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson798dd0c9EncodeGithubCom20242BetterCallFirewallInternalModels1(out *jwriter.Writer, in Community) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"id\":" + out.RawString(prefix[1:]) + out.Uint32(uint32(in.ID)) + } + { + const prefix string = ",\"name\":" + out.RawString(prefix) + out.String(string(in.Name)) + } + { + const prefix string = ",\"avatar\":" + out.RawString(prefix) + out.String(string(in.Avatar)) + } + { + const prefix string = ",\"about\":" + out.RawString(prefix) + out.String(string(in.About)) + } + { + const prefix string = ",\"count_subscribers\":" + out.RawString(prefix) + out.Uint32(uint32(in.CountSubscribers)) + } + if in.IsAdmin { + const prefix string = ",\"is_admin\":" + out.RawString(prefix) + out.Bool(bool(in.IsAdmin)) + } + if in.IsFollowed { + const prefix string = ",\"is_followed\":" + out.RawString(prefix) + out.Bool(bool(in.IsFollowed)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v Community) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson798dd0c9EncodeGithubCom20242BetterCallFirewallInternalModels1(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Community) MarshalEasyJSON(w *jwriter.Writer) { + easyjson798dd0c9EncodeGithubCom20242BetterCallFirewallInternalModels1(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *Community) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson798dd0c9DecodeGithubCom20242BetterCallFirewallInternalModels1(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Community) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson798dd0c9DecodeGithubCom20242BetterCallFirewallInternalModels1(l, v) +} diff --git a/internal/models/content.go b/internal/models/content.go index def50fda..cef48ac9 100644 --- a/internal/models/content.go +++ b/internal/models/content.go @@ -5,6 +5,7 @@ import ( "time" ) +//easyjson:json type Content struct { Text string `json:"text"` File []Picture `json:"file,omitempty"` @@ -29,6 +30,7 @@ func (c *Content) ToDto() ContentDto { } } +//easyjson:skip type ContentDto struct { Text string File Picture diff --git a/internal/models/content_easyjson.go b/internal/models/content_easyjson.go new file mode 100644 index 00000000..fd293128 --- /dev/null +++ b/internal/models/content_easyjson.go @@ -0,0 +1,140 @@ +// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. + +package models + +import ( + json "encoding/json" + easyjson "github.com/mailru/easyjson" + jlexer "github.com/mailru/easyjson/jlexer" + jwriter "github.com/mailru/easyjson/jwriter" +) + +// suppress unused package warning +var ( + _ *json.RawMessage + _ *jlexer.Lexer + _ *jwriter.Writer + _ easyjson.Marshaler +) + +func easyjson344736e9DecodeGithubCom20242BetterCallFirewallInternalModels(in *jlexer.Lexer, out *Content) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "text": + out.Text = string(in.String()) + case "file": + if in.IsNull() { + in.Skip() + out.File = nil + } else { + in.Delim('[') + if out.File == nil { + if !in.IsDelim(']') { + out.File = make([]Picture, 0, 4) + } else { + out.File = []Picture{} + } + } else { + out.File = (out.File)[:0] + } + for !in.IsDelim(']') { + var v1 Picture + v1 = Picture(in.String()) + out.File = append(out.File, v1) + in.WantComma() + } + in.Delim(']') + } + case "created_at": + if data := in.Raw(); in.Ok() { + in.AddError((out.CreatedAt).UnmarshalJSON(data)) + } + case "updated_at": + if data := in.Raw(); in.Ok() { + in.AddError((out.UpdatedAt).UnmarshalJSON(data)) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson344736e9EncodeGithubCom20242BetterCallFirewallInternalModels(out *jwriter.Writer, in Content) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"text\":" + out.RawString(prefix[1:]) + out.String(string(in.Text)) + } + if len(in.File) != 0 { + const prefix string = ",\"file\":" + out.RawString(prefix) + { + out.RawByte('[') + for v2, v3 := range in.File { + if v2 > 0 { + out.RawByte(',') + } + out.String(string(v3)) + } + out.RawByte(']') + } + } + { + const prefix string = ",\"created_at\":" + out.RawString(prefix) + out.Raw((in.CreatedAt).MarshalJSON()) + } + { + const prefix string = ",\"updated_at\":" + out.RawString(prefix) + out.Raw((in.UpdatedAt).MarshalJSON()) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v Content) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson344736e9EncodeGithubCom20242BetterCallFirewallInternalModels(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Content) MarshalEasyJSON(w *jwriter.Writer) { + easyjson344736e9EncodeGithubCom20242BetterCallFirewallInternalModels(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *Content) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson344736e9DecodeGithubCom20242BetterCallFirewallInternalModels(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Content) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson344736e9DecodeGithubCom20242BetterCallFirewallInternalModels(l, v) +} diff --git a/internal/models/content_test.go b/internal/models/content_test.go index be7353c5..a742b153 100644 --- a/internal/models/content_test.go +++ b/internal/models/content_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/assert" ) +//easyjson:skip type TestCase struct { content Content contentDto ContentDto diff --git a/internal/models/post.go b/internal/models/post.go index d7ad6845..b2930e77 100644 --- a/internal/models/post.go +++ b/internal/models/post.go @@ -1,5 +1,6 @@ package models +//easyjson:json type Post struct { ID uint32 `json:"id"` Header Header `json:"header"` @@ -20,6 +21,7 @@ func (p *Post) ToDto() PostDto { } } +//easyjson:skip type PostDto struct { ID uint32 Header Header @@ -40,6 +42,7 @@ func (p *PostDto) FromDto() Post { } } +//easyjson:json type Header struct { AuthorID uint32 `json:"author_id"` CommunityID uint32 `json:"community_id"` @@ -47,6 +50,7 @@ type Header struct { Avatar Picture `json:"avatar"` } +//easyjson:json type Comment struct { ID uint32 `json:"id"` Header Header `json:"header"` @@ -65,6 +69,7 @@ func (c *Comment) ToDto() CommentDto { } } +//easyjson:skip type CommentDto struct { ID uint32 Header Header diff --git a/internal/models/post_easyjson.go b/internal/models/post_easyjson.go new file mode 100644 index 00000000..be42cefa --- /dev/null +++ b/internal/models/post_easyjson.go @@ -0,0 +1,301 @@ +// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. + +package models + +import ( + json "encoding/json" + easyjson "github.com/mailru/easyjson" + jlexer "github.com/mailru/easyjson/jlexer" + jwriter "github.com/mailru/easyjson/jwriter" +) + +// suppress unused package warning +var ( + _ *json.RawMessage + _ *jlexer.Lexer + _ *jwriter.Writer + _ easyjson.Marshaler +) + +func easyjson5a72dc82DecodeGithubCom20242BetterCallFirewallInternalModels(in *jlexer.Lexer, out *Post) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "id": + out.ID = uint32(in.Uint32()) + case "header": + (out.Header).UnmarshalEasyJSON(in) + case "post_content": + (out.PostContent).UnmarshalEasyJSON(in) + case "likes_count": + out.LikesCount = uint32(in.Uint32()) + case "is_liked": + out.IsLiked = bool(in.Bool()) + case "comment_count": + out.CommentCount = uint32(in.Uint32()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson5a72dc82EncodeGithubCom20242BetterCallFirewallInternalModels(out *jwriter.Writer, in Post) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"id\":" + out.RawString(prefix[1:]) + out.Uint32(uint32(in.ID)) + } + { + const prefix string = ",\"header\":" + out.RawString(prefix) + (in.Header).MarshalEasyJSON(out) + } + { + const prefix string = ",\"post_content\":" + out.RawString(prefix) + (in.PostContent).MarshalEasyJSON(out) + } + { + const prefix string = ",\"likes_count\":" + out.RawString(prefix) + out.Uint32(uint32(in.LikesCount)) + } + { + const prefix string = ",\"is_liked\":" + out.RawString(prefix) + out.Bool(bool(in.IsLiked)) + } + { + const prefix string = ",\"comment_count\":" + out.RawString(prefix) + out.Uint32(uint32(in.CommentCount)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v Post) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson5a72dc82EncodeGithubCom20242BetterCallFirewallInternalModels(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Post) MarshalEasyJSON(w *jwriter.Writer) { + easyjson5a72dc82EncodeGithubCom20242BetterCallFirewallInternalModels(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *Post) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson5a72dc82DecodeGithubCom20242BetterCallFirewallInternalModels(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Post) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson5a72dc82DecodeGithubCom20242BetterCallFirewallInternalModels(l, v) +} +func easyjson5a72dc82DecodeGithubCom20242BetterCallFirewallInternalModels1(in *jlexer.Lexer, out *Header) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "author_id": + out.AuthorID = uint32(in.Uint32()) + case "community_id": + out.CommunityID = uint32(in.Uint32()) + case "author": + out.Author = string(in.String()) + case "avatar": + out.Avatar = Picture(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson5a72dc82EncodeGithubCom20242BetterCallFirewallInternalModels1(out *jwriter.Writer, in Header) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"author_id\":" + out.RawString(prefix[1:]) + out.Uint32(uint32(in.AuthorID)) + } + { + const prefix string = ",\"community_id\":" + out.RawString(prefix) + out.Uint32(uint32(in.CommunityID)) + } + { + const prefix string = ",\"author\":" + out.RawString(prefix) + out.String(string(in.Author)) + } + { + const prefix string = ",\"avatar\":" + out.RawString(prefix) + out.String(string(in.Avatar)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v Header) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson5a72dc82EncodeGithubCom20242BetterCallFirewallInternalModels1(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Header) MarshalEasyJSON(w *jwriter.Writer) { + easyjson5a72dc82EncodeGithubCom20242BetterCallFirewallInternalModels1(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *Header) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson5a72dc82DecodeGithubCom20242BetterCallFirewallInternalModels1(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Header) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson5a72dc82DecodeGithubCom20242BetterCallFirewallInternalModels1(l, v) +} +func easyjson5a72dc82DecodeGithubCom20242BetterCallFirewallInternalModels2(in *jlexer.Lexer, out *Comment) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "id": + out.ID = uint32(in.Uint32()) + case "header": + (out.Header).UnmarshalEasyJSON(in) + case "content": + (out.Content).UnmarshalEasyJSON(in) + case "likes_count": + out.LikesCount = uint32(in.Uint32()) + case "is_liked": + out.IsLiked = bool(in.Bool()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson5a72dc82EncodeGithubCom20242BetterCallFirewallInternalModels2(out *jwriter.Writer, in Comment) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"id\":" + out.RawString(prefix[1:]) + out.Uint32(uint32(in.ID)) + } + { + const prefix string = ",\"header\":" + out.RawString(prefix) + (in.Header).MarshalEasyJSON(out) + } + { + const prefix string = ",\"content\":" + out.RawString(prefix) + (in.Content).MarshalEasyJSON(out) + } + { + const prefix string = ",\"likes_count\":" + out.RawString(prefix) + out.Uint32(uint32(in.LikesCount)) + } + { + const prefix string = ",\"is_liked\":" + out.RawString(prefix) + out.Bool(bool(in.IsLiked)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v Comment) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson5a72dc82EncodeGithubCom20242BetterCallFirewallInternalModels2(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Comment) MarshalEasyJSON(w *jwriter.Writer) { + easyjson5a72dc82EncodeGithubCom20242BetterCallFirewallInternalModels2(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *Comment) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson5a72dc82DecodeGithubCom20242BetterCallFirewallInternalModels2(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Comment) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson5a72dc82DecodeGithubCom20242BetterCallFirewallInternalModels2(l, v) +} diff --git a/internal/models/post_test.go b/internal/models/post_test.go index 02a7663c..50713e42 100644 --- a/internal/models/post_test.go +++ b/internal/models/post_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/assert" ) +//easyjson:skip type TestCasePost struct { post Post postDto PostDto @@ -51,6 +52,7 @@ func TestPostToDto(t *testing.T) { } } +//easyjson:skip type TestCaseComment struct { comment Comment commentDto CommentDto diff --git a/internal/models/profile.go b/internal/models/profile.go index 441d5739..aa50bece 100644 --- a/internal/models/profile.go +++ b/internal/models/profile.go @@ -1,5 +1,6 @@ package models +//easyjson:json type FullProfile struct { ID uint32 `json:"id"` FirstName string `json:"first_name"` @@ -14,6 +15,7 @@ type FullProfile struct { Posts []*Post `json:"posts"` } +//easyjson:json type ShortProfile struct { ID uint32 `json:"id"` FirstName string `json:"first_name"` @@ -25,6 +27,7 @@ type ShortProfile struct { Avatar Picture `json:"avatar"` } +//easyjson:json type ChangePasswordReq struct { OldPassword string `json:"old_password"` NewPassword string `json:"new_password"` diff --git a/internal/models/profile_easyjson.go b/internal/models/profile_easyjson.go new file mode 100644 index 00000000..b921add6 --- /dev/null +++ b/internal/models/profile_easyjson.go @@ -0,0 +1,419 @@ +// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. + +package models + +import ( + json "encoding/json" + easyjson "github.com/mailru/easyjson" + jlexer "github.com/mailru/easyjson/jlexer" + jwriter "github.com/mailru/easyjson/jwriter" +) + +// suppress unused package warning +var ( + _ *json.RawMessage + _ *jlexer.Lexer + _ *jwriter.Writer + _ easyjson.Marshaler +) + +func easyjson521a5691DecodeGithubCom20242BetterCallFirewallInternalModels(in *jlexer.Lexer, out *ShortProfile) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "id": + out.ID = uint32(in.Uint32()) + case "first_name": + out.FirstName = string(in.String()) + case "last_name": + out.LastName = string(in.String()) + case "is_author": + out.IsAuthor = bool(in.Bool()) + case "is_friend": + out.IsFriend = bool(in.Bool()) + case "is_subscriber": + out.IsSubscriber = bool(in.Bool()) + case "is_subscription": + out.IsSubscription = bool(in.Bool()) + case "avatar": + out.Avatar = Picture(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson521a5691EncodeGithubCom20242BetterCallFirewallInternalModels(out *jwriter.Writer, in ShortProfile) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"id\":" + out.RawString(prefix[1:]) + out.Uint32(uint32(in.ID)) + } + { + const prefix string = ",\"first_name\":" + out.RawString(prefix) + out.String(string(in.FirstName)) + } + { + const prefix string = ",\"last_name\":" + out.RawString(prefix) + out.String(string(in.LastName)) + } + { + const prefix string = ",\"is_author\":" + out.RawString(prefix) + out.Bool(bool(in.IsAuthor)) + } + { + const prefix string = ",\"is_friend\":" + out.RawString(prefix) + out.Bool(bool(in.IsFriend)) + } + { + const prefix string = ",\"is_subscriber\":" + out.RawString(prefix) + out.Bool(bool(in.IsSubscriber)) + } + { + const prefix string = ",\"is_subscription\":" + out.RawString(prefix) + out.Bool(bool(in.IsSubscription)) + } + { + const prefix string = ",\"avatar\":" + out.RawString(prefix) + out.String(string(in.Avatar)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v ShortProfile) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson521a5691EncodeGithubCom20242BetterCallFirewallInternalModels(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v ShortProfile) MarshalEasyJSON(w *jwriter.Writer) { + easyjson521a5691EncodeGithubCom20242BetterCallFirewallInternalModels(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *ShortProfile) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson521a5691DecodeGithubCom20242BetterCallFirewallInternalModels(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *ShortProfile) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson521a5691DecodeGithubCom20242BetterCallFirewallInternalModels(l, v) +} +func easyjson521a5691DecodeGithubCom20242BetterCallFirewallInternalModels1(in *jlexer.Lexer, out *FullProfile) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "id": + out.ID = uint32(in.Uint32()) + case "first_name": + out.FirstName = string(in.String()) + case "last_name": + out.LastName = string(in.String()) + case "bio": + out.Bio = string(in.String()) + case "is_author": + out.IsAuthor = bool(in.Bool()) + case "is_friend": + out.IsFriend = bool(in.Bool()) + case "is_subscriber": + out.IsSubscriber = bool(in.Bool()) + case "is_subscription": + out.IsSubscription = bool(in.Bool()) + case "avatar": + out.Avatar = Picture(in.String()) + case "pics": + if in.IsNull() { + in.Skip() + out.Pics = nil + } else { + in.Delim('[') + if out.Pics == nil { + if !in.IsDelim(']') { + out.Pics = make([]Picture, 0, 4) + } else { + out.Pics = []Picture{} + } + } else { + out.Pics = (out.Pics)[:0] + } + for !in.IsDelim(']') { + var v1 Picture + v1 = Picture(in.String()) + out.Pics = append(out.Pics, v1) + in.WantComma() + } + in.Delim(']') + } + case "posts": + if in.IsNull() { + in.Skip() + out.Posts = nil + } else { + in.Delim('[') + if out.Posts == nil { + if !in.IsDelim(']') { + out.Posts = make([]*Post, 0, 8) + } else { + out.Posts = []*Post{} + } + } else { + out.Posts = (out.Posts)[:0] + } + for !in.IsDelim(']') { + var v2 *Post + if in.IsNull() { + in.Skip() + v2 = nil + } else { + if v2 == nil { + v2 = new(Post) + } + (*v2).UnmarshalEasyJSON(in) + } + out.Posts = append(out.Posts, v2) + in.WantComma() + } + in.Delim(']') + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson521a5691EncodeGithubCom20242BetterCallFirewallInternalModels1(out *jwriter.Writer, in FullProfile) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"id\":" + out.RawString(prefix[1:]) + out.Uint32(uint32(in.ID)) + } + { + const prefix string = ",\"first_name\":" + out.RawString(prefix) + out.String(string(in.FirstName)) + } + { + const prefix string = ",\"last_name\":" + out.RawString(prefix) + out.String(string(in.LastName)) + } + { + const prefix string = ",\"bio\":" + out.RawString(prefix) + out.String(string(in.Bio)) + } + { + const prefix string = ",\"is_author\":" + out.RawString(prefix) + out.Bool(bool(in.IsAuthor)) + } + { + const prefix string = ",\"is_friend\":" + out.RawString(prefix) + out.Bool(bool(in.IsFriend)) + } + { + const prefix string = ",\"is_subscriber\":" + out.RawString(prefix) + out.Bool(bool(in.IsSubscriber)) + } + { + const prefix string = ",\"is_subscription\":" + out.RawString(prefix) + out.Bool(bool(in.IsSubscription)) + } + { + const prefix string = ",\"avatar\":" + out.RawString(prefix) + out.String(string(in.Avatar)) + } + { + const prefix string = ",\"pics\":" + out.RawString(prefix) + if in.Pics == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { + out.RawString("null") + } else { + out.RawByte('[') + for v3, v4 := range in.Pics { + if v3 > 0 { + out.RawByte(',') + } + out.String(string(v4)) + } + out.RawByte(']') + } + } + { + const prefix string = ",\"posts\":" + out.RawString(prefix) + if in.Posts == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { + out.RawString("null") + } else { + out.RawByte('[') + for v5, v6 := range in.Posts { + if v5 > 0 { + out.RawByte(',') + } + if v6 == nil { + out.RawString("null") + } else { + (*v6).MarshalEasyJSON(out) + } + } + out.RawByte(']') + } + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v FullProfile) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson521a5691EncodeGithubCom20242BetterCallFirewallInternalModels1(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v FullProfile) MarshalEasyJSON(w *jwriter.Writer) { + easyjson521a5691EncodeGithubCom20242BetterCallFirewallInternalModels1(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *FullProfile) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson521a5691DecodeGithubCom20242BetterCallFirewallInternalModels1(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *FullProfile) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson521a5691DecodeGithubCom20242BetterCallFirewallInternalModels1(l, v) +} +func easyjson521a5691DecodeGithubCom20242BetterCallFirewallInternalModels2(in *jlexer.Lexer, out *ChangePasswordReq) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "old_password": + out.OldPassword = string(in.String()) + case "new_password": + out.NewPassword = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson521a5691EncodeGithubCom20242BetterCallFirewallInternalModels2(out *jwriter.Writer, in ChangePasswordReq) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"old_password\":" + out.RawString(prefix[1:]) + out.String(string(in.OldPassword)) + } + { + const prefix string = ",\"new_password\":" + out.RawString(prefix) + out.String(string(in.NewPassword)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v ChangePasswordReq) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson521a5691EncodeGithubCom20242BetterCallFirewallInternalModels2(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v ChangePasswordReq) MarshalEasyJSON(w *jwriter.Writer) { + easyjson521a5691EncodeGithubCom20242BetterCallFirewallInternalModels2(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *ChangePasswordReq) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson521a5691DecodeGithubCom20242BetterCallFirewallInternalModels2(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *ChangePasswordReq) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson521a5691DecodeGithubCom20242BetterCallFirewallInternalModels2(l, v) +} diff --git a/internal/models/session.go b/internal/models/session.go index 162f6238..334d688e 100644 --- a/internal/models/session.go +++ b/internal/models/session.go @@ -9,6 +9,7 @@ import ( "github.com/2024_2_BetterCallFirewall/pkg/my_err" ) +//easyjson:skip type Session struct { ID string UserID uint32 diff --git a/internal/models/session_easyjson.go b/internal/models/session_easyjson.go new file mode 100644 index 00000000..4d92eaa6 --- /dev/null +++ b/internal/models/session_easyjson.go @@ -0,0 +1,18 @@ +// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. + +package models + +import ( + json "encoding/json" + easyjson "github.com/mailru/easyjson" + jlexer "github.com/mailru/easyjson/jlexer" + jwriter "github.com/mailru/easyjson/jwriter" +) + +// suppress unused package warning +var ( + _ *json.RawMessage + _ *jlexer.Lexer + _ *jwriter.Writer + _ easyjson.Marshaler +) diff --git a/internal/models/user.go b/internal/models/user.go index 8cc6c5ca..ffc9686d 100644 --- a/internal/models/user.go +++ b/internal/models/user.go @@ -2,6 +2,7 @@ package models type Picture string +//easyjson:json type User struct { ID uint32 `json:"id"` Email string `json:"email"` diff --git a/internal/models/user_easyjson.go b/internal/models/user_easyjson.go new file mode 100644 index 00000000..2c9409a9 --- /dev/null +++ b/internal/models/user_easyjson.go @@ -0,0 +1,120 @@ +// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. + +package models + +import ( + json "encoding/json" + easyjson "github.com/mailru/easyjson" + jlexer "github.com/mailru/easyjson/jlexer" + jwriter "github.com/mailru/easyjson/jwriter" +) + +// suppress unused package warning +var ( + _ *json.RawMessage + _ *jlexer.Lexer + _ *jwriter.Writer + _ easyjson.Marshaler +) + +func easyjson9e1087fdDecodeGithubCom20242BetterCallFirewallInternalModels(in *jlexer.Lexer, out *User) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "id": + out.ID = uint32(in.Uint32()) + case "email": + out.Email = string(in.String()) + case "password": + out.Password = string(in.String()) + case "first_name": + out.FirstName = string(in.String()) + case "last_name": + out.LastName = string(in.String()) + case "avatar": + out.Avatar = Picture(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson9e1087fdEncodeGithubCom20242BetterCallFirewallInternalModels(out *jwriter.Writer, in User) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"id\":" + out.RawString(prefix[1:]) + out.Uint32(uint32(in.ID)) + } + { + const prefix string = ",\"email\":" + out.RawString(prefix) + out.String(string(in.Email)) + } + { + const prefix string = ",\"password\":" + out.RawString(prefix) + out.String(string(in.Password)) + } + { + const prefix string = ",\"first_name\":" + out.RawString(prefix) + out.String(string(in.FirstName)) + } + { + const prefix string = ",\"last_name\":" + out.RawString(prefix) + out.String(string(in.LastName)) + } + { + const prefix string = ",\"avatar\":" + out.RawString(prefix) + out.String(string(in.Avatar)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v User) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson9e1087fdEncodeGithubCom20242BetterCallFirewallInternalModels(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v User) MarshalEasyJSON(w *jwriter.Writer) { + easyjson9e1087fdEncodeGithubCom20242BetterCallFirewallInternalModels(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *User) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson9e1087fdDecodeGithubCom20242BetterCallFirewallInternalModels(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *User) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson9e1087fdDecodeGithubCom20242BetterCallFirewallInternalModels(l, v) +} From cd76c9727404d13388f3a1c55e8b72c343f4c198 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sun, 15 Dec 2024 12:18:04 +0300 Subject: [PATCH 098/135] now use easyjson --- internal/auth/controller/controller.go | 6 +- internal/chat/controller/client.go | 6 +- internal/community/controller/controller.go | 3 +- internal/post/controller/controller.go | 8 +- internal/profile/controller/controller.go | 6 +- internal/router/responder.go | 6 +- internal/router/responder_easyjson.go | 111 ++++++++++++++++++++ 7 files changed, 131 insertions(+), 15 deletions(-) create mode 100644 internal/router/responder_easyjson.go diff --git a/internal/auth/controller/controller.go b/internal/auth/controller/controller.go index 4acbbc0f..81a2fc0e 100644 --- a/internal/auth/controller/controller.go +++ b/internal/auth/controller/controller.go @@ -2,13 +2,13 @@ package controller import ( "context" - "encoding/json" "errors" "fmt" "net/http" "regexp" "time" + "github.com/mailru/easyjson" "golang.org/x/crypto/bcrypt" "github.com/2024_2_BetterCallFirewall/internal/auth" @@ -56,7 +56,7 @@ func (c *AuthController) Register(w http.ResponseWriter, r *http.Request) { } user := models.User{} - err := json.NewDecoder(r.Body).Decode(&user) + err := easyjson.UnmarshalFromReader(r.Body, &user) if err != nil { c.responder.ErrorBadRequest(w, fmt.Errorf("router register: %w", err), reqID) return @@ -106,7 +106,7 @@ func (c *AuthController) Auth(w http.ResponseWriter, r *http.Request) { } user := models.User{} - err := json.NewDecoder(r.Body).Decode(&user) + err := easyjson.UnmarshalFromReader(r.Body, &user) if err != nil { c.responder.ErrorBadRequest(w, fmt.Errorf("router auth: %w", err), reqID) return diff --git a/internal/chat/controller/client.go b/internal/chat/controller/client.go index aef237e0..73cb52a2 100644 --- a/internal/chat/controller/client.go +++ b/internal/chat/controller/client.go @@ -1,10 +1,10 @@ package controller import ( - "encoding/json" "time" "github.com/gorilla/websocket" + "github.com/mailru/easyjson" "github.com/2024_2_BetterCallFirewall/internal/models" ) @@ -26,7 +26,7 @@ func (c *Client) Read(userID uint32) { c.chatController.responder.LogError(err, wc) return } - err = json.Unmarshal(jsonMessage, msg) + err = easyjson.Unmarshal(jsonMessage, msg) if err != nil { c.chatController.responder.LogError(err, wc) return @@ -40,7 +40,7 @@ func (c *Client) Write() { defer c.Socket.Close() for msg := range c.Receive { msg.CreatedAt = time.Now() - jsonForSend, err := json.Marshal(msg) + jsonForSend, err := easyjson.Marshal(msg) if err != nil { c.chatController.responder.LogError(err, wc) return diff --git a/internal/community/controller/controller.go b/internal/community/controller/controller.go index 6609aad6..c4a3014f 100644 --- a/internal/community/controller/controller.go +++ b/internal/community/controller/controller.go @@ -9,6 +9,7 @@ import ( "strconv" "github.com/gorilla/mux" + "github.com/mailru/easyjson" "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/internal/models" @@ -359,7 +360,7 @@ func (c *Controller) SearchCommunity(w http.ResponseWriter, r *http.Request) { func (c *Controller) getCommunityFromBody(r *http.Request) (models.Community, error) { var res models.Community - err := json.NewDecoder(r.Body).Decode(&res) + err := easyjson.UnmarshalFromReader(r.Body, &res) if err != nil { return models.Community{}, err } diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index a49a29e7..b3fadedf 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -2,7 +2,6 @@ package controller import ( "context" - "encoding/json" "errors" "fmt" "math" @@ -12,6 +11,7 @@ import ( "time" "github.com/gorilla/mux" + "github.com/mailru/easyjson" "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/internal/models" @@ -324,7 +324,7 @@ func (pc *PostController) GetBatchPosts(w http.ResponseWriter, r *http.Request) func (pc *PostController) getPostFromBody(r *http.Request) (*models.PostDto, error) { var newPost models.Post - err := json.NewDecoder(r.Body).Decode(&newPost) + err := easyjson.UnmarshalFromReader(r.Body, &newPost) if err != nil { return nil, err } @@ -497,7 +497,7 @@ func (pc *PostController) Comment(w http.ResponseWriter, r *http.Request) { } var content models.Content - if err := json.NewDecoder(r.Body).Decode(&content); err != nil { + if err := easyjson.UnmarshalFromReader(r.Body, &content); err != nil { pc.responder.ErrorBadRequest(w, err, reqID) return } @@ -574,7 +574,7 @@ func (pc *PostController) EditComment(w http.ResponseWriter, r *http.Request) { } var content models.Content - if err := json.NewDecoder(r.Body).Decode(&content); err != nil { + if err := easyjson.UnmarshalFromReader(r.Body, &content); err != nil { pc.responder.ErrorBadRequest(w, err, reqID) return } diff --git a/internal/profile/controller/controller.go b/internal/profile/controller/controller.go index 19259217..d766dc52 100644 --- a/internal/profile/controller/controller.go +++ b/internal/profile/controller/controller.go @@ -1,7 +1,6 @@ package controller import ( - "encoding/json" "errors" "fmt" "math" @@ -9,6 +8,7 @@ import ( "strconv" "github.com/gorilla/mux" + "github.com/mailru/easyjson" "golang.org/x/crypto/bcrypt" "github.com/2024_2_BetterCallFirewall/internal/middleware" @@ -124,7 +124,7 @@ func (h *ProfileHandlerImplementation) UpdateProfile(w http.ResponseWriter, r *h func (h *ProfileHandlerImplementation) getNewProfile(r *http.Request) (*models.FullProfile, error) { newProfile := models.FullProfile{} - err := json.NewDecoder(r.Body).Decode(&newProfile) + err := easyjson.UnmarshalFromReader(r.Body, &newProfile) if err != nil { return nil, err } @@ -547,7 +547,7 @@ func (h *ProfileHandlerImplementation) ChangePassword(w http.ResponseWriter, r * } var request models.ChangePasswordReq - if err := json.NewDecoder(r.Body).Decode(&request); err != nil { + if err := easyjson.UnmarshalFromReader(r.Body, &request); err != nil { h.Responder.ErrorBadRequest(w, err, reqID) return } diff --git a/internal/router/responder.go b/internal/router/responder.go index fb7dab96..8e69de91 100644 --- a/internal/router/responder.go +++ b/internal/router/responder.go @@ -6,6 +6,7 @@ import ( "errors" "net/http" + "github.com/mailru/easyjson" log "github.com/sirupsen/logrus" "github.com/2024_2_BetterCallFirewall/pkg/my_err" @@ -22,12 +23,14 @@ func fullUnwrap(err error) error { return last } +//esyjson:json type Response struct { Success bool `json:"success"` Data any `json:"data,omitempty"` Message string `json:"message,omitempty"` } +//easyjson:skip type Respond struct { logger *log.Logger } @@ -47,7 +50,8 @@ func (r *Respond) OutputJSON(w http.ResponseWriter, data any, requestID string) w.WriteHeader(http.StatusOK) r.logger.Infof("req: %s: success request", requestID) - if err := json.NewEncoder(w).Encode(&Response{Success: true, Data: data}); err != nil { + + if _, err := easyjson.MarshalToWriter(&Response{Success: true, Data: data}, w); err != nil { r.logger.Error(err) } } diff --git a/internal/router/responder_easyjson.go b/internal/router/responder_easyjson.go new file mode 100644 index 00000000..2c504463 --- /dev/null +++ b/internal/router/responder_easyjson.go @@ -0,0 +1,111 @@ +// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. + +package router + +import ( + json "encoding/json" + easyjson "github.com/mailru/easyjson" + jlexer "github.com/mailru/easyjson/jlexer" + jwriter "github.com/mailru/easyjson/jwriter" +) + +// suppress unused package warning +var ( + _ *json.RawMessage + _ *jlexer.Lexer + _ *jwriter.Writer + _ easyjson.Marshaler +) + +func easyjson7e1c2d3cDecodeGithubCom20242BetterCallFirewallInternalRouter(in *jlexer.Lexer, out *Response) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "success": + out.Success = bool(in.Bool()) + case "data": + if m, ok := out.Data.(easyjson.Unmarshaler); ok { + m.UnmarshalEasyJSON(in) + } else if m, ok := out.Data.(json.Unmarshaler); ok { + _ = m.UnmarshalJSON(in.Raw()) + } else { + out.Data = in.Interface() + } + case "message": + out.Message = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson7e1c2d3cEncodeGithubCom20242BetterCallFirewallInternalRouter(out *jwriter.Writer, in Response) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"success\":" + out.RawString(prefix[1:]) + out.Bool(bool(in.Success)) + } + if in.Data != nil { + const prefix string = ",\"data\":" + out.RawString(prefix) + if m, ok := in.Data.(easyjson.Marshaler); ok { + m.MarshalEasyJSON(out) + } else if m, ok := in.Data.(json.Marshaler); ok { + out.Raw(m.MarshalJSON()) + } else { + out.Raw(json.Marshal(in.Data)) + } + } + if in.Message != "" { + const prefix string = ",\"message\":" + out.RawString(prefix) + out.String(string(in.Message)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v Response) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson7e1c2d3cEncodeGithubCom20242BetterCallFirewallInternalRouter(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Response) MarshalEasyJSON(w *jwriter.Writer) { + easyjson7e1c2d3cEncodeGithubCom20242BetterCallFirewallInternalRouter(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *Response) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson7e1c2d3cDecodeGithubCom20242BetterCallFirewallInternalRouter(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Response) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson7e1c2d3cDecodeGithubCom20242BetterCallFirewallInternalRouter(l, v) +} From eae3084f8909dc71c218483cdc7354e3ff9b61d7 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sun, 15 Dec 2024 12:20:20 +0300 Subject: [PATCH 099/135] add test --- internal/app/stickers/app.go | 9 +++++---- internal/app/stickers/app_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 internal/app/stickers/app_test.go diff --git a/internal/app/stickers/app.go b/internal/app/stickers/app.go index edcf9334..7ff111cd 100644 --- a/internal/app/stickers/app.go +++ b/internal/app/stickers/app.go @@ -11,9 +11,9 @@ import ( "github.com/2024_2_BetterCallFirewall/internal/ext_grpc/adapter/auth" "github.com/2024_2_BetterCallFirewall/internal/router" "github.com/2024_2_BetterCallFirewall/internal/router/stickers" - controller "github.com/2024_2_BetterCallFirewall/internal/stickers/controller" - repository "github.com/2024_2_BetterCallFirewall/internal/stickers/repository" - service "github.com/2024_2_BetterCallFirewall/internal/stickers/service" + "github.com/2024_2_BetterCallFirewall/internal/stickers/controller" + "github.com/2024_2_BetterCallFirewall/internal/stickers/repository" + "github.com/2024_2_BetterCallFirewall/internal/stickers/service" "github.com/2024_2_BetterCallFirewall/pkg/start_postgres" ) @@ -26,7 +26,8 @@ func GetHTTPServer(cfg *config.Config) (*http.Server, error) { ForceColors: true, } - connStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s", + connStr := fmt.Sprintf( + "host=%s port=%s user=%s password=%s dbname=%s sslmode=%s", cfg.DB.Host, cfg.DB.Port, cfg.DB.User, diff --git a/internal/app/stickers/app_test.go b/internal/app/stickers/app_test.go new file mode 100644 index 00000000..35751bec --- /dev/null +++ b/internal/app/stickers/app_test.go @@ -0,0 +1,26 @@ +package stickers + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/2024_2_BetterCallFirewall/internal/config" +) + +func TestGetServer(t *testing.T) { + server, err := GetHTTPServer( + &config.Config{ + DB: config.DBConnect{ + Port: "test", + Host: "test", + DBName: "test", + User: "test", + Pass: "test", + SSLMode: "test", + }, + }, + ) + assert.NoError(t, err) + assert.NotNil(t, server) +} From 222335f403f7bcfa9a69de7471badb869b8ccff7 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sun, 15 Dec 2024 13:00:13 +0300 Subject: [PATCH 100/135] add test for chat modek --- internal/models/chat_test.go | 69 ++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/internal/models/chat_test.go b/internal/models/chat_test.go index ce068669..83014fc7 100644 --- a/internal/models/chat_test.go +++ b/internal/models/chat_test.go @@ -1,8 +1,11 @@ package models import ( + "encoding/json" "testing" + "time" + "github.com/mailru/easyjson" "github.com/stretchr/testify/assert" ) @@ -85,3 +88,69 @@ func TestMessageToDto(t *testing.T) { assert.Equal(t, test.messageDto, res) } } + +func TestMarshal(t *testing.T) { + createTime := time.Time{} + m := &Message{ + Content: MessageContent{Text: "new message", FilePath: []string{"image"}}, Sender: 1, Receiver: 2, + CreatedAt: createTime, + } + + want := []byte(`{"sender":1,"receiver":2,"content":{"text":"new message","file_path":["image"],"sticker_path":""},"created_at":"0001-01-01T00:00:00Z"}`) + res, err := easyjson.Marshal(m) + assert.NoError(t, err) + assert.Equal(t, string(want), string(res)) + + res, err = json.Marshal(m) + assert.NoError(t, err) + assert.Equal(t, string(want), string(res)) + +} + +func TestUnmarshal(t *testing.T) { + sl := []byte(`{"sender":1,"receiver":2,"content":{"text":"new message","file_path":["image"],"sticker_path":""},"created_at":"0001-01-01T00:00:00Z"}`) + m := &Message{} + err := easyjson.Unmarshal(sl, m) + assert.NoError(t, err) + createTime := time.Time{} + want := &Message{ + Content: MessageContent{Text: "new message", FilePath: []string{"image"}}, Sender: 1, Receiver: 2, + CreatedAt: createTime, + } + + assert.Equal(t, want, m) +} + +func TestMarshalChat(t *testing.T) { + c := &Chat{ + LastMessage: "message", + LastDate: time.Time{}, + Receiver: Header{ + Author: "Andrew Savvateev", + }, + } + want := []byte(`{"last_message":"message","last_date":"0001-01-01T00:00:00Z","receiver":{"author_id":0,"community_id":0,"author":"Andrew Savvateev","avatar":""}}`) + res, err := easyjson.Marshal(c) + assert.NoError(t, err) + assert.Equal(t, string(want), string(res)) + + res, err = json.Marshal(c) + assert.NoError(t, err) + assert.Equal(t, string(want), string(res)) +} + +func TestUnmarshalChat(t *testing.T) { + sl := []byte(`{"last_message":"message","last_date":"0001-01-01T00:00:00Z","receiver":{"author_id":0,"community_id":0,"author":"Andrew Savvateev","avatar":""}}`) + c := &Chat{} + err := easyjson.Unmarshal(sl, c) + assert.NoError(t, err) + want := &Chat{ + LastMessage: "message", + LastDate: time.Time{}, + Receiver: Header{ + Author: "Andrew Savvateev", + }, + } + + assert.Equal(t, want, c) +} From 2bb90a793477673ba1c3c6e04d3a34c33663f66a Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sun, 15 Dec 2024 13:05:28 +0300 Subject: [PATCH 101/135] add test for content model --- internal/models/content_test.go | 40 +++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/internal/models/content_test.go b/internal/models/content_test.go index a742b153..57eeb97a 100644 --- a/internal/models/content_test.go +++ b/internal/models/content_test.go @@ -1,8 +1,11 @@ package models import ( + "encoding/json" "testing" + "time" + "github.com/mailru/easyjson" "github.com/stretchr/testify/assert" ) @@ -49,3 +52,40 @@ func TestToDto(t *testing.T) { assert.Equal(t, test.contentDto, res) } } + +func TestMarshalJson(t *testing.T) { + c := &Content{ + Text: "comment", + File: []Picture{Picture("image")}, + CreatedAt: time.Time{}, + UpdatedAt: time.Time{}, + } + want := []byte(`{"text":"comment","file":["image"],"created_at":"0001-01-01T00:00:00Z","updated_at":"0001-01-01T00:00:00Z"}`) + + res, err := easyjson.Marshal(c) + assert.NoError(t, err) + assert.Equal(t, want, res) + + res, err = json.Marshal(c) + assert.NoError(t, err) + assert.Equal(t, want, res) +} + +func TestUnmarshallJson(t *testing.T) { + sl := []byte(`{"text":"comment","file":["image"],"created_at":"0001-01-01T00:00:00Z","updated_at":"0001-01-01T00:00:00Z"}`) + c := &Content{} + want := &Content{ + Text: "comment", + File: []Picture{Picture("image")}, + CreatedAt: time.Time{}, + UpdatedAt: time.Time{}, + } + + err := easyjson.Unmarshal(sl, c) + assert.NoError(t, err) + assert.Equal(t, want, c) + + err = json.Unmarshal(sl, want) + assert.NoError(t, err) + assert.Equal(t, want, c) +} From 7c948840e9833431a0ff498b4edcd757876854fd Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sun, 15 Dec 2024 13:14:34 +0300 Subject: [PATCH 102/135] add test for post model --- internal/models/chat_test.go | 8 ++- internal/models/post_test.go | 123 +++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+), 2 deletions(-) diff --git a/internal/models/chat_test.go b/internal/models/chat_test.go index 83014fc7..e4c9d96a 100644 --- a/internal/models/chat_test.go +++ b/internal/models/chat_test.go @@ -142,8 +142,6 @@ func TestMarshalChat(t *testing.T) { func TestUnmarshalChat(t *testing.T) { sl := []byte(`{"last_message":"message","last_date":"0001-01-01T00:00:00Z","receiver":{"author_id":0,"community_id":0,"author":"Andrew Savvateev","avatar":""}}`) c := &Chat{} - err := easyjson.Unmarshal(sl, c) - assert.NoError(t, err) want := &Chat{ LastMessage: "message", LastDate: time.Time{}, @@ -152,5 +150,11 @@ func TestUnmarshalChat(t *testing.T) { }, } + err := easyjson.Unmarshal(sl, c) + assert.NoError(t, err) + assert.Equal(t, want, c) + + err = json.Unmarshal(sl, c) + assert.NoError(t, err) assert.Equal(t, want, c) } diff --git a/internal/models/post_test.go b/internal/models/post_test.go index 50713e42..62f6b9e3 100644 --- a/internal/models/post_test.go +++ b/internal/models/post_test.go @@ -1,8 +1,11 @@ package models import ( + "encoding/json" "testing" + "time" + "github.com/mailru/easyjson" "github.com/stretchr/testify/assert" ) @@ -87,3 +90,123 @@ func TestCommentToDto(t *testing.T) { assert.Equal(t, test.commentDto, res) } } + +func TestMarshalPost(t *testing.T) { + p := &Post{ + ID: 1, + Header: Header{ + AuthorID: 10, + CommunityID: 0, + Author: "Alexey", + Avatar: "/image", + }, + PostContent: Content{ + Text: "text", + File: []Picture{"image"}, + CreatedAt: time.Time{}, + UpdatedAt: time.Time{}, + }, + LikesCount: 1, + IsLiked: true, + CommentCount: 10, + } + want := []byte(`{"id":1,"header":{"author_id":10,"community_id":0,"author":"Alexey","avatar":"/image"},"post_content":{"text":"text","file":["image"],"created_at":"0001-01-01T00:00:00Z","updated_at":"0001-01-01T00:00:00Z"},"likes_count":1,"is_liked":true,"comment_count":10}`) + + res, err := easyjson.Marshal(p) + assert.NoError(t, err) + assert.Equal(t, want, res) + + res, err = json.Marshal(p) + assert.NoError(t, err) + assert.Equal(t, want, res) +} + +func TestUnmarshallPost(t *testing.T) { + want := &Post{ + ID: 1, + Header: Header{ + AuthorID: 10, + CommunityID: 0, + Author: "Alexey", + Avatar: "/image", + }, + PostContent: Content{ + Text: "text", + File: []Picture{"image"}, + CreatedAt: time.Time{}, + UpdatedAt: time.Time{}, + }, + LikesCount: 1, + IsLiked: true, + CommentCount: 10, + } + sl := []byte(`{"id":1,"header":{"author_id":10,"community_id":0,"author":"Alexey","avatar":"/image"},"post_content":{"text":"text","file":["image"],"created_at":"0001-01-01T00:00:00Z","updated_at":"0001-01-01T00:00:00Z"},"likes_count":1,"is_liked":true,"comment_count":10}`) + p := &Post{} + + err := easyjson.Unmarshal(sl, p) + assert.NoError(t, err) + assert.Equal(t, want, p) + + err = json.Unmarshal(sl, p) + assert.NoError(t, err) + assert.Equal(t, want, p) +} + +func TestMarshallComment(t *testing.T) { + c := &Comment{ + ID: 10, + Header: Header{ + AuthorID: 10, + CommunityID: 0, + Author: "Alexey", + Avatar: "/image", + }, + Content: Content{ + Text: "comment", + File: nil, + CreatedAt: time.Time{}, + UpdatedAt: time.Time{}, + }, + LikesCount: 0, + IsLiked: false, + } + want := []byte(`{"id":10,"header":{"author_id":10,"community_id":0,"author":"Alexey","avatar":"/image"},"content":{"text":"comment","created_at":"0001-01-01T00:00:00Z","updated_at":"0001-01-01T00:00:00Z"},"likes_count":0,"is_liked":false}`) + + res, err := easyjson.Marshal(c) + assert.NoError(t, err) + assert.Equal(t, res, want) + + res, err = json.Marshal(c) + assert.NoError(t, err) + assert.Equal(t, want, res) +} + +func TestUnmarshallComment(t *testing.T) { + want := &Comment{ + ID: 10, + Header: Header{ + AuthorID: 10, + CommunityID: 0, + Author: "Alexey", + Avatar: "/image", + }, + Content: Content{ + Text: "comment", + File: nil, + CreatedAt: time.Time{}, + UpdatedAt: time.Time{}, + }, + LikesCount: 0, + IsLiked: false, + } + sl := []byte(`{"id":10,"header":{"author_id":10,"community_id":0,"author":"Alexey","avatar":"/image"},"content":{"text":"comment","created_at":"0001-01-01T00:00:00Z","updated_at":"0001-01-01T00:00:00Z"},"likes_count":0,"is_liked":false}`) + c := &Comment{} + + err := easyjson.Unmarshal(sl, c) + assert.NoError(t, err) + assert.Equal(t, want, c) + + err = json.Unmarshal(sl, c) + assert.NoError(t, err) + assert.Equal(t, want, c) +} From 0f92e27ad051168eb7f38ad3ba956d13f9a55720 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sun, 15 Dec 2024 13:38:27 +0300 Subject: [PATCH 103/135] add test for repository --- internal/post/repository/postgres/postgres.go | 7 +- .../post/repository/postgres/postgres_test.go | 160 ++++++++++++++++++ 2 files changed, 165 insertions(+), 2 deletions(-) diff --git a/internal/post/repository/postgres/postgres.go b/internal/post/repository/postgres/postgres.go index 3a0bbaa5..438ef549 100644 --- a/internal/post/repository/postgres/postgres.go +++ b/internal/post/repository/postgres/postgres.go @@ -250,15 +250,18 @@ func (a *Adapter) CreateCommunityPost(ctx context.Context, post *models.PostDto, } return ID, nil - } func (a *Adapter) GetCommunityPosts(ctx context.Context, communityID, id uint32) ([]*models.PostDto, error) { var posts []*models.PostDto rows, err := a.db.QueryContext(ctx, getCommunityPosts, communityID, id) if err != nil { - return nil, fmt.Errorf("postgres get community posts: %w", err) + if errors.Is(err, sql.ErrNoRows) { + return nil, my_err.ErrNoMoreContent + } + return nil, fmt.Errorf("postgres get posts: %w", err) } + defer rows.Close() for rows.Next() { post := &models.PostDto{} diff --git a/internal/post/repository/postgres/postgres_test.go b/internal/post/repository/postgres/postgres_test.go index 7413f96a..c58f0832 100644 --- a/internal/post/repository/postgres/postgres_test.go +++ b/internal/post/repository/postgres/postgres_test.go @@ -543,3 +543,163 @@ func TestGetFriendsPosts(t *testing.T) { assert.Equalf(t, posts, test.wantPost, "result dont match\nwant: %v\ngot:%v", test.wantPost, posts) } } + +type TestCaseCreateCommunity struct { + post *models.PostDto + communityID uint32 + wantID uint32 + wantErr error + dbErr error +} + +func TestCreateCommunityPost(t *testing.T) { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) + } + defer db.Close() + + repo := NewAdapter(db) + + tests := []TestCaseCreateCommunity{ + { + communityID: 1, + post: &models.PostDto{ + Header: models.Header{AuthorID: 1}, PostContent: models.ContentDto{Text: "content from user 1"}, + }, wantID: 1, wantErr: nil, dbErr: nil, + }, + { + communityID: 2, + post: &models.PostDto{ + Header: models.Header{AuthorID: 2}, + PostContent: models.ContentDto{Text: "content from user 2", File: "http://someFile"}, + }, wantID: 2, wantErr: nil, dbErr: nil, + }, + { + communityID: 3, + post: &models.PostDto{ + Header: models.Header{AuthorID: 10}, PostContent: models.ContentDto{Text: "wrong query"}, + }, wantID: 0, wantErr: errMockDB, dbErr: errMockDB, + }, + } + + for _, test := range tests { + mock.ExpectQuery(regexp.QuoteMeta(createCommunityPost)). + WithArgs(test.communityID, test.post.PostContent.Text, test.post.PostContent.File). + WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(test.wantID)). + WillReturnError(test.dbErr) + + id, err := repo.CreateCommunityPost(context.Background(), test.post, test.communityID) + if id != test.wantID { + t.Errorf("results not match,\n want %v\n have %v", test.wantID, id) + } + if !errors.Is(err, test.wantErr) { + t.Errorf("unexpected err:\n want:%v\n got:%v", test.wantErr, err) + } + } +} + +type TestCaseGetCommunityPost struct { + communityID uint32 + lastID uint32 + wantPost []*models.PostDto + dbErr error + wantErr error +} + +func TestCommunityPost(t *testing.T) { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) + } + defer db.Close() + + createTime := time.Now() + expect := []*models.PostDto{ + { + ID: 1, Header: models.Header{CommunityID: 1}, + PostContent: models.ContentDto{Text: "content from user 1", CreatedAt: createTime}, + }, + { + ID: 2, Header: models.Header{CommunityID: 1}, + PostContent: models.ContentDto{Text: "content from user 1", CreatedAt: createTime}, + }, + { + ID: 3, Header: models.Header{CommunityID: 2}, + PostContent: models.ContentDto{Text: "content from user 2", CreatedAt: createTime}, + }, + { + ID: 4, Header: models.Header{CommunityID: 2}, + PostContent: models.ContentDto{Text: "content from user 2", CreatedAt: createTime}, + }, + { + ID: 5, Header: models.Header{CommunityID: 3}, + PostContent: models.ContentDto{Text: "content from user 3", CreatedAt: createTime}, + }, + { + ID: 6, Header: models.Header{CommunityID: 3}, + PostContent: models.ContentDto{Text: "content from user 3", CreatedAt: createTime}, + }, + { + ID: 7, Header: models.Header{CommunityID: 6}, + PostContent: models.ContentDto{Text: "content from user 6", CreatedAt: createTime}, + }, + { + ID: 8, Header: models.Header{CommunityID: 4}, + PostContent: models.ContentDto{Text: "content from user 4", CreatedAt: createTime}, + }, + { + ID: 9, Header: models.Header{CommunityID: 2}, + PostContent: models.ContentDto{Text: "content from user 2", CreatedAt: createTime}, + }, + { + ID: 10, Header: models.Header{CommunityID: 1}, + PostContent: models.ContentDto{Text: "content from user 1", CreatedAt: createTime}, + }, + { + ID: 11, Header: models.Header{CommunityID: 2}, + PostContent: models.ContentDto{Text: "content from user 2", CreatedAt: createTime}, + }, + } + + repo := NewAdapter(db) + + tests := []TestCaseGetCommunityPost{ + {lastID: 0, wantPost: nil, wantErr: my_err.ErrNoMoreContent, dbErr: sql.ErrNoRows}, + {lastID: 1, wantPost: nil, wantErr: errMockDB, dbErr: errMockDB}, + { + lastID: 3, + communityID: 1, + wantPost: expect[:3], + wantErr: nil, + dbErr: nil, + }, + { + lastID: 11, + wantPost: expect[1:11], + communityID: 10, + wantErr: nil, + dbErr: nil, + }, + } + + for _, test := range tests { + rows := sqlmock.NewRows([]string{"id", "community_id", "content", "file_path", "created_at"}) + for _, post := range test.wantPost { + rows.AddRow( + post.ID, post.Header.CommunityID, post.PostContent.Text, post.PostContent.File, + post.PostContent.CreatedAt, + ) + } + mock.ExpectQuery(regexp.QuoteMeta(getCommunityPosts)). + WithArgs(test.communityID, test.lastID). + WillReturnRows(rows). + WillReturnError(test.dbErr) + + posts, err := repo.GetCommunityPosts(context.Background(), test.communityID, test.lastID) + if !errors.Is(err, test.wantErr) { + t.Errorf("unexpected error: got:%v\nwant:%v\n", err, test.wantErr) + } + assert.Equalf(t, posts, test.wantPost, "result dont match\nwant: %v\ngot:%v", test.wantPost, posts) + } +} From 3632103ebf272f9964bcb21acf2e4541377c21bd Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sun, 15 Dec 2024 16:48:42 +0300 Subject: [PATCH 104/135] add name for file --- internal/fileService/controller/controller.go | 10 +++++++--- internal/fileService/controller/mock.go | 8 ++++---- internal/fileService/service/fileService.go | 6 ++++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index a6b87b1b..516ae21f 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -26,7 +26,7 @@ var fileFormat = map[string]struct{}{ type fileService interface { Upload(ctx context.Context, name string) ([]byte, error) Download(ctx context.Context, file multipart.File, format string) (string, error) - DownloadNonImage(ctx context.Context, file multipart.File, format string) (string, error) + DownloadNonImage(ctx context.Context, file multipart.File, format, realName string) (string, error) UploadNonImage(ctx context.Context, name string) ([]byte, error) } @@ -142,8 +142,12 @@ func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { if _, ok := fileFormat[format]; ok { url, err = fc.fileService.Download(r.Context(), file, format) } else { - - url, err = fc.fileService.DownloadNonImage(r.Context(), file, format) + name := header.Filename + if len(name+format) > 55 { + fc.responder.ErrorBadRequest(w, errors.New("file name is too big"), reqID) + return + } + url, err = fc.fileService.DownloadNonImage(r.Context(), file, format, name) } if err != nil { diff --git a/internal/fileService/controller/mock.go b/internal/fileService/controller/mock.go index ff73012b..816a55a1 100644 --- a/internal/fileService/controller/mock.go +++ b/internal/fileService/controller/mock.go @@ -58,18 +58,18 @@ func (mr *MockfileServiceMockRecorder) Download(ctx, file, format any) *gomock.C } // DownloadNonImage mocks base method. -func (m *MockfileService) DownloadNonImage(ctx context.Context, file multipart.File, format string) (string, error) { +func (m *MockfileService) DownloadNonImage(ctx context.Context, file multipart.File, format, realName string) (string, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DownloadNonImage", ctx, file, format) + ret := m.ctrl.Call(m, "DownloadNonImage", ctx, file, format, realName) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } // DownloadNonImage indicates an expected call of DownloadNonImage. -func (mr *MockfileServiceMockRecorder) DownloadNonImage(ctx, file, format any) *gomock.Call { +func (mr *MockfileServiceMockRecorder) DownloadNonImage(ctx, file, format, realName any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadNonImage", reflect.TypeOf((*MockfileService)(nil).DownloadNonImage), ctx, file, format) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadNonImage", reflect.TypeOf((*MockfileService)(nil).DownloadNonImage), ctx, file, format, realName) } // Upload mocks base method. diff --git a/internal/fileService/service/fileService.go b/internal/fileService/service/fileService.go index 2b26d7d8..b2eb0cc3 100644 --- a/internal/fileService/service/fileService.go +++ b/internal/fileService/service/fileService.go @@ -37,10 +37,12 @@ func (f *FileService) Download(ctx context.Context, file multipart.File, format return filePath, nil } -func (f *FileService) DownloadNonImage(ctx context.Context, file multipart.File, format string) (string, error) { +func (f *FileService) DownloadNonImage( + ctx context.Context, file multipart.File, format, realName string, +) (string, error) { var ( fileName = uuid.New().String() - filePath = fmt.Sprintf("/files/%s.%s", fileName, format) + filePath = fmt.Sprintf("/files/%s|%s.%s", fileName, realName, format) dst, err = os.Create(filePath) ) defer func(dst *os.File) { From 15bc054e930d98a532cc5e77ac8c1c8c54173981 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Mon, 16 Dec 2024 10:05:44 +0300 Subject: [PATCH 105/135] fix typo in stickers --- cmd/stickers/main.go | 2 +- internal/app/stickers/app.go | 6 +++--- internal/config/config.go | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/stickers/main.go b/cmd/stickers/main.go index 45e748d3..2596a54a 100644 --- a/cmd/stickers/main.go +++ b/cmd/stickers/main.go @@ -22,7 +22,7 @@ func main() { panic(err) } - log.Printf("Starting server on port %s", cfg.STCIKER.Port) + log.Printf("Starting server on port %s", cfg.STICKER.Port) if err := server.ListenAndServe(); err != nil { panic(err) } diff --git a/internal/app/stickers/app.go b/internal/app/stickers/app.go index 7ff111cd..f3e47550 100644 --- a/internal/app/stickers/app.go +++ b/internal/app/stickers/app.go @@ -55,9 +55,9 @@ func GetHTTPServer(cfg *config.Config) (*http.Server, error) { rout := stickers.NewRouter(stickerController, sm, logger) server := &http.Server{ Handler: rout, - Addr: fmt.Sprintf(":%s", cfg.STCIKER.Port), - ReadTimeout: cfg.STCIKER.ReadTimeout, - WriteTimeout: cfg.STCIKER.WriteTimeout, + Addr: fmt.Sprintf(":%s", cfg.STICKER.Port), + ReadTimeout: cfg.STICKER.ReadTimeout, + WriteTimeout: cfg.STICKER.WriteTimeout, } return server, nil diff --git a/internal/config/config.go b/internal/config/config.go index 798a156b..93f5bfc5 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -45,7 +45,7 @@ type Config struct { POST Server PROFILE Server COMMUNITY Server - STCIKER Server + STICKER Server AUTHGRPC GRPCServer PROFILEGRPC GRPCServer POSTGRPC GRPCServer @@ -102,8 +102,8 @@ func GetConfig(configFilePath string) (*Config, error) { ReadTimeout: time.Duration(getIntEnv("SERVER_READ_TIMEOUT")) * time.Second, WriteTimeout: time.Duration(getIntEnv("SERVER_WRITE_TIMEOUT")) * time.Second, }, - STCIKER: Server{ - Port: os.Getenv("STCIKER_HTTP_PORT"), + STICKER: Server{ + Port: os.Getenv("STICKER_HTTP_PORT"), ReadTimeout: time.Duration(getIntEnv("SERVER_READ_TIMEOUT")) * time.Second, WriteTimeout: time.Duration(getIntEnv("SERVER_WRITE_TIMEOUT")) * time.Second, }, From c03b414494313e396c5584d6d582e75509e5fe7e Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Mon, 16 Dec 2024 10:38:16 +0300 Subject: [PATCH 106/135] fix validate --- DB/migrations/000001_init_schema.up.sql | 2 +- internal/auth/controller/controller.go | 2 +- internal/chat/controller/controller.go | 2 +- internal/community/controller/controller.go | 2 +- internal/post/controller/controller.go | 4 ++-- internal/profile/controller/controller.go | 8 ++++---- internal/stickers/controller/controller.go | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/DB/migrations/000001_init_schema.up.sql b/DB/migrations/000001_init_schema.up.sql index c2234c54..82633c2a 100644 --- a/DB/migrations/000001_init_schema.up.sql +++ b/DB/migrations/000001_init_schema.up.sql @@ -46,7 +46,7 @@ CREATE TABLE IF NOT EXISTS post ( id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, author_id INT REFERENCES profile(id) ON DELETE CASCADE, community_id INT REFERENCES community(id) ON DELETE CASCADE DEFAULT NULL, - content TEXT CONSTRAINT content_post_length CHECK (CHAR_LENGTH(content) <= 500) DEFAULT '', + content TEXT CONSTRAINT content_post_length CHECK (CHAR_LENGTH(content) <= 1000) DEFAULT '', file_path TEXT CONSTRAINT file_path_length CHECK (CHAR_LENGTH(file_path) <= 1000) DEFAULT '', created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() diff --git a/internal/auth/controller/controller.go b/internal/auth/controller/controller.go index 81a2fc0e..3072610f 100644 --- a/internal/auth/controller/controller.go +++ b/internal/auth/controller/controller.go @@ -185,7 +185,7 @@ func (c *AuthController) Logout(w http.ResponseWriter, r *http.Request) { func validate(user models.User) bool { if len([]rune(user.FirstName)) < 3 || len([]rune(user.LastName)) < 3 || len([]rune(user.Password)) < 6 || - len(user.FirstName) > 30 || len(user.LastName) > 30 { + len([]rune(user.FirstName)) > 30 || len([]rune(user.LastName)) > 30 { return false } return true diff --git a/internal/chat/controller/controller.go b/internal/chat/controller/controller.go index 569c3d54..6a8c907a 100644 --- a/internal/chat/controller/controller.go +++ b/internal/chat/controller/controller.go @@ -91,7 +91,7 @@ func (cc *ChatController) SetConnection(w http.ResponseWriter, r *http.Request) } func validate(content models.MessageContent) bool { - if len(content.FilePath) > 10 || len(content.StickerPath) > 100 || len(content.Text) > 500 { + if len(content.FilePath) > 10 || len([]rune(content.StickerPath)) > 100 || len([]rune(content.Text)) > 500 { return false } if content.StickerPath != "" && (len(content.FilePath) > 0 || content.Text != "") { diff --git a/internal/community/controller/controller.go b/internal/community/controller/controller.go index c4a3014f..9548d42e 100644 --- a/internal/community/controller/controller.go +++ b/internal/community/controller/controller.go @@ -388,7 +388,7 @@ func getIDFromQuery(r *http.Request) (uint32, error) { } func validate(data models.Community) bool { - if len([]rune(data.Name)) < 3 || len(data.Name) >= 50 || len([]rune(data.About)) >= 60 { + if len([]rune(data.Name)) < 3 || len([]rune(data.Name)) >= 50 || len([]rune(data.About)) >= 60 { return false } diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index b3fadedf..ff80b228 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -653,7 +653,7 @@ func validateContent(content models.Content) bool { return false } - return validateFile(content.File) && len(content.Text) < 500 + return validateFile(content.File) && len([]rune(content.Text)) < 1000 } func validateFile(filepaths []models.Picture) bool { @@ -662,7 +662,7 @@ func validateFile(filepaths []models.Picture) bool { } for _, f := range filepaths { - if len(f) > 100 { + if len([]rune(f)) > 100 { return false } if !(strings.HasPrefix(string(f), filePrefix) || strings.HasPrefix(string(f), imagePrefix)) { diff --git a/internal/profile/controller/controller.go b/internal/profile/controller/controller.go index d766dc52..8f2b8f47 100644 --- a/internal/profile/controller/controller.go +++ b/internal/profile/controller/controller.go @@ -129,9 +129,9 @@ func (h *ProfileHandlerImplementation) getNewProfile(r *http.Request) (*models.F return nil, err } - if len([]rune(newProfile.FirstName)) < 3 || len(newProfile.FirstName) > 30 || - len([]rune(newProfile.LastName)) < 3 || len(newProfile.LastName) > 30 || - len(newProfile.Bio) > 100 || len(newProfile.Avatar) > 100 { + if len([]rune(newProfile.FirstName)) < 3 || len([]rune(newProfile.FirstName)) > 30 || + len([]rune(newProfile.LastName)) < 3 || len([]rune(newProfile.LastName)) > 30 || + len(newProfile.Bio) > 100 || len([]rune(newProfile.Avatar)) > 100 { return nil, errors.New("invalid profile") } @@ -574,7 +574,7 @@ func (h *ProfileHandlerImplementation) ChangePassword(w http.ResponseWriter, r * } func validate(request models.ChangePasswordReq) bool { - if len(request.OldPassword) < 6 || len(request.NewPassword) < 6 || request.OldPassword == request.NewPassword { + if len([]rune(request.OldPassword)) < 6 || len([]rune(request.NewPassword)) < 6 || request.OldPassword == request.NewPassword { return false } diff --git a/internal/stickers/controller/controller.go b/internal/stickers/controller/controller.go index e00c8fdd..fb476ee7 100644 --- a/internal/stickers/controller/controller.go +++ b/internal/stickers/controller/controller.go @@ -117,5 +117,5 @@ func (s StickersHandlerImplementation) GetMineStickers(w http.ResponseWriter, r } func validate(filepath string) bool { - return len(filepath) < 100 && strings.HasPrefix(filepath, imagePrefix) + return len([]rune(filepath)) < 100 && strings.HasPrefix(filepath, imagePrefix) } From fd4a29d6ec303b2e3cc3081296c8197a6d093533 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Mon, 16 Dec 2024 10:44:20 +0300 Subject: [PATCH 107/135] fix post test --- internal/post/controller/controller_test.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/internal/post/controller/controller_test.go b/internal/post/controller/controller_test.go index 4efe3cec..edcf1c93 100644 --- a/internal/post/controller/controller_test.go +++ b/internal/post/controller/controller_test.go @@ -308,7 +308,9 @@ func TestCreate(t *testing.T) { SetupInput: func() (*Request, error) { req := httptest.NewRequest( http.MethodPost, "/api/v1/feed?community=10", - bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`)), + bytes.NewBuffer( + []byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. wiukyjctg"}}`), + ), ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -1034,7 +1036,9 @@ func TestUpdate(t *testing.T) { SetupInput: func() (*Request, error) { req := httptest.NewRequest( http.MethodPut, "/api/v1/feed/10?community=1", - bytes.NewBuffer([]byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`)), + bytes.NewBuffer( + []byte(`{"post_content":{"text":"new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. new post Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus arcu, vulputate rutrum enim vitae, tincidunt imperdiet tellus. Aenean vulputate elit consequat lorem pellentesque bibendum. Donec sed mi posuere dolor semper mollis eu eget dolor. Proin et eleifend magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur tempus ultricies mi, eget malesuada metus. Nam sit amet felis nec dolor vehicula dapibus gravida in nunc. Mauris turpis et. "}}`), + ), ) w := httptest.NewRecorder() req = mux.SetURLVars(req, map[string]string{"id": "10"}) From d9121173524c734b9cd406512a7718d183ef99e4 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Mon, 16 Dec 2024 12:23:05 +0300 Subject: [PATCH 108/135] fix request sticker --- internal/models/sticker_request.go | 5 +++++ internal/stickers/controller/controller.go | 6 +++--- internal/stickers/controller/controller_test.go | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 internal/models/sticker_request.go diff --git a/internal/models/sticker_request.go b/internal/models/sticker_request.go new file mode 100644 index 00000000..fe23396b --- /dev/null +++ b/internal/models/sticker_request.go @@ -0,0 +1,5 @@ +package models + +type StickerRequest struct { + File string `json:"file"` +} diff --git a/internal/stickers/controller/controller.go b/internal/stickers/controller/controller.go index fb476ee7..5f371fd7 100644 --- a/internal/stickers/controller/controller.go +++ b/internal/stickers/controller/controller.go @@ -43,14 +43,14 @@ func (s StickersHandlerImplementation) AddNewSticker(w http.ResponseWriter, r *h s.Responder.LogError(my_err.ErrInvalidContext, "") } - filePath := "" + filePath := models.StickerRequest{} if err := json.NewDecoder(r.Body).Decode(&filePath); err != nil { s.Responder.ErrorBadRequest(w, my_err.ErrNoFile, reqID) fmt.Println(err) return } - if !validate(filePath) { + if !validate(filePath.File) { s.Responder.ErrorBadRequest(w, my_err.ErrNoImage, reqID) return } @@ -61,7 +61,7 @@ func (s StickersHandlerImplementation) AddNewSticker(w http.ResponseWriter, r *h return } - err = s.StickersManager.AddNewSticker(r.Context(), filePath, sess.UserID) + err = s.StickersManager.AddNewSticker(r.Context(), filePath.File, sess.UserID) if err != nil { s.Responder.ErrorInternal(w, err, reqID) return diff --git a/internal/stickers/controller/controller_test.go b/internal/stickers/controller/controller_test.go index 987b2cbe..cbaaa68b 100644 --- a/internal/stickers/controller/controller_test.go +++ b/internal/stickers/controller/controller_test.go @@ -134,7 +134,7 @@ func TestAddNewSticker(t *testing.T) { name: "4", SetupInput: func() (*Request, error) { req := httptest.NewRequest( - http.MethodPost, "/api/v1/stickers", bytes.NewBuffer([]byte(`"/image/someimage"`)), + http.MethodPost, "/api/v1/stickers", bytes.NewBuffer([]byte(`{"file":"/image/someimage"}`)), ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) @@ -167,7 +167,7 @@ func TestAddNewSticker(t *testing.T) { name: "5", SetupInput: func() (*Request, error) { req := httptest.NewRequest( - http.MethodPost, "/api/v1/stickers", bytes.NewBuffer([]byte(`"/image/someimage"`)), + http.MethodPost, "/api/v1/stickers", bytes.NewBuffer([]byte(`{"file":"/image/someimage"}`)), ) w := httptest.NewRecorder() req = req.WithContext(models.ContextWithSession(req.Context(), &models.Session{ID: "1", UserID: 1})) From cfedc7cc983160f8c7d2fe561fab5ba90222d78e Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Mon, 16 Dec 2024 12:48:49 +0300 Subject: [PATCH 109/135] fix getting requestID --- internal/stickers/controller/controller.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/stickers/controller/controller.go b/internal/stickers/controller/controller.go index 5f371fd7..4e6f62ad 100644 --- a/internal/stickers/controller/controller.go +++ b/internal/stickers/controller/controller.go @@ -7,6 +7,7 @@ import ( "net/http" "strings" + "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/internal/stickers" "github.com/2024_2_BetterCallFirewall/pkg/my_err" @@ -37,7 +38,7 @@ func NewStickerController(manager stickers.Usecase, responder Responder) *Sticke } func (s StickersHandlerImplementation) AddNewSticker(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { s.Responder.LogError(my_err.ErrInvalidContext, "") @@ -71,7 +72,7 @@ func (s StickersHandlerImplementation) AddNewSticker(w http.ResponseWriter, r *h } func (s StickersHandlerImplementation) GetAllStickers(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { s.Responder.LogError(my_err.ErrInvalidContext, "") @@ -91,7 +92,7 @@ func (s StickersHandlerImplementation) GetAllStickers(w http.ResponseWriter, r * } func (s StickersHandlerImplementation) GetMineStickers(w http.ResponseWriter, r *http.Request) { - reqID, ok := r.Context().Value("requestID").(string) + reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { s.Responder.LogError(my_err.ErrInvalidContext, "") From 08bcb19ff3c3969f80e899e922b5e5c9663c96f1 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Tue, 17 Dec 2024 20:43:46 +0300 Subject: [PATCH 110/135] replace cookie to lax --- internal/auth/controller/controller.go | 3 +++ internal/middleware/auth.go | 6 +++-- internal/middleware/preflite.go | 30 ++++++++++++---------- internal/profile/repository/QueryConsts.go | 17 ++++++++++-- 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/internal/auth/controller/controller.go b/internal/auth/controller/controller.go index 3072610f..1b6a62ce 100644 --- a/internal/auth/controller/controller.go +++ b/internal/auth/controller/controller.go @@ -91,6 +91,7 @@ func (c *AuthController) Register(w http.ResponseWriter, r *http.Request) { Path: "/", HttpOnly: true, Secure: true, + SameSite: http.SameSiteLaxMode, Expires: time.Now().AddDate(0, 0, 1), } @@ -139,6 +140,7 @@ func (c *AuthController) Auth(w http.ResponseWriter, r *http.Request) { Path: "/", HttpOnly: true, Secure: true, + SameSite: http.SameSiteLaxMode, Expires: time.Now().AddDate(0, 0, 1), } http.SetCookie(w, cookie) @@ -176,6 +178,7 @@ func (c *AuthController) Logout(w http.ResponseWriter, r *http.Request) { Path: "/", HttpOnly: true, Secure: true, + SameSite: http.SameSiteLaxMode, Expires: time.Now().AddDate(0, 0, -1), } http.SetCookie(w, cookie) diff --git a/internal/middleware/auth.go b/internal/middleware/auth.go index c3a2b060..148625de 100644 --- a/internal/middleware/auth.go +++ b/internal/middleware/auth.go @@ -61,6 +61,7 @@ func Auth(sm SessionManager, next http.Handler) http.Handler { Path: "/", HttpOnly: true, Secure: true, + SameSite: http.SameSiteLaxMode, Expires: time.Now().AddDate(0, 0, 1), } http.SetCookie(w, cookie) @@ -94,6 +95,7 @@ func logout(w http.ResponseWriter, r *http.Request, sm SessionManager) { Path: "/", HttpOnly: true, Secure: true, + SameSite: http.SameSiteLaxMode, Expires: time.Now().AddDate(0, 0, -1), } @@ -102,7 +104,7 @@ func logout(w http.ResponseWriter, r *http.Request, sm SessionManager) { func unauthorized(w http.ResponseWriter, r *http.Request, err error) { w.Header().Set("Content-Type", "application/json:charset=UTF-8") - w.Header().Set("Access-Control-Allow-Origin", "http://vilka.online") + w.Header().Set("Access-Control-Allow-Origin", "https://vilka.online") w.Header().Set("Access-Control-Allow-Credentials", "true") w.WriteHeader(http.StatusUnauthorized) @@ -113,7 +115,7 @@ func unauthorized(w http.ResponseWriter, r *http.Request, err error) { func internalErr(w http.ResponseWriter) { w.Header().Set("Content-Type", "application/json:charset=UTF-8") - w.Header().Set("Access-Control-Allow-Origin", "http://vilka.online") + w.Header().Set("Access-Control-Allow-Origin", "https://vilka.online") w.Header().Set("Access-Control-Allow-Credentials", "true") w.WriteHeader(http.StatusInternalServerError) diff --git a/internal/middleware/preflite.go b/internal/middleware/preflite.go index 86149bc4..df3af25f 100644 --- a/internal/middleware/preflite.go +++ b/internal/middleware/preflite.go @@ -5,19 +5,21 @@ import ( ) func Preflite(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method == http.MethodOptions { - w.Header().Set("Access-Control-Allow-Origin", "http://vilka.online") - w.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE") - w.Header().Set("Access-Control-Max-Age", "3600") - w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Accept") - w.Header().Set("Content-Type", "application/json:charset=UTF-8") - w.Header().Set("Access-Control-Allow-Credentials", "true") + return http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodOptions { + w.Header().Set("Access-Control-Allow-Origin", "https://vilka.online") + w.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE") + w.Header().Set("Access-Control-Max-Age", "3600") + w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Accept") + w.Header().Set("Content-Type", "application/json:charset=UTF-8") + w.Header().Set("Access-Control-Allow-Credentials", "true") - w.WriteHeader(http.StatusOK) - return - } else { - next.ServeHTTP(w, r) - } - }) + w.WriteHeader(http.StatusOK) + return + } else { + next.ServeHTTP(w, r) + } + }, + ) } diff --git a/internal/profile/repository/QueryConsts.go b/internal/profile/repository/QueryConsts.go index 6fd4d1dc..317cfb8a 100644 --- a/internal/profile/repository/QueryConsts.go +++ b/internal/profile/repository/QueryConsts.go @@ -25,8 +25,21 @@ const ( GetFriendsID = "SELECT sender AS friend FROM friend WHERE (receiver = $1 AND status = 0) UNION SELECT receiver AS friend FROM friend WHERE (sender = $1 AND status = 0)" GetSubsID = "SELECT sender AS subscriber FROM friend WHERE (receiver = $1 AND status = 1) UNION SELECT receiver AS subscriber FROM friend WHERE (sender = $1 AND status = -1)" GetSubscriptionsID = "SELECT sender AS subscription FROM friend WHERE (receiver = $1 AND status = -1) UNION SELECT receiver AS subscriber FROM friend WHERE (sender = $1 AND status = 1)" - GetAllStatuses = "WITH friends AS (\n SELECT sender AS friend\n FROM friend\n WHERE (receiver = $1 AND status = 0)\n UNION\n SELECT receiver AS friend\n FROM friend\n WHERE (sender = $1 AND status = 0)\n), subscriptions AS (\n SELECT sender AS subscription FROM friend WHERE (receiver = $1 AND status = -1) UNION SELECT receiver AS subscriber FROM friend WHERE (sender = $1 AND status = 1)\n), subscribers AS (\n SELECT sender AS subscriber FROM friend WHERE (receiver = $1 AND status = 1) UNION SELECT receiver AS subscriber FROM friend WHERE (sender = $1 AND status = -1)) SELECT (SELECT json_agg(friend) FROM friends) AS friends, (SELECT json_agg(subscriber) FROM subscribers) AS subscribers, (SELECT json_agg(subscription) FROM subscriptions) AS subscriptions;" - GetShortProfile = "SELECT first_name || ' ' || last_name AS name, avatar FROM profile WHERE profile.id = $1 LIMIT 1;" + GetAllStatuses = `WITH friends AS ( +SELECT sender AS friend +FROM friend WHERE (receiver = $1 AND status = 0) UNION +SELECT receiver AS friend FROM friend WHERE (sender = $1 AND status = 0) +), subscriptions AS ( +SELECT sender AS subscription FROM friend WHERE (receiver = $1 AND status = -1) UNION +SELECT receiver AS subscriber FROM friend WHERE (sender = $1 AND status = 1) +), subscribers AS ( +SELECT sender AS subscriber FROM friend WHERE (receiver = $1 AND status = 1) UNION +SELECT receiver AS subscriber FROM friend WHERE (sender = $1 AND status = -1) +) SELECT (SELECT json_agg(friend) FROM friends) AS friends, +(SELECT json_agg(subscriber) FROM subscribers) AS subscribers, +(SELECT json_agg(subscription) FROM subscriptions) AS subscriptions;` + + GetShortProfile = "SELECT first_name || ' ' || last_name AS name, avatar FROM profile WHERE profile.id = $1 LIMIT 1;" GetCommunitySubs = `WITH subs AS (SELECT profile_id AS id FROM community_profile WHERE community_id = $1) SELECT p.id, first_name, last_name, avatar FROM profile p JOIN subs ON p.id = subs.id WHERE id > $2 ORDER BY id LIMIT $3;` From 481936208ac4120fb3b67641f44cd4cf227edf36 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Tue, 17 Dec 2024 21:04:27 +0300 Subject: [PATCH 111/135] fix cookie to strict --- internal/auth/controller/controller.go | 6 +++--- internal/middleware/auth.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/auth/controller/controller.go b/internal/auth/controller/controller.go index 1b6a62ce..10d5b5a9 100644 --- a/internal/auth/controller/controller.go +++ b/internal/auth/controller/controller.go @@ -91,7 +91,7 @@ func (c *AuthController) Register(w http.ResponseWriter, r *http.Request) { Path: "/", HttpOnly: true, Secure: true, - SameSite: http.SameSiteLaxMode, + SameSite: http.SameSiteStrictMode, Expires: time.Now().AddDate(0, 0, 1), } @@ -140,7 +140,7 @@ func (c *AuthController) Auth(w http.ResponseWriter, r *http.Request) { Path: "/", HttpOnly: true, Secure: true, - SameSite: http.SameSiteLaxMode, + SameSite: http.SameSiteStrictMode, Expires: time.Now().AddDate(0, 0, 1), } http.SetCookie(w, cookie) @@ -178,7 +178,7 @@ func (c *AuthController) Logout(w http.ResponseWriter, r *http.Request) { Path: "/", HttpOnly: true, Secure: true, - SameSite: http.SameSiteLaxMode, + SameSite: http.SameSiteStrictMode, Expires: time.Now().AddDate(0, 0, -1), } http.SetCookie(w, cookie) diff --git a/internal/middleware/auth.go b/internal/middleware/auth.go index 148625de..c9b3d69a 100644 --- a/internal/middleware/auth.go +++ b/internal/middleware/auth.go @@ -61,7 +61,7 @@ func Auth(sm SessionManager, next http.Handler) http.Handler { Path: "/", HttpOnly: true, Secure: true, - SameSite: http.SameSiteLaxMode, + SameSite: http.SameSiteStrictMode, Expires: time.Now().AddDate(0, 0, 1), } http.SetCookie(w, cookie) @@ -95,7 +95,7 @@ func logout(w http.ResponseWriter, r *http.Request, sm SessionManager) { Path: "/", HttpOnly: true, Secure: true, - SameSite: http.SameSiteLaxMode, + SameSite: http.SameSiteStrictMode, Expires: time.Now().AddDate(0, 0, -1), } From cbf4c258c96cecc1f658f65f39ba14b27c9d54f1 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Tue, 17 Dec 2024 21:33:19 +0300 Subject: [PATCH 112/135] update logs --- internal/chat/controller/client.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/chat/controller/client.go b/internal/chat/controller/client.go index 73cb52a2..05753123 100644 --- a/internal/chat/controller/client.go +++ b/internal/chat/controller/client.go @@ -1,6 +1,7 @@ package controller import ( + "fmt" "time" "github.com/gorilla/websocket" @@ -23,7 +24,7 @@ func (c *Client) Read(userID uint32) { msg := &models.Message{} _, jsonMessage, err := c.Socket.ReadMessage() if err != nil { - c.chatController.responder.LogError(err, wc) + c.chatController.responder.LogError(fmt.Errorf("read message: %w", err), wc) return } err = easyjson.Unmarshal(jsonMessage, msg) @@ -47,7 +48,7 @@ func (c *Client) Write() { } err = c.Socket.WriteMessage(websocket.TextMessage, jsonForSend) if err != nil { - c.chatController.responder.LogError(err, wc) + c.chatController.responder.LogError(fmt.Errorf("write message: %w", err), wc) return } } From ca0d503d21aba8dacfba46fe0e10d3d4e34ef76d Mon Sep 17 00:00:00 2001 From: slashlight Date: Wed, 18 Dec 2024 00:09:54 +0300 Subject: [PATCH 113/135] feat: added sanitizing --- go.mod | 3 + go.sum | 6 ++ internal/auth/controller/controller.go | 12 +++ internal/chat/controller/client.go | 11 ++- internal/chat/controller/controller.go | 3 +- internal/community/controller/controller.go | 38 ++++++++- internal/post/controller/controller.go | 88 ++++++++++++++++++--- internal/profile/controller/controller.go | 50 ++++++++++-- internal/stickers/controller/controller.go | 18 ++++- 9 files changed, 202 insertions(+), 27 deletions(-) diff --git a/go.mod b/go.mod index 79cc766e..7b281808 100644 --- a/go.mod +++ b/go.mod @@ -24,11 +24,13 @@ require ( ) require ( + github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cockroachdb/apd v1.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/gofrs/uuid v4.4.0+incompatible // indirect + github.com/gorilla/css v1.0.1 // indirect github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect @@ -37,6 +39,7 @@ require ( github.com/klauspost/compress v1.17.9 // indirect github.com/kr/text v0.2.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/microcosm-cc/bluemonday v1.0.27 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/go.sum b/go.sum index c669881d..ba7f8257 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -22,6 +24,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= +github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= @@ -55,6 +59,8 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= +github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= diff --git a/internal/auth/controller/controller.go b/internal/auth/controller/controller.go index 10d5b5a9..1370e47a 100644 --- a/internal/auth/controller/controller.go +++ b/internal/auth/controller/controller.go @@ -9,6 +9,7 @@ import ( "time" "github.com/mailru/easyjson" + "github.com/microcosm-cc/bluemonday" "golang.org/x/crypto/bcrypt" "github.com/2024_2_BetterCallFirewall/internal/auth" @@ -49,6 +50,12 @@ func NewAuthController( } } +func sanitize(input string) string { + sanitizer := bluemonday.UGCPolicy() + cleaned := sanitizer.Sanitize(input) + return cleaned +} + func (c *AuthController) Register(w http.ResponseWriter, r *http.Request) { reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { @@ -57,6 +64,9 @@ func (c *AuthController) Register(w http.ResponseWriter, r *http.Request) { user := models.User{} err := easyjson.UnmarshalFromReader(r.Body, &user) + user.FirstName = sanitize(user.FirstName) + user.LastName = sanitize(user.LastName) + user.Email = sanitize(user.Email) if err != nil { c.responder.ErrorBadRequest(w, fmt.Errorf("router register: %w", err), reqID) return @@ -108,6 +118,8 @@ func (c *AuthController) Auth(w http.ResponseWriter, r *http.Request) { user := models.User{} err := easyjson.UnmarshalFromReader(r.Body, &user) + user.Email = sanitize(user.Email) + user.Password = sanitize(user.Password) if err != nil { c.responder.ErrorBadRequest(w, fmt.Errorf("router auth: %w", err), reqID) return diff --git a/internal/chat/controller/client.go b/internal/chat/controller/client.go index 05753123..30e6123d 100644 --- a/internal/chat/controller/client.go +++ b/internal/chat/controller/client.go @@ -6,6 +6,7 @@ import ( "github.com/gorilla/websocket" "github.com/mailru/easyjson" + "github.com/microcosm-cc/bluemonday" "github.com/2024_2_BetterCallFirewall/internal/models" ) @@ -18,16 +19,24 @@ type Client struct { chatController *ChatController } +func sanitize(input string) string { + sanitizer := bluemonday.UGCPolicy() + cleaned := sanitizer.Sanitize(input) + return cleaned +} + func (c *Client) Read(userID uint32) { defer c.Socket.Close() for { msg := &models.Message{} _, jsonMessage, err := c.Socket.ReadMessage() + clearJson := sanitize(string(jsonMessage)) if err != nil { c.chatController.responder.LogError(fmt.Errorf("read message: %w", err), wc) return } - err = easyjson.Unmarshal(jsonMessage, msg) + err = easyjson.Unmarshal([]byte(clearJson), msg) + if err != nil { c.chatController.responder.LogError(err, wc) return diff --git a/internal/chat/controller/controller.go b/internal/chat/controller/controller.go index 6a8c907a..1690cb40 100644 --- a/internal/chat/controller/controller.go +++ b/internal/chat/controller/controller.go @@ -174,8 +174,9 @@ func GetIdFromURL(r *http.Request) (uint32, error) { if id == "" { return 0, my_err.ErrEmptyId } + clearId := sanitize(id) - uid, err := strconv.ParseUint(id, 10, 32) + uid, err := strconv.ParseUint(clearId, 10, 32) if err != nil { return 0, err } diff --git a/internal/community/controller/controller.go b/internal/community/controller/controller.go index 9548d42e..bc85c45b 100644 --- a/internal/community/controller/controller.go +++ b/internal/community/controller/controller.go @@ -10,6 +10,7 @@ import ( "github.com/gorilla/mux" "github.com/mailru/easyjson" + "github.com/microcosm-cc/bluemonday" "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/internal/models" @@ -50,6 +51,11 @@ func NewCommunityController(responder responder, service communityService) *Cont service: service, } } +func sanitize(input string) string { + sanitizer := bluemonday.UGCPolicy() + cleaned := sanitizer.Sanitize(input) + return cleaned +} func (c *Controller) GetOne(w http.ResponseWriter, r *http.Request) { reqID, ok := r.Context().Value(middleware.RequestKey).(string) @@ -75,13 +81,17 @@ func (c *Controller) GetOne(w http.ResponseWriter, r *http.Request) { return } + community.Name = sanitize(community.Name) + community.Avatar = models.Picture(sanitize(string(community.Avatar))) + community.About = sanitize(community.About) + c.responder.OutputJSON(w, community, reqID) } func (c *Controller) GetAll(w http.ResponseWriter, r *http.Request) { var ( reqID, ok = r.Context().Value(middleware.RequestKey).(string) - lastID = r.URL.Query().Get("id") + lastID = sanitize(r.URL.Query().Get("id")) intLastID uint64 err error ) @@ -117,6 +127,12 @@ func (c *Controller) GetAll(w http.ResponseWriter, r *http.Request) { return } + for _, card := range res { + card.Name = sanitize(card.Name) + card.Avatar = models.Picture(sanitize(string(card.Avatar))) + card.About = sanitize(card.About) + } + c.responder.OutputJSON(w, res, reqID) } @@ -155,6 +171,10 @@ func (c *Controller) Update(w http.ResponseWriter, r *http.Request) { return } + newCommunity.Avatar = models.Picture(sanitize(string(newCommunity.Avatar))) + newCommunity.Name = sanitize(newCommunity.Name) + newCommunity.About = sanitize(newCommunity.About) + c.responder.OutputJSON(w, newCommunity, reqID) } @@ -317,8 +337,8 @@ func (c *Controller) AddAdmin(w http.ResponseWriter, r *http.Request) { func (c *Controller) SearchCommunity(w http.ResponseWriter, r *http.Request) { var ( reqID, ok = r.Context().Value(middleware.RequestKey).(string) - subStr = r.URL.Query().Get("q") - lastID = r.URL.Query().Get("id") + subStr = sanitize(r.URL.Query().Get("q")) + lastID = sanitize(r.URL.Query().Get("id")) id uint64 err error ) @@ -354,6 +374,12 @@ func (c *Controller) SearchCommunity(w http.ResponseWriter, r *http.Request) { return } + for _, card := range cards { + card.Name = sanitize(card.Name) + card.Avatar = models.Picture(sanitize(string(card.Avatar))) + card.About = sanitize(card.About) + } + c.responder.OutputJSON(w, cards, reqID) } @@ -367,6 +393,9 @@ func (c *Controller) getCommunityFromBody(r *http.Request) (models.Community, er if !validate(res) { return models.Community{}, my_err.ErrBadCommunity } + res.Avatar = models.Picture(sanitize(string(res.Avatar))) + res.Name = sanitize(res.Name) + res.About = sanitize(res.About) return res, nil } @@ -378,8 +407,9 @@ func getIDFromQuery(r *http.Request) (uint32, error) { if id == "" { return 0, errors.New("id is empty") } + clearID := sanitize(id) - uid, err := strconv.ParseUint(id, 10, 32) + uid, err := strconv.ParseUint(clearID, 10, 32) if err != nil { return 0, err } diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index ff80b228..3985c5b9 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -12,6 +12,7 @@ import ( "github.com/gorilla/mux" "github.com/mailru/easyjson" + "github.com/microcosm-cc/bluemonday" "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/internal/models" @@ -74,10 +75,25 @@ func NewPostController(service PostService, commentService CommentService, respo } } +func sanitize(input string) string { + sanitizer := bluemonday.UGCPolicy() + cleaned := sanitizer.Sanitize(input) + return cleaned +} + +func sanitizeFiles(pics []models.Picture) []models.Picture { + var results []models.Picture + for _, pic := range pics { + results = append(results, models.Picture(sanitize(string(pic)))) + } + + return results +} + func (pc *PostController) Create(w http.ResponseWriter, r *http.Request) { var ( reqID, ok = r.Context().Value(middleware.RequestKey).(string) - comunity = r.URL.Query().Get("community") + comunity = sanitize(r.URL.Query().Get("community")) id uint32 err error ) @@ -119,7 +135,13 @@ func (pc *PostController) Create(w http.ResponseWriter, r *http.Request) { newPost.ID = id - pc.responder.OutputJSON(w, newPost.FromDto(), reqID) + post := newPost.FromDto() + post.PostContent.Text = sanitize(post.PostContent.Text) + post.PostContent.File = sanitizeFiles(post.PostContent.File) + post.Header.Avatar = models.Picture(sanitize(string(post.Header.Avatar))) + post.Header.Author = sanitize(post.Header.Author) + + pc.responder.OutputJSON(w, post, reqID) } func (pc *PostController) GetOne(w http.ResponseWriter, r *http.Request) { @@ -151,15 +173,21 @@ func (pc *PostController) GetOne(w http.ResponseWriter, r *http.Request) { return } } + newPost := post.FromDto() + + newPost.PostContent.Text = sanitize(newPost.PostContent.Text) + newPost.PostContent.File = sanitizeFiles(newPost.PostContent.File) + newPost.Header.Avatar = models.Picture(sanitize(string(newPost.Header.Avatar))) + newPost.Header.Author = sanitize(newPost.Header.Author) - pc.responder.OutputJSON(w, post.FromDto(), reqID) + pc.responder.OutputJSON(w, newPost, reqID) } func (pc *PostController) Update(w http.ResponseWriter, r *http.Request) { var ( reqID, ok = r.Context().Value(middleware.RequestKey).(string) id, err = getIDFromURL(r, postIDkey) - community = r.URL.Query().Get("community") + community = sanitize(r.URL.Query().Get("community")) ) if err != nil { @@ -203,15 +231,21 @@ func (pc *PostController) Update(w http.ResponseWriter, r *http.Request) { pc.responder.ErrorInternal(w, err, reqID) return } + newPost := post.FromDto() - pc.responder.OutputJSON(w, post.FromDto(), reqID) + newPost.PostContent.Text = sanitize(newPost.PostContent.Text) + newPost.PostContent.File = sanitizeFiles(newPost.PostContent.File) + newPost.Header.Avatar = models.Picture(sanitize(string(newPost.Header.Avatar))) + newPost.Header.Author = sanitize(newPost.Header.Author) + + pc.responder.OutputJSON(w, newPost, reqID) } func (pc *PostController) Delete(w http.ResponseWriter, r *http.Request) { var ( reqID, ok = r.Context().Value(middleware.RequestKey).(string) postID, err = getIDFromURL(r, postIDkey) - community = r.URL.Query().Get("community") + community = sanitize(r.URL.Query().Get("community")) ) if !ok { @@ -255,8 +289,8 @@ func (pc *PostController) Delete(w http.ResponseWriter, r *http.Request) { func (pc *PostController) GetBatchPosts(w http.ResponseWriter, r *http.Request) { var ( reqID, ok = r.Context().Value(middleware.RequestKey).(string) - section = r.URL.Query().Get("section") - communityID = r.URL.Query().Get("community") + section = sanitize(r.URL.Query().Get("section")) + communityID = sanitize(r.URL.Query().Get("community")) posts []*models.PostDto intLastID uint64 err error @@ -315,7 +349,13 @@ func (pc *PostController) GetBatchPosts(w http.ResponseWriter, r *http.Request) res := make([]models.Post, 0, len(posts)) for _, post := range posts { - res = append(res, post.FromDto()) + newPost := post.FromDto() + + newPost.PostContent.Text = sanitize(newPost.PostContent.Text) + newPost.PostContent.File = sanitizeFiles(newPost.PostContent.File) + newPost.Header.Avatar = models.Picture(sanitize(string(newPost.Header.Avatar))) + newPost.Header.Author = sanitize(newPost.Header.Author) + res = append(res, newPost) } pc.responder.OutputJSON(w, res, reqID) @@ -340,6 +380,11 @@ func (pc *PostController) getPostFromBody(r *http.Request) (*models.PostDto, err newPost.Header.AuthorID = sess.UserID post := newPost.ToDto() + post.PostContent.Text = sanitize(post.PostContent.Text) + post.PostContent.File = models.Picture(sanitize(string(post.PostContent.File))) + post.Header.Avatar = models.Picture(sanitize(string(post.Header.Avatar))) + post.Header.Author = sanitize(post.Header.Author) + return &post, nil } @@ -350,8 +395,9 @@ func getIDFromURL(r *http.Request, key string) (uint32, error) { if id == "" { return 0, errors.New("id is empty") } + clearID := sanitize(id) - uid, err := strconv.ParseUint(id, 10, 32) + uid, err := strconv.ParseUint(clearID, 10, 32) if err != nil { return 0, err } @@ -365,8 +411,8 @@ func getLastID(r *http.Request) (uint64, error) { if lastID == "" { return math.MaxInt32, nil } - - intLastID, err := strconv.ParseUint(lastID, 10, 32) + clearLastID := sanitize(lastID) + intLastID, err := strconv.ParseUint(clearLastID, 10, 32) if err != nil { return 0, err } @@ -502,6 +548,8 @@ func (pc *PostController) Comment(w http.ResponseWriter, r *http.Request) { return } + content.Text = sanitize(content.Text) + if !validateContent(content) { pc.responder.ErrorBadRequest(w, my_err.ErrBadPostOrComment, reqID) return @@ -514,6 +562,10 @@ func (pc *PostController) Comment(w http.ResponseWriter, r *http.Request) { return } newComment.Content.CreatedAt = time.Now() + newComment.Content.Text = sanitize(newComment.Content.Text) + newComment.Content.File = models.Picture(sanitize(string(newComment.Content.File))) + newComment.Header.Avatar = models.Picture(sanitize(string(newComment.Header.Avatar))) + newComment.Header.Author = sanitize(newComment.Header.Author) pc.responder.OutputJSON(w, newComment.FromDto(), reqID) } @@ -579,6 +631,8 @@ func (pc *PostController) EditComment(w http.ResponseWriter, r *http.Request) { return } + content.Text = sanitize(content.Text) + if !validateContent(content) { pc.responder.ErrorBadRequest(w, my_err.ErrBadPostOrComment, reqID) return @@ -620,7 +674,7 @@ func (pc *PostController) GetComments(w http.ResponseWriter, r *http.Request) { pc.responder.ErrorBadRequest(w, err, reqID) return } - sorting := r.URL.Query().Get("sort") + sorting := sanitize(r.URL.Query().Get("sort")) newest := true if sorting == "old" { newest = false @@ -645,6 +699,14 @@ func (pc *PostController) GetComments(w http.ResponseWriter, r *http.Request) { res = append(res, comment.FromDto()) } + for _, newComment := range res { + newComment.Content.CreatedAt = time.Now() + newComment.Content.Text = sanitize(newComment.Content.Text) + newComment.Content.File = sanitizeFiles(newComment.Content.File) + newComment.Header.Avatar = models.Picture(sanitize(string(newComment.Header.Avatar))) + newComment.Header.Author = sanitize(newComment.Header.Author) + } + pc.responder.OutputJSON(w, res, reqID) } diff --git a/internal/profile/controller/controller.go b/internal/profile/controller/controller.go index 8f2b8f47..c9ccf8c1 100644 --- a/internal/profile/controller/controller.go +++ b/internal/profile/controller/controller.go @@ -9,6 +9,7 @@ import ( "github.com/gorilla/mux" "github.com/mailru/easyjson" + "github.com/microcosm-cc/bluemonday" "golang.org/x/crypto/bcrypt" "github.com/2024_2_BetterCallFirewall/internal/middleware" @@ -39,6 +40,27 @@ func NewProfileController(manager profile.ProfileUsecase, responder Responder) * } } +func sanitize(input string) string { + sanitizer := bluemonday.UGCPolicy() + cleaned := sanitizer.Sanitize(input) + return cleaned +} + +func sanitizeProfile(fullProfile *models.FullProfile) { + fullProfile.Bio = sanitize(fullProfile.Bio) + fullProfile.Avatar = models.Picture(sanitize(string(fullProfile.Avatar))) + fullProfile.FirstName = sanitize(fullProfile.FirstName) + fullProfile.LastName = sanitize(fullProfile.LastName) +} + +func sanitizeProfiles(shorts []*models.ShortProfile) { + for _, short := range shorts { + short.Avatar = models.Picture(sanitize(string(short.Avatar))) + short.FirstName = sanitize(short.FirstName) + short.LastName = sanitize(short.LastName) + } +} + func (h *ProfileHandlerImplementation) GetHeader(w http.ResponseWriter, r *http.Request) { reqID, ok := r.Context().Value(middleware.RequestKey).(string) if !ok { @@ -53,6 +75,8 @@ func (h *ProfileHandlerImplementation) GetHeader(w http.ResponseWriter, r *http. userId := sess.UserID header, err := h.ProfileManager.GetHeader(r.Context(), userId) + header.Author = sanitize(header.Author) + header.Avatar = models.Picture(sanitize(string(header.Avatar))) if err != nil { if errors.Is(err, my_err.ErrProfileNotFound) { h.Responder.ErrorBadRequest(w, err, reqID) @@ -90,6 +114,7 @@ func (h *ProfileHandlerImplementation) GetProfile(w http.ResponseWriter, r *http h.Responder.ErrorInternal(w, err, reqID) return } + sanitizeProfile(userProfile) h.Responder.OutputJSON(w, userProfile, reqID) } @@ -119,6 +144,7 @@ func (h *ProfileHandlerImplementation) UpdateProfile(w http.ResponseWriter, r *h return } + sanitizeProfile(newProfile) h.Responder.OutputJSON(w, newProfile, reqID) } @@ -128,6 +154,7 @@ func (h *ProfileHandlerImplementation) getNewProfile(r *http.Request) (*models.F if err != nil { return nil, err } + sanitizeProfile(&newProfile) if len([]rune(newProfile.FirstName)) < 3 || len([]rune(newProfile.FirstName)) > 30 || len([]rune(newProfile.LastName)) < 3 || len([]rune(newProfile.LastName)) > 30 || @@ -169,8 +196,9 @@ func GetIdFromURL(r *http.Request) (uint32, error) { if id == "" { return 0, my_err.ErrEmptyId } + clearID := sanitize(id) - uid, err := strconv.ParseUint(id, 10, 32) + uid, err := strconv.ParseUint(clearID, 10, 32) if err != nil { return 0, err } @@ -195,7 +223,7 @@ func (h *ProfileHandlerImplementation) GetProfileById(w http.ResponseWriter, r * return } - profile, err := h.ProfileManager.GetProfileById(r.Context(), id) + uprofile, err := h.ProfileManager.GetProfileById(r.Context(), id) if err != nil { if errors.Is(err, my_err.ErrProfileNotFound) { h.Responder.ErrorBadRequest(w, err, reqID) @@ -204,12 +232,13 @@ func (h *ProfileHandlerImplementation) GetProfileById(w http.ResponseWriter, r * h.Responder.ErrorInternal(w, err, reqID) return } + sanitizeProfile(uprofile) - h.Responder.OutputJSON(w, profile, reqID) + h.Responder.OutputJSON(w, uprofile, reqID) } func GetLastId(r *http.Request) (uint32, error) { - strLastId := r.URL.Query().Get("last_id") + strLastId := sanitize(r.URL.Query().Get("last_id")) if strLastId == "" { return 0, nil } @@ -250,6 +279,7 @@ func (h *ProfileHandlerImplementation) GetAll(w http.ResponseWriter, r *http.Req h.Responder.OutputNoMoreContentJSON(w, reqID) return } + sanitizeProfiles(profiles) h.Responder.OutputJSON(w, profiles, reqID) } @@ -387,7 +417,7 @@ func (h *ProfileHandlerImplementation) GetAllFriends(w http.ResponseWriter, r *h h.Responder.OutputNoMoreContentJSON(w, reqID) return } - + sanitizeProfiles(profiles) h.Responder.OutputJSON(w, profiles, reqID) } @@ -420,6 +450,7 @@ func (h *ProfileHandlerImplementation) GetAllSubs(w http.ResponseWriter, r *http h.Responder.OutputNoMoreContentJSON(w, reqID) return } + sanitizeProfiles(profiles) h.Responder.OutputJSON(w, profiles, reqID) } @@ -454,6 +485,7 @@ func (h *ProfileHandlerImplementation) GetAllSubscriptions(w http.ResponseWriter return } + sanitizeProfiles(profiles) h.Responder.OutputJSON(w, profiles, reqID) } @@ -489,14 +521,15 @@ func (h *ProfileHandlerImplementation) GetCommunitySubs(w http.ResponseWriter, r return } + sanitizeProfiles(subs) h.Responder.OutputJSON(w, subs, reqID) } func (h *ProfileHandlerImplementation) SearchProfile(w http.ResponseWriter, r *http.Request) { var ( reqID, ok = r.Context().Value(middleware.RequestKey).(string) - subStr = r.URL.Query().Get("q") - lastID = r.URL.Query().Get("id") + subStr = sanitize(r.URL.Query().Get("q")) + lastID = sanitize(r.URL.Query().Get("id")) id uint64 err error ) @@ -531,6 +564,7 @@ func (h *ProfileHandlerImplementation) SearchProfile(w http.ResponseWriter, r *h return } + sanitizeProfiles(profiles) h.Responder.OutputJSON(w, profiles, reqID) } @@ -574,6 +608,8 @@ func (h *ProfileHandlerImplementation) ChangePassword(w http.ResponseWriter, r * } func validate(request models.ChangePasswordReq) bool { + request.OldPassword = sanitize(request.OldPassword) + request.NewPassword = sanitize(request.NewPassword) if len([]rune(request.OldPassword)) < 6 || len([]rune(request.NewPassword)) < 6 || request.OldPassword == request.NewPassword { return false } diff --git a/internal/stickers/controller/controller.go b/internal/stickers/controller/controller.go index 4e6f62ad..5895311e 100644 --- a/internal/stickers/controller/controller.go +++ b/internal/stickers/controller/controller.go @@ -7,6 +7,8 @@ import ( "net/http" "strings" + "github.com/microcosm-cc/bluemonday" + "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/internal/stickers" @@ -37,6 +39,18 @@ func NewStickerController(manager stickers.Usecase, responder Responder) *Sticke } } +func sanitize(input string) string { + sanitizer := bluemonday.UGCPolicy() + cleaned := sanitizer.Sanitize(input) + return cleaned +} + +func sanitizeFiles(pics []*models.Picture) { + for _, pic := range pics { + *pic = models.Picture(sanitize(string(*pic))) + } +} + func (s StickersHandlerImplementation) AddNewSticker(w http.ResponseWriter, r *http.Request) { reqID, ok := r.Context().Value(middleware.RequestKey).(string) @@ -51,6 +65,7 @@ func (s StickersHandlerImplementation) AddNewSticker(w http.ResponseWriter, r *h return } + filePath.File = sanitize(filePath.File) if !validate(filePath.File) { s.Responder.ErrorBadRequest(w, my_err.ErrNoImage, reqID) return @@ -88,6 +103,7 @@ func (s StickersHandlerImplementation) GetAllStickers(w http.ResponseWriter, r * return } + sanitizeFiles(res) s.Responder.OutputJSON(w, res, reqID) } @@ -113,7 +129,7 @@ func (s StickersHandlerImplementation) GetMineStickers(w http.ResponseWriter, r s.Responder.ErrorInternal(w, err, reqID) return } - + sanitizeFiles(res) s.Responder.OutputJSON(w, res, reqID) } From 98ae337fdda9685f2d9a80471692ee41c4ddc5ba Mon Sep 17 00:00:00 2001 From: slashlight Date: Wed, 18 Dec 2024 00:50:58 +0300 Subject: [PATCH 114/135] feat: added sanitizer tests --- internal/auth/controller/controller_test.go | 9 ++++ internal/chat/controller/controller_test.go | 7 +++ .../community/controller/controller_test.go | 7 +++ internal/fileService/controller/controller.go | 17 +++++-- internal/post/controller/controller_test.go | 14 +++++ .../profile/controller/controller_test.go | 51 +++++++++++++++++++ .../stickers/controller/controller_test.go | 17 +++++++ 7 files changed, 117 insertions(+), 5 deletions(-) diff --git a/internal/auth/controller/controller_test.go b/internal/auth/controller/controller_test.go index 46753dd7..10310b77 100644 --- a/internal/auth/controller/controller_test.go +++ b/internal/auth/controller/controller_test.go @@ -10,6 +10,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/2024_2_BetterCallFirewall/internal/models" "github.com/2024_2_BetterCallFirewall/pkg/my_err" ) @@ -166,6 +168,13 @@ func TestRegister(t *testing.T) { } } +func TestSanitize(t *testing.T) { + test := "" + expected := "" + res := sanitize(test) + assert.Equal(t, expected, res) +} + func TestAuth(t *testing.T) { controller := NewAuthController(&MockResponder{}, MockAuthService{}, MockSessionManager{}) jsonUser0, _ := json.Marshal(models.User{ID: 0, Email: "test@test.ru", Password: "password"}) diff --git a/internal/chat/controller/controller_test.go b/internal/chat/controller/controller_test.go index 254d6dde..76192d8f 100644 --- a/internal/chat/controller/controller_test.go +++ b/internal/chat/controller/controller_test.go @@ -36,6 +36,13 @@ func TestNewController(t *testing.T) { assert.NotNil(t, res) } +func TestSanitize(t *testing.T) { + test := "" + expected := "" + res := sanitize(test) + assert.Equal(t, expected, res) +} + func TestGetAllChat(t *testing.T) { tests := []TableTest[Response, Request]{ { diff --git a/internal/community/controller/controller_test.go b/internal/community/controller/controller_test.go index bfde7f58..80f2edc8 100644 --- a/internal/community/controller/controller_test.go +++ b/internal/community/controller/controller_test.go @@ -228,6 +228,13 @@ func TestGetOne(t *testing.T) { } } +func TestSanitize(t *testing.T) { + test := "" + expected := "" + res := sanitize(test) + assert.Equal(t, expected, res) +} + func TestGetAll(t *testing.T) { tests := []TableTest[Response, Request]{ { diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index 516ae21f..9806542e 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/gorilla/mux" + "github.com/microcosm-cc/bluemonday" "github.com/2024_2_BetterCallFirewall/internal/middleware" "github.com/2024_2_BetterCallFirewall/pkg/my_err" @@ -50,11 +51,17 @@ func NewFileController(fileService fileService, responder responder) *FileContro } } +func sanitize(input string) string { + sanitizer := bluemonday.UGCPolicy() + cleaned := sanitizer.Sanitize(input) + return cleaned +} + func (fc *FileController) UploadNonImage(w http.ResponseWriter, r *http.Request) { var ( reqID, ok = r.Context().Value("requestID").(string) vars = mux.Vars(r) - name = vars["name"] + name = sanitize(vars["name"]) ) if !ok { @@ -72,14 +79,14 @@ func (fc *FileController) UploadNonImage(w http.ResponseWriter, r *http.Request) return } - fc.responder.OutputBytes(w, res, reqID) + fc.responder.OutputBytes(w, []byte(sanitize(string(res))), reqID) } func (fc *FileController) Upload(w http.ResponseWriter, r *http.Request) { var ( reqID, ok = r.Context().Value(middleware.RequestKey).(string) vars = mux.Vars(r) - name = vars["name"] + name = sanitize(vars["name"]) ) if !ok { @@ -97,7 +104,7 @@ func (fc *FileController) Upload(w http.ResponseWriter, r *http.Request) { return } - fc.responder.OutputBytes(w, res, reqID) + fc.responder.OutputBytes(w, []byte(sanitize(string(res))), reqID) } func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { @@ -154,5 +161,5 @@ func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { fc.responder.ErrorBadRequest(w, err, reqID) return } - fc.responder.OutputJSON(w, url, reqID) + fc.responder.OutputJSON(w, sanitize(url), reqID) } diff --git a/internal/post/controller/controller_test.go b/internal/post/controller/controller_test.go index edcf1c93..d46e7374 100644 --- a/internal/post/controller/controller_test.go +++ b/internal/post/controller/controller_test.go @@ -2191,6 +2191,20 @@ func TestDeleteLikeFromPost(t *testing.T) { } } +func TestSanitize(t *testing.T) { + test := "" + expected := "" + res := sanitize(test) + assert.Equal(t, expected, res) +} + +func TestSanitizeFiles(t *testing.T) { + test := []models.Picture{"", "filepath"} + expected := []models.Picture{"", "filepath"} + res := sanitizeFiles(test) + assert.Equal(t, expected, res) +} + func TestComment(t *testing.T) { tests := []TableTest[Response, Request]{ { diff --git a/internal/profile/controller/controller_test.go b/internal/profile/controller/controller_test.go index a2b94f21..0d5a21ff 100644 --- a/internal/profile/controller/controller_test.go +++ b/internal/profile/controller/controller_test.go @@ -202,6 +202,57 @@ func TestGetHeader(t *testing.T) { } } +func TestSanitize(t *testing.T) { + test := "" + expected := "" + res := sanitize(test) + assert.Equal(t, expected, res) +} + +func TestSanitizeProfile(t *testing.T) { + testProfile := &models.FullProfile{ + FirstName: "Andrew", + LastName: "", + Bio: "", + Avatar: "file", + } + + expProfile := &models.FullProfile{ + FirstName: "Andrew", + LastName: "", + Bio: "", + Avatar: "file", + } + + sanitizeProfile(testProfile) + assert.Equal(t, expProfile, testProfile) +} + +func TestSanitizeProfiles(t *testing.T) { + short1 := &models.ShortProfile{ + FirstName: "Andrew", + LastName: "Savvateev", + Avatar: "filepath", + } + + short2 := &models.ShortProfile{ + FirstName: "Andrew", + LastName: "", + Avatar: "", + } + + short3 := &models.ShortProfile{ + FirstName: "Andrew", + LastName: "", + Avatar: "", + } + + test := []*models.ShortProfile{short1, short2} + exp := []*models.ShortProfile{short1, short3} + sanitizeProfiles(test) + assert.Equal(t, exp, test) +} + func TestGetProfile(t *testing.T) { tests := []TableTest[Response, Request]{ { diff --git a/internal/stickers/controller/controller_test.go b/internal/stickers/controller/controller_test.go index cbaaa68b..fff95e3a 100644 --- a/internal/stickers/controller/controller_test.go +++ b/internal/stickers/controller/controller_test.go @@ -229,6 +229,23 @@ func TestAddNewSticker(t *testing.T) { } } +func TestSanitize(t *testing.T) { + test := "" + expected := "" + res := sanitize(test) + assert.Equal(t, expected, res) +} + +func TestSanitizeFiles(t *testing.T) { + xssV := models.Picture("") + file := models.Picture("filepath") + empty := models.Picture("") + test := []*models.Picture{&xssV, &file} + expected := []*models.Picture{&empty, &file} + sanitizeFiles(test) + assert.Equal(t, expected, test) +} + func TestGetAllSticker(t *testing.T) { tests := []TableTest[Response, Request]{ { From 704725d79236f49e03ff80f5583f81ea27c1a337 Mon Sep 17 00:00:00 2001 From: slashlight Date: Wed, 18 Dec 2024 01:14:37 +0300 Subject: [PATCH 115/135] bugfix: fixed nil sanitizing --- internal/community/controller/controller.go | 8 +++++--- internal/fileService/controller/controller_test.go | 7 +++++++ internal/profile/controller/controller.go | 6 ++++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/internal/community/controller/controller.go b/internal/community/controller/controller.go index bc85c45b..407e69ba 100644 --- a/internal/community/controller/controller.go +++ b/internal/community/controller/controller.go @@ -81,9 +81,11 @@ func (c *Controller) GetOne(w http.ResponseWriter, r *http.Request) { return } - community.Name = sanitize(community.Name) - community.Avatar = models.Picture(sanitize(string(community.Avatar))) - community.About = sanitize(community.About) + if community != nil { + community.Name = sanitize(community.Name) + community.Avatar = models.Picture(sanitize(string(community.Avatar))) + community.About = sanitize(community.About) + } c.responder.OutputJSON(w, community, reqID) } diff --git a/internal/fileService/controller/controller_test.go b/internal/fileService/controller/controller_test.go index cb536d54..0f811e18 100644 --- a/internal/fileService/controller/controller_test.go +++ b/internal/fileService/controller/controller_test.go @@ -288,6 +288,13 @@ func TestUploadNonImage(t *testing.T) { } } +func TestSanitize(t *testing.T) { + test := "" + expected := "" + res := sanitize(test) + assert.Equal(t, expected, res) +} + func TestDownload(t *testing.T) { tests := []TableTest[Response, Request]{ { diff --git a/internal/profile/controller/controller.go b/internal/profile/controller/controller.go index c9ccf8c1..d3cf1f7d 100644 --- a/internal/profile/controller/controller.go +++ b/internal/profile/controller/controller.go @@ -75,8 +75,6 @@ func (h *ProfileHandlerImplementation) GetHeader(w http.ResponseWriter, r *http. userId := sess.UserID header, err := h.ProfileManager.GetHeader(r.Context(), userId) - header.Author = sanitize(header.Author) - header.Avatar = models.Picture(sanitize(string(header.Avatar))) if err != nil { if errors.Is(err, my_err.ErrProfileNotFound) { h.Responder.ErrorBadRequest(w, err, reqID) @@ -86,6 +84,10 @@ func (h *ProfileHandlerImplementation) GetHeader(w http.ResponseWriter, r *http. return } + if header != nil { + header.Author = sanitize(header.Author) + header.Avatar = models.Picture(sanitize(string(header.Avatar))) + } h.Responder.OutputJSON(w, &header, reqID) } From 9a3f3a69c00258232145ba24236cab157b06cb0d Mon Sep 17 00:00:00 2001 From: slashlight Date: Wed, 18 Dec 2024 01:24:09 +0300 Subject: [PATCH 116/135] bugfix: fixed file sanitizing --- internal/fileService/controller/controller.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index 9806542e..0e551121 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -79,7 +79,7 @@ func (fc *FileController) UploadNonImage(w http.ResponseWriter, r *http.Request) return } - fc.responder.OutputBytes(w, []byte(sanitize(string(res))), reqID) + fc.responder.OutputBytes(w, res, reqID) } func (fc *FileController) Upload(w http.ResponseWriter, r *http.Request) { @@ -104,7 +104,7 @@ func (fc *FileController) Upload(w http.ResponseWriter, r *http.Request) { return } - fc.responder.OutputBytes(w, []byte(sanitize(string(res))), reqID) + fc.responder.OutputBytes(w, res, reqID) } func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { @@ -161,5 +161,5 @@ func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { fc.responder.ErrorBadRequest(w, err, reqID) return } - fc.responder.OutputJSON(w, sanitize(url), reqID) + fc.responder.OutputJSON(w, url, reqID) } From 44ca73f6e9293a0b1116d89386a3dd3a2ec19ed9 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Wed, 18 Dec 2024 11:27:31 +0300 Subject: [PATCH 117/135] fix sanitize --- go.mod | 4 ++-- internal/auth/controller/controller.go | 13 +++++++----- internal/chat/controller/client.go | 21 +++++++++++++++++-- internal/chat/controller/controller.go | 9 ++++---- internal/chat/controller/controller_test.go | 7 +++++++ internal/community/controller/controller.go | 12 +++++------ internal/post/controller/controller.go | 23 +++++++++++---------- internal/profile/controller/controller.go | 9 ++++---- internal/stickers/controller/controller.go | 2 -- 9 files changed, 63 insertions(+), 37 deletions(-) diff --git a/go.mod b/go.mod index 7b281808..95021e12 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,8 @@ require ( github.com/jackc/pgx/v5 v5.7.1 github.com/joho/godotenv v1.5.1 github.com/lib/pq v1.10.9 + github.com/mailru/easyjson v0.7.7 + github.com/microcosm-cc/bluemonday v1.0.27 github.com/prometheus/client_golang v1.20.5 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 @@ -38,8 +40,6 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.17.9 // indirect github.com/kr/text v0.2.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/microcosm-cc/bluemonday v1.0.27 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/internal/auth/controller/controller.go b/internal/auth/controller/controller.go index 1370e47a..96aaca2f 100644 --- a/internal/auth/controller/controller.go +++ b/internal/auth/controller/controller.go @@ -64,13 +64,15 @@ func (c *AuthController) Register(w http.ResponseWriter, r *http.Request) { user := models.User{} err := easyjson.UnmarshalFromReader(r.Body, &user) - user.FirstName = sanitize(user.FirstName) - user.LastName = sanitize(user.LastName) - user.Email = sanitize(user.Email) if err != nil { c.responder.ErrorBadRequest(w, fmt.Errorf("router register: %w", err), reqID) return } + + user.FirstName = sanitize(user.FirstName) + user.LastName = sanitize(user.LastName) + user.Email = sanitize(user.Email) + if !validate(user) { c.responder.ErrorBadRequest(w, my_err.ErrBadUserInfo, reqID) return @@ -118,12 +120,13 @@ func (c *AuthController) Auth(w http.ResponseWriter, r *http.Request) { user := models.User{} err := easyjson.UnmarshalFromReader(r.Body, &user) - user.Email = sanitize(user.Email) - user.Password = sanitize(user.Password) if err != nil { c.responder.ErrorBadRequest(w, fmt.Errorf("router auth: %w", err), reqID) return } + user.Email = sanitize(user.Email) + user.Password = sanitize(user.Password) + if !validateAuth(user) { c.responder.ErrorBadRequest(w, my_err.ErrBadUserInfo, reqID) return diff --git a/internal/chat/controller/client.go b/internal/chat/controller/client.go index 30e6123d..35d2fd19 100644 --- a/internal/chat/controller/client.go +++ b/internal/chat/controller/client.go @@ -25,22 +25,36 @@ func sanitize(input string) string { return cleaned } +func sanitizeFiles(input []string) []string { + var output []string + for _, f := range input { + res := sanitize(f) + if res != "" { + output = append(output, res) + } + } + + return output +} + func (c *Client) Read(userID uint32) { defer c.Socket.Close() for { msg := &models.Message{} _, jsonMessage, err := c.Socket.ReadMessage() - clearJson := sanitize(string(jsonMessage)) if err != nil { c.chatController.responder.LogError(fmt.Errorf("read message: %w", err), wc) return } - err = easyjson.Unmarshal([]byte(clearJson), msg) + err = easyjson.Unmarshal(jsonMessage, msg) if err != nil { c.chatController.responder.LogError(err, wc) return } + msg.Content.Text = sanitize(msg.Content.Text) + msg.Content.FilePath = sanitizeFiles(msg.Content.FilePath) + msg.Content.StickerPath = sanitize(msg.Content.StickerPath) msg.Sender = userID c.chatController.Messages <- msg } @@ -50,6 +64,9 @@ func (c *Client) Write() { defer c.Socket.Close() for msg := range c.Receive { msg.CreatedAt = time.Now() + msg.Content.Text = sanitize(msg.Content.Text) + msg.Content.FilePath = sanitizeFiles(msg.Content.FilePath) + msg.Content.StickerPath = sanitize(msg.Content.StickerPath) jsonForSend, err := easyjson.Marshal(msg) if err != nil { c.chatController.responder.LogError(err, wc) diff --git a/internal/chat/controller/controller.go b/internal/chat/controller/controller.go index 1690cb40..577eeaeb 100644 --- a/internal/chat/controller/controller.go +++ b/internal/chat/controller/controller.go @@ -129,7 +129,7 @@ func (cc *ChatController) SendChatMsg(ctx context.Context, reqID string, w http. func (cc *ChatController) GetAllChats(w http.ResponseWriter, r *http.Request) { var ( reqID, ok = r.Context().Value(middleware.RequestKey).(string) - lastTimeQuery = r.URL.Query().Get("lastTime") + lastTimeQuery = sanitize(r.URL.Query().Get("lastTime")) lastTime time.Time err error ) @@ -170,13 +170,12 @@ func (cc *ChatController) GetAllChats(w http.ResponseWriter, r *http.Request) { func GetIdFromURL(r *http.Request) (uint32, error) { vars := mux.Vars(r) - id := vars["id"] + id := sanitize(vars["id"]) if id == "" { return 0, my_err.ErrEmptyId } - clearId := sanitize(id) - uid, err := strconv.ParseUint(clearId, 10, 32) + uid, err := strconv.ParseUint(id, 10, 32) if err != nil { return 0, err } @@ -189,7 +188,7 @@ func GetIdFromURL(r *http.Request) (uint32, error) { func (cc *ChatController) GetChat(w http.ResponseWriter, r *http.Request) { var ( reqID, ok = r.Context().Value(middleware.RequestKey).(string) - lastTimeQuery = r.URL.Query().Get("lastTime") + lastTimeQuery = sanitize(r.URL.Query().Get("lastTime")) lastTime time.Time err error ) diff --git a/internal/chat/controller/controller_test.go b/internal/chat/controller/controller_test.go index 76192d8f..b69cf3ab 100644 --- a/internal/chat/controller/controller_test.go +++ b/internal/chat/controller/controller_test.go @@ -43,6 +43,13 @@ func TestSanitize(t *testing.T) { assert.Equal(t, expected, res) } +func TestSanitizeFiles(t *testing.T) { + test := []string{""} + var expected []string + res := sanitizeFiles(test) + assert.Equal(t, expected, res) +} + func TestGetAllChat(t *testing.T) { tests := []TableTest[Response, Request]{ { diff --git a/internal/community/controller/controller.go b/internal/community/controller/controller.go index 407e69ba..99441619 100644 --- a/internal/community/controller/controller.go +++ b/internal/community/controller/controller.go @@ -392,26 +392,26 @@ func (c *Controller) getCommunityFromBody(r *http.Request) (models.Community, er if err != nil { return models.Community{}, err } - if !validate(res) { - return models.Community{}, my_err.ErrBadCommunity - } res.Avatar = models.Picture(sanitize(string(res.Avatar))) res.Name = sanitize(res.Name) res.About = sanitize(res.About) + if !validate(res) { + return models.Community{}, my_err.ErrBadCommunity + } + return res, nil } func getIDFromQuery(r *http.Request) (uint32, error) { vars := mux.Vars(r) - id := vars["id"] + id := sanitize(vars["id"]) if id == "" { return 0, errors.New("id is empty") } - clearID := sanitize(id) - uid, err := strconv.ParseUint(clearID, 10, 32) + uid, err := strconv.ParseUint(id, 10, 32) if err != nil { return 0, err } diff --git a/internal/post/controller/controller.go b/internal/post/controller/controller.go index 3985c5b9..68fe211d 100644 --- a/internal/post/controller/controller.go +++ b/internal/post/controller/controller.go @@ -369,6 +369,11 @@ func (pc *PostController) getPostFromBody(r *http.Request) (*models.PostDto, err return nil, err } + newPost.PostContent.Text = sanitize(newPost.PostContent.Text) + newPost.PostContent.File = sanitizeFiles(newPost.PostContent.File) + newPost.Header.Avatar = models.Picture(sanitize(string(newPost.Header.Avatar))) + newPost.Header.Author = sanitize(newPost.Header.Author) + if !validateContent(newPost.PostContent) { return nil, my_err.ErrBadPostOrComment } @@ -380,11 +385,6 @@ func (pc *PostController) getPostFromBody(r *http.Request) (*models.PostDto, err newPost.Header.AuthorID = sess.UserID post := newPost.ToDto() - post.PostContent.Text = sanitize(post.PostContent.Text) - post.PostContent.File = models.Picture(sanitize(string(post.PostContent.File))) - post.Header.Avatar = models.Picture(sanitize(string(post.Header.Avatar))) - post.Header.Author = sanitize(post.Header.Author) - return &post, nil } @@ -392,10 +392,10 @@ func getIDFromURL(r *http.Request, key string) (uint32, error) { vars := mux.Vars(r) id := vars[key] - if id == "" { + clearID := sanitize(id) + if clearID == "" { return 0, errors.New("id is empty") } - clearID := sanitize(id) uid, err := strconv.ParseUint(clearID, 10, 32) if err != nil { @@ -407,11 +407,11 @@ func getIDFromURL(r *http.Request, key string) (uint32, error) { func getLastID(r *http.Request) (uint64, error) { lastID := r.URL.Query().Get("id") - - if lastID == "" { + clearLastID := sanitize(lastID) + if clearLastID == "" { return math.MaxInt32, nil } - clearLastID := sanitize(lastID) + intLastID, err := strconv.ParseUint(clearLastID, 10, 32) if err != nil { return 0, err @@ -549,6 +549,7 @@ func (pc *PostController) Comment(w http.ResponseWriter, r *http.Request) { } content.Text = sanitize(content.Text) + content.File = sanitizeFiles(content.File) if !validateContent(content) { pc.responder.ErrorBadRequest(w, my_err.ErrBadPostOrComment, reqID) @@ -632,6 +633,7 @@ func (pc *PostController) EditComment(w http.ResponseWriter, r *http.Request) { } content.Text = sanitize(content.Text) + content.File = sanitizeFiles(content.File) if !validateContent(content) { pc.responder.ErrorBadRequest(w, my_err.ErrBadPostOrComment, reqID) @@ -700,7 +702,6 @@ func (pc *PostController) GetComments(w http.ResponseWriter, r *http.Request) { } for _, newComment := range res { - newComment.Content.CreatedAt = time.Now() newComment.Content.Text = sanitize(newComment.Content.Text) newComment.Content.File = sanitizeFiles(newComment.Content.File) newComment.Header.Avatar = models.Picture(sanitize(string(newComment.Header.Avatar))) diff --git a/internal/profile/controller/controller.go b/internal/profile/controller/controller.go index d3cf1f7d..b7daa92f 100644 --- a/internal/profile/controller/controller.go +++ b/internal/profile/controller/controller.go @@ -194,13 +194,12 @@ func (h *ProfileHandlerImplementation) DeleteProfile(w http.ResponseWriter, r *h func GetIdFromURL(r *http.Request) (uint32, error) { vars := mux.Vars(r) - id := vars["id"] + id := sanitize(vars["id"]) if id == "" { return 0, my_err.ErrEmptyId } - clearID := sanitize(id) - uid, err := strconv.ParseUint(clearID, 10, 32) + uid, err := strconv.ParseUint(id, 10, 32) if err != nil { return 0, err } @@ -234,8 +233,8 @@ func (h *ProfileHandlerImplementation) GetProfileById(w http.ResponseWriter, r * h.Responder.ErrorInternal(w, err, reqID) return } - sanitizeProfile(uprofile) + sanitizeProfile(uprofile) h.Responder.OutputJSON(w, uprofile, reqID) } @@ -281,6 +280,7 @@ func (h *ProfileHandlerImplementation) GetAll(w http.ResponseWriter, r *http.Req h.Responder.OutputNoMoreContentJSON(w, reqID) return } + sanitizeProfiles(profiles) h.Responder.OutputJSON(w, profiles, reqID) } @@ -452,6 +452,7 @@ func (h *ProfileHandlerImplementation) GetAllSubs(w http.ResponseWriter, r *http h.Responder.OutputNoMoreContentJSON(w, reqID) return } + sanitizeProfiles(profiles) h.Responder.OutputJSON(w, profiles, reqID) } diff --git a/internal/stickers/controller/controller.go b/internal/stickers/controller/controller.go index 5895311e..152f2b7b 100644 --- a/internal/stickers/controller/controller.go +++ b/internal/stickers/controller/controller.go @@ -3,7 +3,6 @@ package controller import ( "encoding/json" "errors" - "fmt" "net/http" "strings" @@ -61,7 +60,6 @@ func (s StickersHandlerImplementation) AddNewSticker(w http.ResponseWriter, r *h filePath := models.StickerRequest{} if err := json.NewDecoder(r.Body).Decode(&filePath); err != nil { s.Responder.ErrorBadRequest(w, my_err.ErrNoFile, reqID) - fmt.Println(err) return } From 43bd299c1ccc655ab40f9057cea9fdcda307f862 Mon Sep 17 00:00:00 2001 From: slashlight Date: Wed, 18 Dec 2024 11:47:01 +0300 Subject: [PATCH 118/135] bugfix: fixed msg sanitizing --- internal/chat/controller/client.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/chat/controller/client.go b/internal/chat/controller/client.go index 35d2fd19..89e84fcb 100644 --- a/internal/chat/controller/client.go +++ b/internal/chat/controller/client.go @@ -55,6 +55,9 @@ func (c *Client) Read(userID uint32) { msg.Content.Text = sanitize(msg.Content.Text) msg.Content.FilePath = sanitizeFiles(msg.Content.FilePath) msg.Content.StickerPath = sanitize(msg.Content.StickerPath) + if msg.Content.Text == "" && msg.Content.StickerPath == "" && len(msg.Content.FilePath) == 0 { + msg.Content.Text = "Я хотел отправить XSS" + } msg.Sender = userID c.chatController.Messages <- msg } From 9354cc8e84221f700003087259993b40d38a5a58 Mon Sep 17 00:00:00 2001 From: slashlight Date: Wed, 18 Dec 2024 11:50:43 +0300 Subject: [PATCH 119/135] bugfix: fixed msg sanitizing --- internal/chat/controller/client.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/chat/controller/client.go b/internal/chat/controller/client.go index 89e84fcb..35d2fd19 100644 --- a/internal/chat/controller/client.go +++ b/internal/chat/controller/client.go @@ -55,9 +55,6 @@ func (c *Client) Read(userID uint32) { msg.Content.Text = sanitize(msg.Content.Text) msg.Content.FilePath = sanitizeFiles(msg.Content.FilePath) msg.Content.StickerPath = sanitize(msg.Content.StickerPath) - if msg.Content.Text == "" && msg.Content.StickerPath == "" && len(msg.Content.FilePath) == 0 { - msg.Content.Text = "Я хотел отправить XSS" - } msg.Sender = userID c.chatController.Messages <- msg } From 532f89745f739423e041c389c63078a59f9acbe4 Mon Sep 17 00:00:00 2001 From: slashlight Date: Wed, 18 Dec 2024 12:04:08 +0300 Subject: [PATCH 120/135] bugfix: fixed friends accepting --- internal/profile/repository/QueryConsts.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/profile/repository/QueryConsts.go b/internal/profile/repository/QueryConsts.go index 317cfb8a..bfa5966a 100644 --- a/internal/profile/repository/QueryConsts.go +++ b/internal/profile/repository/QueryConsts.go @@ -13,7 +13,7 @@ const ( UpdateProfileAvatar = "UPDATE profile SET avatar = $2, first_name = $3, last_name = $4, bio = $5 WHERE id = $1;" DeleteProfile = "DELETE FROM profile WHERE id = $1;" AddFriends = "INSERT INTO friend(sender, receiver, status) VALUES ($1, $2, 1);" - AcceptFriendReq = "UPDATE friend SET status = 0 WHERE sender = $1 AND receiver = $2;" + AcceptFriendReq = "UPDATE friend SET status = 0 WHERE (sender = $1 AND receiver = $2) OR (sender = $2 AND receiver = $1);" RemoveFriendsReq = "UPDATE friend SET status = ( CASE WHEN sender = $1 THEN -1 ELSE 1 END) WHERE (receiver = $1 AND sender = $2) OR (sender = $1 AND receiver = $2);" GetAllFriends = "WITH friends AS (SELECT sender AS friend FROM friend WHERE (receiver = $1 AND status = 0) UNION SELECT receiver AS friend FROM friend WHERE (sender = $1 AND status = 0)) SELECT profile.id, first_name, last_name, avatar FROM profile INNER JOIN friends ON friend = profile.id WHERE profile.id > $2 ORDER BY profile.id LIMIT $3;" GetAllSubs = "WITH subs AS ( SELECT sender AS subscriber FROM friend WHERE (receiver = $1 AND status = 1) UNION SELECT receiver AS subscriber FROM friend WHERE (sender = $1 AND status = -1)) SELECT profile.id, first_name, last_name, avatar FROM profile INNER JOIN subs ON subscriber = profile.id WHERE profile.id > $2 ORDER BY profile.id LIMIT $3;" From 2e63a6cfc48469015464fa5c41c6c47b0b736903 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Wed, 18 Dec 2024 15:02:32 +0300 Subject: [PATCH 121/135] detect type with http.Detected --- internal/fileService/controller/controller.go | 35 ++++++++++++++----- internal/fileService/controller/mock.go | 6 ++-- internal/fileService/service/fileService.go | 5 ++- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index 0e551121..ab5baebc 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -1,9 +1,11 @@ package controller import ( + "bytes" "context" "errors" "fmt" + "io" "mime/multipart" "net/http" "strings" @@ -26,8 +28,8 @@ var fileFormat = map[string]struct{}{ //go:generate mockgen -destination=mock.go -source=$GOFILE -package=${GOPACKAGE} type fileService interface { Upload(ctx context.Context, name string) ([]byte, error) - Download(ctx context.Context, file multipart.File, format string) (string, error) - DownloadNonImage(ctx context.Context, file multipart.File, format, realName string) (string, error) + Download(ctx context.Context, file io.Reader, format string) (string, error) + DownloadNonImage(ctx context.Context, file io.Reader, format, realName string) (string, error) UploadNonImage(ctx context.Context, name string) ([]byte, error) } @@ -51,6 +53,17 @@ func NewFileController(fileService fileService, responder responder) *FileContro } } +func getFormat(buf []byte) string { + formats := http.DetectContentType(buf) + format := strings.Split(formats, "/")[1] + + if strings.HasPrefix(format, "plain") { + format = "txt" + } + + return format +} + func sanitize(input string) string { sanitizer := bluemonday.UGCPolicy() cleaned := sanitizer.Sanitize(input) @@ -138,23 +151,29 @@ func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { } }(file) - formats := strings.Split(header.Header.Get("Content-Type"), "/") - if len(formats) != 2 { - fc.responder.ErrorBadRequest(w, my_err.ErrWrongFiletype, reqID) + buf := bytes.NewBuffer(make([]byte, 20)) + n, err := file.Read(buf.Bytes()) + if err != nil { + fc.responder.ErrorBadRequest(w, err, reqID) return } + format := getFormat(buf.Bytes()[:n]) + + _, err = io.Copy(buf, file) + if err != nil { + fc.responder.ErrorBadRequest(w, err, reqID) + } var url string - format := formats[1] if _, ok := fileFormat[format]; ok { - url, err = fc.fileService.Download(r.Context(), file, format) + url, err = fc.fileService.Download(r.Context(), buf, format) } else { name := header.Filename if len(name+format) > 55 { fc.responder.ErrorBadRequest(w, errors.New("file name is too big"), reqID) return } - url, err = fc.fileService.DownloadNonImage(r.Context(), file, format, name) + url, err = fc.fileService.DownloadNonImage(r.Context(), buf, format, name) } if err != nil { diff --git a/internal/fileService/controller/mock.go b/internal/fileService/controller/mock.go index 816a55a1..76b8237e 100644 --- a/internal/fileService/controller/mock.go +++ b/internal/fileService/controller/mock.go @@ -11,7 +11,7 @@ package controller import ( context "context" - multipart "mime/multipart" + io "io" http "net/http" reflect "reflect" @@ -43,7 +43,7 @@ func (m *MockfileService) EXPECT() *MockfileServiceMockRecorder { } // Download mocks base method. -func (m *MockfileService) Download(ctx context.Context, file multipart.File, format string) (string, error) { +func (m *MockfileService) Download(ctx context.Context, file io.Reader, format string) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Download", ctx, file, format) ret0, _ := ret[0].(string) @@ -58,7 +58,7 @@ func (mr *MockfileServiceMockRecorder) Download(ctx, file, format any) *gomock.C } // DownloadNonImage mocks base method. -func (m *MockfileService) DownloadNonImage(ctx context.Context, file multipart.File, format, realName string) (string, error) { +func (m *MockfileService) DownloadNonImage(ctx context.Context, file io.Reader, format, realName string) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DownloadNonImage", ctx, file, format, realName) ret0, _ := ret[0].(string) diff --git a/internal/fileService/service/fileService.go b/internal/fileService/service/fileService.go index b2eb0cc3..fab9845c 100644 --- a/internal/fileService/service/fileService.go +++ b/internal/fileService/service/fileService.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "io" - "mime/multipart" "os" "github.com/google/uuid" @@ -16,7 +15,7 @@ func NewFileService() *FileService { return &FileService{} } -func (f *FileService) Download(ctx context.Context, file multipart.File, format string) (string, error) { +func (f *FileService) Download(ctx context.Context, file io.Reader, format string) (string, error) { var ( fileName = uuid.New().String() filePath = fmt.Sprintf("/image/%s.%s", fileName, format) @@ -38,7 +37,7 @@ func (f *FileService) Download(ctx context.Context, file multipart.File, format } func (f *FileService) DownloadNonImage( - ctx context.Context, file multipart.File, format, realName string, + ctx context.Context, file io.Reader, format, realName string, ) (string, error) { var ( fileName = uuid.New().String() From 565e242c6f4af6b64ee7ae47e3b32b570f312d61 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Wed, 18 Dec 2024 15:19:30 +0300 Subject: [PATCH 122/135] add test --- internal/fileService/controller/controller.go | 14 ++++++++++++-- .../fileService/controller/controller_test.go | 17 +++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index ab5baebc..6051c78c 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -25,6 +25,12 @@ var fileFormat = map[string]struct{}{ "gif": {}, } +const ( + charset = "charset=utf" + txt = "txt" + plain = "plain" +) + //go:generate mockgen -destination=mock.go -source=$GOFILE -package=${GOPACKAGE} type fileService interface { Upload(ctx context.Context, name string) ([]byte, error) @@ -57,8 +63,12 @@ func getFormat(buf []byte) string { formats := http.DetectContentType(buf) format := strings.Split(formats, "/")[1] - if strings.HasPrefix(format, "plain") { - format = "txt" + if strings.Contains(format, charset) { + format = strings.Split(format, ";")[0] + } + + if format == plain { + format = txt } return format diff --git a/internal/fileService/controller/controller_test.go b/internal/fileService/controller/controller_test.go index 0f811e18..c5b4546f 100644 --- a/internal/fileService/controller/controller_test.go +++ b/internal/fileService/controller/controller_test.go @@ -391,6 +391,23 @@ func TestDownload(t *testing.T) { } } +func TestGetFormat(t *testing.T) { + tests := []struct { + input []byte + output string + }{ + {input: []byte("some text"), output: "txt"}, + {input: []byte(""), output: "html"}, + } + + for i, tt := range tests { + actual := getFormat(tt.input) + if actual != tt.output { + t.Errorf("%d: expected %s, got %s", i, tt.output, actual) + } + } +} + type Request struct { w *httptest.ResponseRecorder r *http.Request From 733ce44992c431b9fba2d2b8890358985c5b2ddc Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Wed, 18 Dec 2024 19:27:41 +0300 Subject: [PATCH 123/135] fix max memmory file --- internal/fileService/controller/controller.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index 6051c78c..f74be875 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -136,7 +136,7 @@ func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { fc.responder.LogError(my_err.ErrInvalidContext, "") } - err := r.ParseMultipartForm(10 * (10 << 20)) // 100Mbyte + err := r.ParseMultipartForm(100 * (1 << 23)) // 100Mbyte if err != nil { fc.responder.ErrorBadRequest(w, my_err.ErrToLargeFile, reqID) return From dedc21462fc073c3145b8d0be2bfb2308019892a Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Wed, 18 Dec 2024 20:00:26 +0300 Subject: [PATCH 124/135] fix file size --- internal/fileService/controller/controller.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index f74be875..45ca2ede 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -26,9 +26,10 @@ var fileFormat = map[string]struct{}{ } const ( - charset = "charset=utf" - txt = "txt" - plain = "plain" + charset = "charset=utf" + txt = "txt" + plain = "plain" + maxMemory = 10 * 1024 * 1024 ) //go:generate mockgen -destination=mock.go -source=$GOFILE -package=${GOPACKAGE} @@ -136,7 +137,7 @@ func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { fc.responder.LogError(my_err.ErrInvalidContext, "") } - err := r.ParseMultipartForm(100 * (1 << 23)) // 100Mbyte + err := r.ParseMultipartForm(maxMemory) // 100Mbyte if err != nil { fc.responder.ErrorBadRequest(w, my_err.ErrToLargeFile, reqID) return From f3e891c8839a03232ccaac4c826b1babc29b3110 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Wed, 18 Dec 2024 20:16:43 +0300 Subject: [PATCH 125/135] fix size to 100Mb --- internal/fileService/controller/controller.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index 45ca2ede..a741a07b 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -29,7 +29,7 @@ const ( charset = "charset=utf" txt = "txt" plain = "plain" - maxMemory = 10 * 1024 * 1024 + maxMemory = 100 * 1024 * 1024 ) //go:generate mockgen -destination=mock.go -source=$GOFILE -package=${GOPACKAGE} From f890abd8158cd52a46447a4500e2325f8ba122c0 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Thu, 19 Dec 2024 21:05:41 +0300 Subject: [PATCH 126/135] fix test makefile --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fd4add19..41949239 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,8 @@ test: - go test -v ./... -coverprofile=cover.out && go tool cover -html=cover.out -o cover.html + go test ./... -coverprofile=cover.out \ + && go tool cover -func=cover.out | grep -vE "*mock.go|*easyjson.go|*pb.go|*mock_helper.go" \ + && go tool cover -html=cover.out -o cover.html + start: docker compose up --build From 0d2401337ca017dc172a9b837bb0bd912e922e2a Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Fri, 20 Dec 2024 21:25:13 +0300 Subject: [PATCH 127/135] fix: get one --- internal/community/controller/controller.go | 4 ++++ internal/community/repository/repository.go | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/internal/community/controller/controller.go b/internal/community/controller/controller.go index 99441619..cd9e9a60 100644 --- a/internal/community/controller/controller.go +++ b/internal/community/controller/controller.go @@ -77,6 +77,10 @@ func (c *Controller) GetOne(w http.ResponseWriter, r *http.Request) { community, err := c.service.GetOne(r.Context(), id, sess.UserID) if err != nil { + if errors.Is(err, my_err.ErrWrongCommunity) { + c.responder.ErrorBadRequest(w, err, reqID) + return + } c.responder.ErrorInternal(w, err, reqID) return } diff --git a/internal/community/repository/repository.go b/internal/community/repository/repository.go index 751b09ce..8cdd15fc 100644 --- a/internal/community/repository/repository.go +++ b/internal/community/repository/repository.go @@ -45,8 +45,13 @@ func (c CommunityRepository) GetBatch(ctx context.Context, lastID uint32) ([]*mo func (c CommunityRepository) GetOne(ctx context.Context, id uint32) (*models.Community, error) { res := &models.Community{} - err := c.db.QueryRowContext(ctx, GetOne, id).Scan(&res.ID, &res.Name, &res.Avatar, &res.About, &res.CountSubscribers) + err := c.db.QueryRowContext(ctx, GetOne, id).Scan( + &res.ID, &res.Name, &res.Avatar, &res.About, &res.CountSubscribers, + ) if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, my_err.ErrWrongCommunity + } return nil, fmt.Errorf("get community db: %w", err) } @@ -59,7 +64,9 @@ func (c CommunityRepository) Create(ctx context.Context, community *models.Commu if community.Avatar == "" { res = c.db.QueryRowContext(ctx, CreateNewCommunity, community.Name, community.About, author) } else { - res = c.db.QueryRowContext(ctx, CreateNewCommunityWithAvatar, community.Name, community.About, community.Avatar, author) + res = c.db.QueryRowContext( + ctx, CreateNewCommunityWithAvatar, community.Name, community.About, community.Avatar, author, + ) } err := res.Err() @@ -80,7 +87,9 @@ func (c CommunityRepository) Update(ctx context.Context, community *models.Commu if community.Avatar == "" { _, err = c.db.ExecContext(ctx, UpdateWithoutAvatar, community.Name, community.About, community.ID) } else { - _, err = c.db.ExecContext(ctx, UpdateWithAvatar, community.Name, community.Avatar, community.About, community.ID) + _, err = c.db.ExecContext( + ctx, UpdateWithAvatar, community.Name, community.Avatar, community.About, community.ID, + ) } if err != nil { return fmt.Errorf("update community: %w", err) From 7849c561bdedada39f89f204815f813aac87bb6c Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Fri, 20 Dec 2024 21:30:39 +0300 Subject: [PATCH 128/135] fix: wrong id community check now --- internal/community/controller/controller.go | 16 ++++++++++++++++ internal/community/repository/repository.go | 18 ++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/internal/community/controller/controller.go b/internal/community/controller/controller.go index cd9e9a60..74cd71b3 100644 --- a/internal/community/controller/controller.go +++ b/internal/community/controller/controller.go @@ -173,6 +173,10 @@ func (c *Controller) Update(w http.ResponseWriter, r *http.Request) { err = c.service.Update(r.Context(), id, &newCommunity) if err != nil { + if errors.Is(err, my_err.ErrWrongCommunity) { + c.responder.ErrorBadRequest(w, err, reqID) + return + } c.responder.ErrorInternal(w, err, reqID) return } @@ -209,6 +213,10 @@ func (c *Controller) Delete(w http.ResponseWriter, r *http.Request) { err = c.service.Delete(r.Context(), id) if err != nil { + if errors.Is(err, my_err.ErrWrongCommunity) { + c.responder.ErrorBadRequest(w, err, reqID) + return + } c.responder.ErrorInternal(w, err, reqID) return } @@ -263,6 +271,10 @@ func (c *Controller) JoinToCommunity(w http.ResponseWriter, r *http.Request) { err = c.service.JoinCommunity(r.Context(), id, sess.UserID) if err != nil { + if errors.Is(err, my_err.ErrWrongCommunity) { + c.responder.ErrorBadRequest(w, err, reqID) + return + } c.responder.ErrorInternal(w, err, reqID) return } @@ -290,6 +302,10 @@ func (c *Controller) LeaveFromCommunity(w http.ResponseWriter, r *http.Request) err = c.service.LeaveCommunity(r.Context(), id, sess.UserID) if err != nil { + if errors.Is(err, my_err.ErrWrongCommunity) { + c.responder.ErrorBadRequest(w, err, reqID) + return + } c.responder.ErrorInternal(w, err, reqID) return } diff --git a/internal/community/repository/repository.go b/internal/community/repository/repository.go index 8cdd15fc..397470b2 100644 --- a/internal/community/repository/repository.go +++ b/internal/community/repository/repository.go @@ -92,6 +92,9 @@ func (c CommunityRepository) Update(ctx context.Context, community *models.Commu ) } if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return my_err.ErrWrongCommunity + } return fmt.Errorf("update community: %w", err) } @@ -101,6 +104,9 @@ func (c CommunityRepository) Update(ctx context.Context, community *models.Commu func (c CommunityRepository) Delete(ctx context.Context, id uint32) error { _, err := c.db.ExecContext(ctx, Delete, id) if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return my_err.ErrWrongCommunity + } return fmt.Errorf("delete community: %w", err) } @@ -110,6 +116,9 @@ func (c CommunityRepository) Delete(ctx context.Context, id uint32) error { func (c CommunityRepository) JoinCommunity(ctx context.Context, communityId, author uint32) error { _, err := c.db.ExecContext(ctx, JoinCommunity, communityId, author) if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return my_err.ErrWrongCommunity + } return fmt.Errorf("join community: %w", err) } @@ -119,6 +128,9 @@ func (c CommunityRepository) JoinCommunity(ctx context.Context, communityId, aut func (c CommunityRepository) LeaveCommunity(ctx context.Context, communityId, author uint32) error { _, err := c.db.ExecContext(ctx, LeaveCommunity, communityId, author) if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return my_err.ErrWrongCommunity + } return fmt.Errorf("leave community: %w", err) } access := c.CheckAccess(ctx, communityId, author) @@ -126,6 +138,9 @@ func (c CommunityRepository) LeaveCommunity(ctx context.Context, communityId, au if access { _, err := c.db.ExecContext(ctx, DeleteAdmin, communityId, author) if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return my_err.ErrWrongCommunity + } return fmt.Errorf("delete admin: %w", err) } } @@ -136,6 +151,9 @@ func (c CommunityRepository) LeaveCommunity(ctx context.Context, communityId, au func (c CommunityRepository) NewAdmin(ctx context.Context, communityId uint32, author uint32) error { _, err := c.db.ExecContext(ctx, InsertNewAdmin, communityId, author) if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return my_err.ErrWrongCommunity + } return fmt.Errorf("insert new admin: %w", err) } return nil From d176163012cae7c5bcc59127365bf7dd73ea1192 Mon Sep 17 00:00:00 2001 From: slashlight Date: Fri, 20 Dec 2024 22:48:06 +0300 Subject: [PATCH 129/135] bugfix: fixed get all friends --- internal/profile/repository/QueryConsts.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/profile/repository/QueryConsts.go b/internal/profile/repository/QueryConsts.go index bfa5966a..904335e4 100644 --- a/internal/profile/repository/QueryConsts.go +++ b/internal/profile/repository/QueryConsts.go @@ -8,7 +8,7 @@ const ( GetProfileByID = "SELECT profile.id, first_name, last_name, bio, avatar FROM profile WHERE profile.id = $1 LIMIT 1;" GetStatus = "SELECT status FROM friend WHERE (sender = $1 AND receiver = $2) LIMIT 1" - GetAllProfilesBatch = "WITH friends AS (SELECT sender AS friend FROM friend WHERE (receiver = $1 AND status = 0) UNION SELECT receiver AS friend FROM friend WHERE (sender = $1 AND status = 0)), subscriptions AS (SELECT sender AS subscription FROM friend WHERE (receiver = $1 AND status = -1) UNION SELECT receiver AS subscriber FROM friend WHERE (sender = $1 AND status = 1)) SELECT p.id, first_name, last_name, avatar FROM profile p WHERE p.id <> $1 AND p.id > $2 AND p.id NOT IN (SELECT friend FROM friends) AND p.id NOT IN (SELECT subscription FROM subscriptions) ORDER BY p.id LIMIT $3;" + GetAllProfilesBatch = "WITH friends AS (SELECT sender AS friend FROM friend WHERE (receiver = $1 AND status = 0) UNION SELECT receiver AS friend FROM friend WHERE (sender = $1 AND status = 0)), subscriptions AS (SELECT sender AS subscription FROM friend WHERE (receiver = $1 AND status = -1) UNION SELECT receiver AS subscription FROM friend WHERE (sender = $1 AND status = 1)), subscribers AS (SELECT sender AS subscriber FROM friend WHERE (receiver = $1 AND status = 1) UNION SELECT receiver AS subscriber FROM friend WHERE (sender = $1 AND status = -1)) SELECT p.id, first_name, last_name, avatar FROM profile p WHERE p.id <> $1 AND p.id > $2 AND p.id NOT IN (SELECT friend FROM friends) AND p.id NOT IN (SELECT subscription FROM subscriptions) AND p.id NOT IN (SELECT subscriber FROM subscribers) ORDER BY p.id LIMIT $3;" UpdateProfile = "UPDATE profile SET first_name = $1, last_name = $2, bio = $3 WHERE id = $4;" UpdateProfileAvatar = "UPDATE profile SET avatar = $2, first_name = $3, last_name = $4, bio = $5 WHERE id = $1;" DeleteProfile = "DELETE FROM profile WHERE id = $1;" From 0bd6d70b14e6283e222eafd60b876dc24aa667d2 Mon Sep 17 00:00:00 2001 From: Alexeyzem <92686279+Alexeyzem@users.noreply.github.com> Date: Sat, 21 Dec 2024 00:27:32 +0300 Subject: [PATCH 130/135] Update controller.go --- internal/fileService/controller/controller.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index a741a07b..a99280df 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -172,7 +172,8 @@ func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { _, err = io.Copy(buf, file) if err != nil { - fc.responder.ErrorBadRequest(w, err, reqID) + fc.responder.ErrorBadRequest(w, err, reqID + return } var url string @@ -180,7 +181,7 @@ func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { url, err = fc.fileService.Download(r.Context(), buf, format) } else { name := header.Filename - if len(name+format) > 55 { + if len([]rune(name+format)) > 55 { fc.responder.ErrorBadRequest(w, errors.New("file name is too big"), reqID) return } From 529c84b1de06c66dfa3431298a27ac4f9cd2a16c Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sat, 21 Dec 2024 00:30:25 +0300 Subject: [PATCH 131/135] hotfix --- internal/fileService/controller/controller.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index a99280df..325e3ed2 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -172,7 +172,7 @@ func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { _, err = io.Copy(buf, file) if err != nil { - fc.responder.ErrorBadRequest(w, err, reqID + fc.responder.ErrorBadRequest(w, err, reqID) return } var url string From eae6f4e0a40c55a7ce5a93f3dabc4a9848c63247 Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sat, 21 Dec 2024 00:43:29 +0300 Subject: [PATCH 132/135] fix file len --- internal/fileService/controller/controller.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/fileService/controller/controller.go b/internal/fileService/controller/controller.go index 325e3ed2..51ad745a 100644 --- a/internal/fileService/controller/controller.go +++ b/internal/fileService/controller/controller.go @@ -181,7 +181,7 @@ func (fc *FileController) Download(w http.ResponseWriter, r *http.Request) { url, err = fc.fileService.Download(r.Context(), buf, format) } else { name := header.Filename - if len([]rune(name+format)) > 55 { + if len([]rune(name+format)) > 53 { fc.responder.ErrorBadRequest(w, errors.New("file name is too big"), reqID) return } From 25ca82d144cb0b87511ebb277b0d60f8ba37d18c Mon Sep 17 00:00:00 2001 From: Alexeyzem Date: Sat, 21 Dec 2024 09:38:31 +0300 Subject: [PATCH 133/135] fix get profile --- internal/profile/repository/QueryConsts.go | 2 +- internal/profile/repository/postgres.go | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/internal/profile/repository/QueryConsts.go b/internal/profile/repository/QueryConsts.go index 904335e4..efe49bdc 100644 --- a/internal/profile/repository/QueryConsts.go +++ b/internal/profile/repository/QueryConsts.go @@ -7,7 +7,7 @@ const ( ChangePassword = `UPDATE profile SET hashed_password = $1 WHERE id = $2;` GetProfileByID = "SELECT profile.id, first_name, last_name, bio, avatar FROM profile WHERE profile.id = $1 LIMIT 1;" - GetStatus = "SELECT status FROM friend WHERE (sender = $1 AND receiver = $2) LIMIT 1" + GetStatus = "SELECT sender, status FROM friend WHERE (sender = $1 AND receiver = $2) OR (sender = $2 AND receiver = $1) LIMIT 1" GetAllProfilesBatch = "WITH friends AS (SELECT sender AS friend FROM friend WHERE (receiver = $1 AND status = 0) UNION SELECT receiver AS friend FROM friend WHERE (sender = $1 AND status = 0)), subscriptions AS (SELECT sender AS subscription FROM friend WHERE (receiver = $1 AND status = -1) UNION SELECT receiver AS subscription FROM friend WHERE (sender = $1 AND status = 1)), subscribers AS (SELECT sender AS subscriber FROM friend WHERE (receiver = $1 AND status = 1) UNION SELECT receiver AS subscriber FROM friend WHERE (sender = $1 AND status = -1)) SELECT p.id, first_name, last_name, avatar FROM profile p WHERE p.id <> $1 AND p.id > $2 AND p.id NOT IN (SELECT friend FROM friends) AND p.id NOT IN (SELECT subscription FROM subscriptions) AND p.id NOT IN (SELECT subscriber FROM subscribers) ORDER BY p.id LIMIT $3;" UpdateProfile = "UPDATE profile SET first_name = $1, last_name = $2, bio = $3 WHERE id = $4;" UpdateProfileAvatar = "UPDATE profile SET avatar = $2, first_name = $3, last_name = $4, bio = $5 WHERE id = $1;" diff --git a/internal/profile/repository/postgres.go b/internal/profile/repository/postgres.go index f2834d4b..5dc7bae3 100644 --- a/internal/profile/repository/postgres.go +++ b/internal/profile/repository/postgres.go @@ -69,11 +69,20 @@ func (p *ProfileRepo) GetProfileById(ctx context.Context, id uint32) (*models.Fu } func (p *ProfileRepo) GetStatus(ctx context.Context, self uint32, profile uint32) (int, error) { - var status int - err := p.DB.QueryRowContext(ctx, GetStatus, self, profile).Scan(&status) + var ( + status int + sender uint32 + ) + + err := p.DB.QueryRowContext(ctx, GetStatus, self, profile).Scan(&sender, &status) if err != nil { return 0, err } + + if sender != self && status != 0 { + status = -status + } + return status, nil } From 639c2d276c5687f7f6ff76d288a0ba7543e2d7f5 Mon Sep 17 00:00:00 2001 From: slashlight Date: Sun, 22 Dec 2024 11:09:21 +0300 Subject: [PATCH 134/135] feat: added perf_test --- perf_test/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 perf_test/README.md diff --git a/perf_test/README.md b/perf_test/README.md new file mode 100644 index 00000000..e69de29b From e7222345098d10ddb1256f19adfdf04466822eba Mon Sep 17 00:00:00 2001 From: SlashLight <99999386+SlashLight@users.noreply.github.com> Date: Sun, 22 Dec 2024 16:09:05 +0300 Subject: [PATCH 135/135] added test file --- test | 1 + 1 file changed, 1 insertion(+) create mode 100644 test diff --git a/test b/test new file mode 100644 index 00000000..30d74d25 --- /dev/null +++ b/test @@ -0,0 +1 @@ +test \ No newline at end of file