From 2f2dc145300acee87b2255a84f4f362f60c7957a Mon Sep 17 00:00:00 2001 From: Seyeon_Choi Date: Fri, 12 Apr 2024 23:46:17 +0900 Subject: [PATCH 01/21] feat: alter view column type --- internal/domain/pet/view.go | 3 +- internal/domain/sos_post/view.go | 61 ++++++++++++++++++++++++-------- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/internal/domain/pet/view.go b/internal/domain/pet/view.go index ad2a1cf6..94c2510d 100644 --- a/internal/domain/pet/view.go +++ b/internal/domain/pet/view.go @@ -2,7 +2,6 @@ package pet import ( pnd "github.com/pet-sitter/pets-next-door-api/api" - utils "github.com/pet-sitter/pets-next-door-api/internal/common" ) type FindMyPetsView struct { @@ -38,7 +37,7 @@ func (pet *Pet) ToPetView() *PetView { Sex: pet.Sex, Neutered: pet.Neutered, Breed: pet.Breed, - BirthDate: utils.FormatDate(pet.BirthDate), + BirthDate: pet.BirthDate, WeightInKg: pet.WeightInKg, Remarks: pet.Remarks, } diff --git a/internal/domain/sos_post/view.go b/internal/domain/sos_post/view.go index 3fc2aac8..18e5a8f5 100644 --- a/internal/domain/sos_post/view.go +++ b/internal/domain/sos_post/view.go @@ -1,13 +1,10 @@ package sos_post import ( - utils "github.com/pet-sitter/pets-next-door-api/internal/common" - "github.com/pet-sitter/pets-next-door-api/internal/domain/user" - "time" - pnd "github.com/pet-sitter/pets-next-door-api/api" "github.com/pet-sitter/pets-next-door-api/internal/domain/media" "github.com/pet-sitter/pets-next-door-api/internal/domain/pet" + "github.com/pet-sitter/pets-next-door-api/internal/domain/user" ) type ConditionView struct { @@ -15,6 +12,8 @@ type ConditionView struct { Name string `json:"name"` } +type ConditionViewList []*ConditionView + func (c *Condition) ToConditionView() *ConditionView { return &ConditionView{ ID: c.ID, @@ -57,8 +56,8 @@ type WriteSosPostView struct { CarerGender CarerGender `json:"carerGender"` RewardType RewardType `json:"rewardType"` ThumbnailID int `json:"thumbnailId"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` } func (p *SosPost) ToWriteSosPostView( @@ -100,8 +99,8 @@ type FindSosPostView struct { CarerGender CarerGender `json:"carerGender"` RewardType RewardType `json:"rewardType"` ThumbnailID int `json:"thumbnailId"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` } func (p *SosPost) ToFindSosPostView( @@ -142,6 +141,40 @@ func FromEmptySosPostList(sosPosts *SosPostList) *FindSosPostListView { } } +func FromEmptySosPostInfoList(sosPosts *SosPostInfoList) *FindSosPostListView { + return &FindSosPostListView{ + PaginatedView: pnd.NewPaginatedView( + sosPosts.Page, sosPosts.Size, sosPosts.IsLastPage, make([]FindSosPostView, 0), + ), + } +} + +func (p *SosPostInfo) ToFindSosPostInfoView( + author *user.UserWithoutPrivateInfo, + media media.MediaViewList, + conditions []ConditionView, + pets []pet.PetView, + sosDates []SosDateView, +) *FindSosPostView { + return &FindSosPostView{ + ID: p.ID, + Author: author, + Title: p.Title, + Content: p.Content, + Media: media, + Conditions: conditions, + Pets: pets, + Reward: p.Reward, + Dates: sosDates, + CareType: p.CareType, + CarerGender: p.CarerGender, + RewardType: p.RewardType, + ThumbnailID: p.ThumbnailID, + CreatedAt: p.CreatedAt, + UpdatedAt: p.UpdatedAt, + } +} + type UpdateSosPostRequest struct { ID int `json:"id" validate:"required"` Title string `json:"title" validate:"required"` @@ -170,8 +203,8 @@ type UpdateSosPostView struct { CarerGender CarerGender `json:"carerGender"` RewardType RewardType `json:"rewardType"` ThumbnailID int `json:"thumbnailId"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` } func (p *SosPost) ToUpdateSosPostView( @@ -200,14 +233,14 @@ func (p *SosPost) ToUpdateSosPostView( } type SosDateView struct { - DateStartAt string `field:"dateStartAt"` - DateEndAt string `field:"dateEndAt"` + DateStartAt string `json:"dateStartAt"` + DateEndAt string `json:"dateEndAt"` } func (d *SosDates) ToSosDateView() SosDateView { return SosDateView{ - DateStartAt: utils.FormatDate(d.DateStartAt), - DateEndAt: utils.FormatDate(d.DateEndAt), + DateStartAt: d.DateStartAt, + DateEndAt: d.DateEndAt, } } From 915e925fde90555d9259e2a6b7c209b11728b4f7 Mon Sep 17 00:00:00 2001 From: Seyeon_Choi Date: Fri, 12 Apr 2024 23:47:58 +0900 Subject: [PATCH 02/21] feat: add filter_type to FindSosPosts handler --- cmd/server/handler/sos_post_handler.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cmd/server/handler/sos_post_handler.go b/cmd/server/handler/sos_post_handler.go index 3729af81..b191d66f 100644 --- a/cmd/server/handler/sos_post_handler.go +++ b/cmd/server/handler/sos_post_handler.go @@ -61,6 +61,7 @@ func (h *SosPostHandler) WriteSosPost(c echo.Context) error { // @Param page query int false "페이지 번호" default(1) // @Param size query int false "페이지 사이즈" default(20) // @Param sort_by query string false "정렬 기준" Enums(newest, deadline) +// @Param filter_type query string false "필터링 기준" Enums(dog, cat, all) // @Success 200 {object} sos_post.FindSosPostListView // @Router /posts/sos [get] func (h *SosPostHandler) FindSosPosts(c echo.Context) error { @@ -73,6 +74,10 @@ func (h *SosPostHandler) FindSosPosts(c echo.Context) error { if sortByQuery := pnd.ParseOptionalStringQuery(c, "sort_by"); sortByQuery != nil { sortBy = *sortByQuery } + filterType := "all" + if filterTypeQuery := pnd.ParseOptionalStringQuery(c, "filter_type"); filterTypeQuery != nil { + filterType = *filterTypeQuery + } page, size, err := pnd.ParsePaginationQueries(c, 1, 20) if err != nil { @@ -81,12 +86,12 @@ func (h *SosPostHandler) FindSosPosts(c echo.Context) error { var res *sos_post.FindSosPostListView if authorID != nil { - res, err = h.sosPostService.FindSosPostsByAuthorID(c.Request().Context(), *authorID, page, size, sortBy) + res, err = h.sosPostService.FindSosPostsByAuthorID(c.Request().Context(), *authorID, page, size, sortBy, filterType) if err != nil { return c.JSON(err.StatusCode, err) } } else { - res, err = h.sosPostService.FindSosPosts(c.Request().Context(), page, size, sortBy) + res, err = h.sosPostService.FindSosPosts(c.Request().Context(), page, size, sortBy, filterType) if err != nil { return c.JSON(err.StatusCode, err) } From 6f839638ad41c3e19c3dde667093ff320667d132 Mon Sep 17 00:00:00 2001 From: Seyeon_Choi Date: Sat, 13 Apr 2024 01:55:46 +0900 Subject: [PATCH 03/21] feat: add posts view --- .../000017_create_posts_view.down.sql | 4 ++ db/migrations/000017_create_posts_view.up.sql | 61 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 db/migrations/000017_create_posts_view.down.sql create mode 100644 db/migrations/000017_create_posts_view.up.sql diff --git a/db/migrations/000017_create_posts_view.down.sql b/db/migrations/000017_create_posts_view.down.sql new file mode 100644 index 00000000..99a4c911 --- /dev/null +++ b/db/migrations/000017_create_posts_view.down.sql @@ -0,0 +1,4 @@ +DROP VIEW IF EXISTS v_sos_posts; +DROP VIEW IF EXISTS v_pets; +DROP VIEW IF EXISTS v_media; +DROP VIEW IF EXISTS v_conditions; diff --git a/db/migrations/000017_create_posts_view.up.sql b/db/migrations/000017_create_posts_view.up.sql new file mode 100644 index 00000000..f8a6a737 --- /dev/null +++ b/db/migrations/000017_create_posts_view.up.sql @@ -0,0 +1,61 @@ +CREATE OR REPLACE VIEW v_sos_posts AS +SELECT + sos_posts.id, + sos_posts.title, + sos_posts.content, + sos_posts.reward, + sos_posts.reward_type, + sos_posts.care_type, + sos_posts.carer_gender, + sos_posts.thumbnail_id, + sos_posts.author_id, + sos_posts.created_at, + sos_posts.updated_at, + MIN(sos_dates.date_start_at) AS earliest_date_start_at, + json_agg(sos_dates.*) FILTER (WHERE sos_dates.deleted_at IS NULL) AS dates +FROM + sos_posts + LEFT JOIN sos_posts_dates ON sos_posts.id = sos_posts_dates.sos_post_id + LEFT JOIN sos_dates ON sos_posts_dates.sos_dates_id = sos_dates.id +WHERE + sos_posts.deleted_at IS NULL + AND sos_dates.deleted_at IS NULL + AND sos_posts_dates.deleted_at IS NULL +GROUP BY sos_posts.id; + +CREATE OR REPLACE VIEW v_pets AS +SELECT + sos_posts_pets.sos_post_id, + array_agg(pets.pet_type) AS pet_type_list, + json_agg(pets.*) FILTER (WHERE pets.deleted_at IS NULL) AS pets_info +FROM + sos_posts_pets + LEFT JOIN pets ON sos_posts_pets.pet_id = pets.id +WHERE + pets.deleted_at IS NULL + AND sos_posts_pets.deleted_at IS NULL +GROUP BY sos_posts_pets.sos_post_id; + +CREATE OR REPLACE VIEW v_media AS +SELECT + resource_media.resource_id AS sos_post_id, + json_agg(media.*) FILTER (WHERE media.deleted_at IS NULL) AS media_info +FROM + resource_media + LEFT JOIN media ON resource_media.media_id = media.id +WHERE + media.deleted_at IS NULL AND + resource_media.deleted_at IS NULL +GROUP BY resource_media.resource_id; + +CREATE OR REPLACE VIEW v_conditions AS +SELECT + sos_posts_conditions.sos_post_id, + json_agg(sos_conditions.*) FILTER (WHERE sos_conditions.deleted_at IS NULL) AS conditions_info +FROM + sos_posts_conditions + LEFT JOIN sos_conditions ON sos_posts_conditions.sos_condition_id = sos_conditions.id +WHERE + sos_conditions.deleted_at IS NULL AND + sos_posts_conditions.deleted_at IS NULL +GROUP BY sos_posts_conditions.sos_post_id; \ No newline at end of file From 73ff01c63f3fe4520a1d0f0491e8ea50f0b4e782 Mon Sep 17 00:00:00 2001 From: Seyeon_Choi Date: Sat, 13 Apr 2024 02:10:06 +0900 Subject: [PATCH 04/21] feat: add filtering to FindSosPost --- internal/domain/media/media.go | 12 +- internal/domain/pet/pet.go | 28 ++-- internal/domain/sos_post/sos_post.go | 55 +++++-- internal/postgres/sos_post_store.go | 233 ++++++++++++++++++--------- internal/service/sos_post_service.go | 84 +++------- 5 files changed, 235 insertions(+), 177 deletions(-) diff --git a/internal/domain/media/media.go b/internal/domain/media/media.go index 0fb8b916..18cd6019 100644 --- a/internal/domain/media/media.go +++ b/internal/domain/media/media.go @@ -14,12 +14,12 @@ const ( ) type Media struct { - ID int `field:"id"` - MediaType MediaType `field:"media_type"` - URL string `field:"url"` - CreatedAt string `field:"created_at"` - UpdatedAt string `field:"updated_at"` - DeletedAt string `field:"deleted_at"` + ID int `field:"id" json:"id"` + MediaType MediaType `field:"media_type" json:"media_type"` + URL string `field:"url" json:"url"` + CreatedAt string `field:"created_at" json:"created_at"` + UpdatedAt string `field:"updated_at" json:"updated_at"` + DeletedAt string `field:"deleted_at" json:"deleted_at"` } type MediaList []*Media diff --git a/internal/domain/pet/pet.go b/internal/domain/pet/pet.go index 6219682b..f84b342b 100644 --- a/internal/domain/pet/pet.go +++ b/internal/domain/pet/pet.go @@ -8,19 +8,19 @@ import ( ) type BasePet struct { - ID int `field:"id"` - OwnerID int `field:"owner_id"` - Name string `field:"name"` - PetType PetType `field:"pet_type"` - Sex PetSex `field:"sex"` - Neutered bool `field:"neutered"` - Breed string `field:"breed"` - BirthDate string `field:"birth_date"` - WeightInKg float64 `field:"weight_in_kg"` - Remarks string `field:"remarks"` - CreatedAt string `field:"created_at"` - UpdatedAt string `field:"updated_at"` - DeletedAt string `field:"deleted_at"` + ID int `field:"id" json:"id"` + OwnerID int `field:"owner_id" json:"owner_id"` + Name string `field:"name" json:"name"` + PetType PetType `field:"pet_type" json:"pet_type"` + Sex PetSex `field:"sex" json:"sex"` + Neutered bool `field:"neutered" json:"neutered"` + Breed string `field:"breed" json:"breed"` + BirthDate string `field:"birth_date" json:"birth_date"` + WeightInKg float64 `field:"weight_in_kg" json:"weight_in_kg"` + Remarks string `field:"remarks" json:"remarks"` + CreatedAt string `field:"created_at" json:"created_at"` + UpdatedAt string `field:"updated_at" json:"updated_at"` + DeletedAt string `field:"deleted_at" json:"deleted_at"` } type Pet struct { @@ -32,7 +32,7 @@ type PetList []*Pet type PetWithProfileImage struct { BasePet - ProfileImageURL *string `field:"profile_image_url"` + ProfileImageURL *string `field:"profile_image_url" json:"profile_image_url"` } type PetWithProfileList []*PetWithProfileImage diff --git a/internal/domain/sos_post/sos_post.go b/internal/domain/sos_post/sos_post.go index fa04e750..fd7f2d6e 100644 --- a/internal/domain/sos_post/sos_post.go +++ b/internal/domain/sos_post/sos_post.go @@ -2,11 +2,10 @@ package sos_post import ( "context" - "github.com/pet-sitter/pets-next-door-api/internal/infra/database" - "time" - pnd "github.com/pet-sitter/pets-next-door-api/api" + "github.com/pet-sitter/pets-next-door-api/internal/domain/media" "github.com/pet-sitter/pets-next-door-api/internal/domain/pet" + "github.com/pet-sitter/pets-next-door-api/internal/infra/database" ) type CareType string @@ -40,36 +39,64 @@ type SosPost struct { CarerGender CarerGender `field:"carer_gender"` RewardType RewardType `field:"reward_type"` ThumbnailID int `field:"thumbnail_id"` - CreatedAt time.Time `field:"created_at"` - UpdatedAt time.Time `field:"updated_at"` - DeletedAt time.Time `field:"deleted_at"` + CreatedAt string `field:"created_at"` + UpdatedAt string `field:"updated_at"` + DeletedAt string `field:"deleted_at"` } type SosPostList struct { *pnd.PaginatedView[SosPost] } +type SosPostInfo struct { + ID int `field:"id" json:"id"` + AuthorID int `field:"author" json:"author"` + Title string `field:"title" json:"title"` + Content string `field:"content" json:"content"` + Media media.MediaList `field:"media" json:"media"` + Conditions ConditionList `field:"conditions" json:"conditions"` + Pets pet.PetList `field:"pets" json:"pets"` + Reward string `field:"reward" json:"reward"` + Dates SosDatesList `field:"dates" json:"dates"` + CareType CareType `field:"careType" json:"careType"` + CarerGender CarerGender `field:"carerGender" json:"carerGender"` + RewardType RewardType `field:"rewardType" json:"rewardType"` + ThumbnailID int `field:"thumbnailId" json:"thumbnailId"` + CreatedAt string `field:"createdAt" json:"createdAt"` + UpdatedAt string `field:"updatedAt" json:"updatedAt"` +} + +type SosPostInfoList struct { + *pnd.PaginatedView[SosPostInfo] +} + func NewSosPostList(page int, size int) *SosPostList { return &SosPostList{PaginatedView: pnd.NewPaginatedView( page, size, false, make([]SosPost, 0), )} } +func NewSosPostInfoList(page int, size int) *SosPostInfoList { + return &SosPostInfoList{PaginatedView: pnd.NewPaginatedView( + page, size, false, make([]SosPostInfo, 0), + )} +} + type SosDates struct { - ID int `field:"id"` - DateStartAt string `field:"date_start_at"` - DateEndAt string `field:"date_end_at"` - CreatedAt time.Time `field:"created_at"` - UpdatedAt time.Time `field:"updated_at"` - DeletedAt time.Time `field:"deleted_at"` + ID int `field:"id" json:"id"` + DateStartAt string `field:"date_start_at" json:"date_start_at"` + DateEndAt string `field:"date_end_at" json:"date_end_at"` + CreatedAt string `field:"created_at" json:"created_at"` + UpdatedAt string `field:"updated_at" json:"updated_at"` + DeletedAt string `field:"deleted_at" json:"deleted_at"` } type SosDatesList []*SosDates type SosPostStore interface { WriteSosPost(ctx context.Context, tx *database.Tx, authorID int, utcDateStart string, utcDateEnd string, request *WriteSosPostRequest) (*SosPost, *pnd.AppError) - FindSosPosts(ctx context.Context, tx *database.Tx, page int, size int, sortBy string) (*SosPostList, *pnd.AppError) - FindSosPostsByAuthorID(ctx context.Context, tx *database.Tx, authorID int, page int, size int, sortBy string) (*SosPostList, *pnd.AppError) + FindSosPosts(ctx context.Context, tx *database.Tx, page int, size int, sortBy string) (*SosPostInfoList, *pnd.AppError) + FindSosPostsByAuthorID(ctx context.Context, tx *database.Tx, authorID int, page int, size int, sortBy string) (*SosPostInfoList, *pnd.AppError) FindSosPostByID(ctx context.Context, tx *database.Tx, id int) (*SosPost, *pnd.AppError) UpdateSosPost(ctx context.Context, tx *database.Tx, request *UpdateSosPostRequest) (*SosPost, *pnd.AppError) FindConditionByID(ctx context.Context, tx *database.Tx, id int) (*ConditionList, *pnd.AppError) diff --git a/internal/postgres/sos_post_store.go b/internal/postgres/sos_post_store.go index 149d9410..2ebde557 100644 --- a/internal/postgres/sos_post_store.go +++ b/internal/postgres/sos_post_store.go @@ -2,7 +2,10 @@ package postgres import ( "context" + "encoding/json" "fmt" + utils "github.com/pet-sitter/pets-next-door-api/internal/common" + "time" pnd "github.com/pet-sitter/pets-next-door-api/api" "github.com/pet-sitter/pets-next-door-api/internal/domain/media" @@ -174,150 +177,224 @@ func WriteSosPost(ctx context.Context, tx *database.Tx, authorID int, request *s return sosPost, nil } -func FindSosPosts(ctx context.Context, tx *database.Tx, page int, size int, sortBy string) (*sos_post.SosPostList, *pnd.AppError) { - var sortColumn string - var sortOrder string +func FindSosPosts(ctx context.Context, tx *database.Tx, page int, size int, sortBy string, filterType string) (*sos_post.SosPostInfoList, *pnd.AppError) { + var sortString string switch sortBy { case "newest": - sortColumn = "created_at" - sortOrder = "DESC" + sortString = "v_sos_posts.created_at DESC" case "deadline": - sortColumn = "date_end_at" - sortOrder = "ASC" + sortString = "earliest_date_start_at ASC" default: - sortColumn = "created_at" - sortOrder = "DESC" + sortString = "sos_posts.created_at DESC" + } + + var filterString string + switch filterType { + case "dog": + filterString = "'dog' = ANY(pet_type_list)" + case "cat": + filterString = "'cat' = ANY(pet_type_list)" + case "all": + filterString = "'dog' = ANY(pet_type_list) " + + "OR 'cat' = ANY(pet_type_list)" } query := fmt.Sprintf(` - SELECT - id, - author_id, - title, - content, - reward, - care_type, - carer_gender, - reward_type, - thumbnail_id, - created_at, - updated_at - FROM - sos_posts - WHERE - deleted_at IS NULL - ORDER BY %s %s - LIMIT $1 - OFFSET $2 + SELECT + v_sos_posts.id, + v_sos_posts.title, + v_sos_posts.content, + v_sos_posts.reward, + v_sos_posts.reward_type, + v_sos_posts.care_type, + v_sos_posts.carer_gender, + v_sos_posts.thumbnail_id, + v_sos_posts.author_id, + v_sos_posts.created_at, + v_sos_posts.updated_at, + v_sos_posts.dates, + v_pets.pets_info, + v_media.media_info, + v_conditions.conditions_info + FROM + v_sos_posts + LEFT JOIN v_pets ON v_sos_posts.id = v_pets.sos_post_id + LEFT JOIN v_media ON v_sos_posts.id = v_media.sos_post_id + LEFT JOIN v_conditions ON v_sos_posts.id = v_conditions.sos_post_id + WHERE + %s + AND v_sos_posts.earliest_date_start_at >= '%s' + ORDER BY + $1 + LIMIT $2 + OFFSET $3; + `, - sortColumn, - sortOrder, + filterString, + utils.FormatDate(time.Now().String()), ) - rows, err := tx.QueryContext(ctx, query, size+1, (page-1)*size) + rows, err := tx.QueryContext(ctx, query, sortString, size+1, (page-1)*size) if err != nil { - return nil, pnd.FromPostgresError(err) + return &sos_post.SosPostInfoList{}, pnd.FromPostgresError(err) } defer rows.Close() - sosPostList := sos_post.NewSosPostList(page, size) + sosPostList := sos_post.NewSosPostInfoList(page, size) for rows.Next() { - sosPost := sos_post.SosPost{} + sosPost := sos_post.SosPostInfo{} + var datesData, petsData, mediaData, conditionsData string + if err := rows.Scan( &sosPost.ID, - &sosPost.AuthorID, &sosPost.Title, &sosPost.Content, &sosPost.Reward, + &sosPost.RewardType, &sosPost.CareType, &sosPost.CarerGender, - &sosPost.RewardType, &sosPost.ThumbnailID, + &sosPost.AuthorID, &sosPost.CreatedAt, &sosPost.UpdatedAt, - ); err != nil { + &datesData, + &petsData, + &mediaData, + &conditionsData); err != nil { return nil, pnd.FromPostgresError(err) } + + if err := json.Unmarshal([]byte(datesData), &sosPost.Dates); err != nil { + return nil, pnd.FromPostgresError(err) + } + if err := json.Unmarshal([]byte(petsData), &sosPost.Pets); err != nil { + return nil, pnd.FromPostgresError(err) + } + if err := json.Unmarshal([]byte(mediaData), &sosPost.Media); err != nil { + return nil, pnd.FromPostgresError(err) + } + if err := json.Unmarshal([]byte(conditionsData), &sosPost.Conditions); err != nil { + return nil, pnd.FromPostgresError(err) + } + sosPostList.Items = append(sosPostList.Items, sosPost) } if err := rows.Err(); err != nil { return nil, pnd.FromPostgresError(err) } - sosPostList.CalcLastPage() + return sosPostList, nil } -func FindSosPostsByAuthorID(ctx context.Context, tx *database.Tx, authorID int, page int, size int, sortBy string) (*sos_post.SosPostList, *pnd.AppError) { - var sortColumn string - var sortOrder string - +func FindSosPostsByAuthorID(ctx context.Context, tx *database.Tx, authorID int, page int, size int, sortBy string, filterType string) (*sos_post.SosPostInfoList, *pnd.AppError) { + var sortString string switch sortBy { case "newest": - sortColumn = "created_at" - sortOrder = "DESC" + sortString = "v_sos_posts.created_at DESC" case "deadline": - sortColumn = "date_end_at" - sortOrder = "ASC" + sortString = "earliest_date_start_at ASC" default: - sortColumn = "created_at" - sortOrder = "DESC" + sortString = "sos_posts.created_at DESC" + } + + var filterString string + switch filterType { + case "dog": + filterString = "'dog' = ANY(pet_type_list)" + case "cat": + filterString = "'cat' = ANY(pet_type_list)" + case "all": + filterString = "'dog' = ANY(pet_type_list) " + + "OR 'cat' = ANY(pet_type_list)" } query := fmt.Sprintf(` - SELECT - id, - author_id, - title, - content, - reward, - care_type, - carer_gender, - reward_type, - thumbnail_id, - created_at, - updated_at - FROM - sos_posts - WHERE - author_id = $1 AND - deleted_at IS NULL - ORDER BY %s %s - LIMIT $2 - OFFSET $3 + SELECT + v_sos_posts.id, + v_sos_posts.title, + v_sos_posts.content, + v_sos_posts.reward, + v_sos_posts.reward_type, + v_sos_posts.care_type, + v_sos_posts.carer_gender, + v_sos_posts.thumbnail_id, + v_sos_posts.author_id, + v_sos_posts.created_at, + v_sos_posts.updated_at, + v_sos_posts.dates, + v_pets.pets_info, + v_media.media_info, + v_conditions.conditions_info + FROM + v_sos_posts + LEFT JOIN v_pets ON v_sos_posts.id = v_pets.sos_post_id + LEFT JOIN v_media ON v_sos_posts.id = v_media.sos_post_id + LEFT JOIN v_conditions ON v_sos_posts.id = v_conditions.sos_post_id + WHERE + %s + AND v_sos_posts.earliest_date_start_at >= '%s' + AND v_sos_posts.author_id = $1 + ORDER BY + $2 + LIMIT $3 + OFFSET $4; + `, - sortColumn, - sortOrder, + filterString, + utils.FormatDate(time.Now().String()), ) - rows, err := tx.QueryContext(ctx, query, authorID, size+1, (page-1)*size) + rows, err := tx.QueryContext(ctx, query, authorID, sortString, size+1, (page-1)*size) if err != nil { - return nil, pnd.FromPostgresError(err) + return &sos_post.SosPostInfoList{}, pnd.FromPostgresError(err) } defer rows.Close() - sosPostList := sos_post.NewSosPostList(page, size) + sosPostList := sos_post.NewSosPostInfoList(page, size) for rows.Next() { - sosPost := sos_post.SosPost{} + sosPost := sos_post.SosPostInfo{} + var datesData, petsData, mediaData, conditionsData string + if err := rows.Scan( &sosPost.ID, - &sosPost.AuthorID, &sosPost.Title, &sosPost.Content, &sosPost.Reward, + &sosPost.RewardType, &sosPost.CareType, &sosPost.CarerGender, - &sosPost.RewardType, &sosPost.ThumbnailID, + &sosPost.AuthorID, &sosPost.CreatedAt, &sosPost.UpdatedAt, - ); err != nil { + &datesData, + &petsData, + &mediaData, + &conditionsData); err != nil { + return nil, pnd.FromPostgresError(err) + } + + if err := json.Unmarshal([]byte(datesData), &sosPost.Dates); err != nil { + return nil, pnd.FromPostgresError(err) + } + if err := json.Unmarshal([]byte(petsData), &sosPost.Pets); err != nil { return nil, pnd.FromPostgresError(err) } + if err := json.Unmarshal([]byte(mediaData), &sosPost.Media); err != nil { + return nil, pnd.FromPostgresError(err) + } + if err := json.Unmarshal([]byte(conditionsData), &sosPost.Conditions); err != nil { + return nil, pnd.FromPostgresError(err) + } + sosPostList.Items = append(sosPostList.Items, sosPost) } - + if err := rows.Err(); err != nil { + return nil, pnd.FromPostgresError(err) + } sosPostList.CalcLastPage() + return sosPostList, nil } diff --git a/internal/service/sos_post_service.go b/internal/service/sos_post_service.go index 6e6042c4..081b813d 100644 --- a/internal/service/sos_post_service.go +++ b/internal/service/sos_post_service.go @@ -69,113 +69,67 @@ func (service *SosPostService) WriteSosPost(ctx context.Context, fbUid string, r ), nil } -func (service *SosPostService) FindSosPosts(ctx context.Context, page int, size int, sortBy string) (*sos_post.FindSosPostListView, *pnd.AppError) { +func (service *SosPostService) FindSosPosts(ctx context.Context, page int, size int, sortBy string, filterType string) (*sos_post.FindSosPostListView, *pnd.AppError) { tx, err := service.conn.BeginTx(ctx) defer tx.Rollback() if err != nil { return nil, err } - sosPosts, err := postgres.FindSosPosts(ctx, tx, page, size, sortBy) + sosPosts, err := postgres.FindSosPosts(ctx, tx, page, size, sortBy, filterType) if err != nil { return nil, err } - sosPostViews := sos_post.FromEmptySosPostList(sosPosts) - for _, sosPost := range sosPosts.Items { - mediaData, err := postgres.FindResourceMediaByResourceID(ctx, tx, sosPost.ID, string(media.SosResourceType)) - if err != nil { - return nil, err - } - - conditions, err := postgres.FindConditionByID(ctx, tx, sosPost.ID) - if err != nil { - return nil, err - } - - pets, err := postgres.FindPetsByID(ctx, tx, sosPost.ID) - if err != nil { - return nil, err - } - - dates, err := postgres.FindDatesBySosPostID(ctx, tx, sosPost.ID) - if err != nil { - return nil, err - } + sosPostViews := sos_post.FromEmptySosPostInfoList(sosPosts) + for _, sosPost := range sosPosts.Items { author, err := postgres.FindUserByID(ctx, tx, sosPost.AuthorID, true) if err != nil { return nil, err } - - findByAuthorSosPostView := sosPost.ToFindSosPostView( + SosPostView := sosPost.ToFindSosPostInfoView( author.ToUserWithoutPrivateInfo(), - mediaData.ToMediaViewList(), - conditions.ToConditionViewList(), - pets.ToPetViewList(), - dates.ToSosDateViewList(), + sosPost.Media.ToMediaViewList(), + sosPost.Conditions.ToConditionViewList(), + sosPost.Pets.ToPetViewList(), + sosPost.Dates.ToSosDateViewList(), ) - sosPostViews.Items = append(sosPostViews.Items, *findByAuthorSosPostView) + sosPostViews.Items = append(sosPostViews.Items, *SosPostView) } return sosPostViews, nil } -func (service *SosPostService) FindSosPostsByAuthorID(ctx context.Context, authorID int, page int, size int, sortBy string) (*sos_post.FindSosPostListView, *pnd.AppError) { +func (service *SosPostService) FindSosPostsByAuthorID(ctx context.Context, authorID int, page int, size int, sortBy string, filterType string) (*sos_post.FindSosPostListView, *pnd.AppError) { tx, err := service.conn.BeginTx(ctx) defer tx.Rollback() if err != nil { return nil, err } - sosPosts, err := postgres.FindSosPostsByAuthorID(ctx, tx, authorID, page, size, sortBy) + sosPosts, err := postgres.FindSosPostsByAuthorID(ctx, tx, authorID, page, size, sortBy, filterType) if err != nil { return nil, err } + sosPostViews := sos_post.FromEmptySosPostInfoList(sosPosts) - sosPostViews := sos_post.FromEmptySosPostList(sosPosts) for _, sosPost := range sosPosts.Items { - mediaData, err := postgres.FindResourceMediaByResourceID(ctx, tx, sosPost.ID, string(media.SosResourceType)) - if err != nil { - return nil, err - } - - conditions, err := postgres.FindConditionByID(ctx, tx, sosPost.ID) - if err != nil { - return nil, err - } - - pets, err := postgres.FindPetsByID(ctx, tx, sosPost.ID) - if err != nil { - return nil, err - } - - dates, err := postgres.FindDatesBySosPostID(ctx, tx, sosPost.ID) - if err != nil { - return nil, err - } - author, err := postgres.FindUserByID(ctx, tx, sosPost.AuthorID, true) if err != nil { return nil, err } - - findByAuthorSosPostView := sosPost.ToFindSosPostView( + SosPostView := sosPost.ToFindSosPostInfoView( author.ToUserWithoutPrivateInfo(), - mediaData.ToMediaViewList(), - conditions.ToConditionViewList(), - pets.ToPetViewList(), - dates.ToSosDateViewList(), + sosPost.Media.ToMediaViewList(), + sosPost.Conditions.ToConditionViewList(), + sosPost.Pets.ToPetViewList(), + sosPost.Dates.ToSosDateViewList(), ) - sosPostViews.Items = append(sosPostViews.Items, *findByAuthorSosPostView) + sosPostViews.Items = append(sosPostViews.Items, *SosPostView) } - - if err := tx.Commit(); err != nil { - return nil, err - } - return sosPostViews, nil } From babc0bdc7643581326211e07812a7428fccc8728 Mon Sep 17 00:00:00 2001 From: choiseyeon Date: Mon, 15 Apr 2024 01:16:25 +0900 Subject: [PATCH 05/21] fix: change date type --- internal/domain/pet/view.go | 3 ++- internal/domain/sos_post/view.go | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/internal/domain/pet/view.go b/internal/domain/pet/view.go index 94c2510d..ad2a1cf6 100644 --- a/internal/domain/pet/view.go +++ b/internal/domain/pet/view.go @@ -2,6 +2,7 @@ package pet import ( pnd "github.com/pet-sitter/pets-next-door-api/api" + utils "github.com/pet-sitter/pets-next-door-api/internal/common" ) type FindMyPetsView struct { @@ -37,7 +38,7 @@ func (pet *Pet) ToPetView() *PetView { Sex: pet.Sex, Neutered: pet.Neutered, Breed: pet.Breed, - BirthDate: pet.BirthDate, + BirthDate: utils.FormatDate(pet.BirthDate), WeightInKg: pet.WeightInKg, Remarks: pet.Remarks, } diff --git a/internal/domain/sos_post/view.go b/internal/domain/sos_post/view.go index 18e5a8f5..96b88622 100644 --- a/internal/domain/sos_post/view.go +++ b/internal/domain/sos_post/view.go @@ -2,6 +2,7 @@ package sos_post import ( pnd "github.com/pet-sitter/pets-next-door-api/api" + utils "github.com/pet-sitter/pets-next-door-api/internal/common" "github.com/pet-sitter/pets-next-door-api/internal/domain/media" "github.com/pet-sitter/pets-next-door-api/internal/domain/pet" "github.com/pet-sitter/pets-next-door-api/internal/domain/user" @@ -239,8 +240,8 @@ type SosDateView struct { func (d *SosDates) ToSosDateView() SosDateView { return SosDateView{ - DateStartAt: d.DateStartAt, - DateEndAt: d.DateEndAt, + DateStartAt: utils.FormatDate(d.DateStartAt), + DateEndAt: utils.FormatDate(d.DateEndAt), } } From 01e6d009ef68314c3815ff20af925c53b2fb6e2a Mon Sep 17 00:00:00 2001 From: choiseyeon Date: Mon, 15 Apr 2024 01:18:25 +0900 Subject: [PATCH 06/21] fix: update query statement filtering --- internal/postgres/sos_post_store.go | 71 +++++++++++++++++------------ 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/internal/postgres/sos_post_store.go b/internal/postgres/sos_post_store.go index 2ebde557..41f9c54d 100644 --- a/internal/postgres/sos_post_store.go +++ b/internal/postgres/sos_post_store.go @@ -183,20 +183,25 @@ func FindSosPosts(ctx context.Context, tx *database.Tx, page int, size int, sort case "newest": sortString = "v_sos_posts.created_at DESC" case "deadline": - sortString = "earliest_date_start_at ASC" - default: - sortString = "sos_posts.created_at DESC" + sortString = "v_sos_posts.earliest_date_start_at" } var filterString string switch filterType { case "dog": - filterString = "'dog' = ANY(pet_type_list)" + filterString = "AND " + + "NOT EXISTS " + + "(SELECT 1 " + + "FROM unnest(pet_type_list) AS pet_type " + + "WHERE pet_type <> 'dog')" case "cat": - filterString = "'cat' = ANY(pet_type_list)" + filterString = "AND " + + "NOT EXISTS " + + "(SELECT 1 " + + "FROM unnest(pet_type_list) AS pet_type " + + "WHERE pet_type <> 'cat')" case "all": - filterString = "'dog' = ANY(pet_type_list) " + - "OR 'cat' = ANY(pet_type_list)" + filterString = "" } query := fmt.Sprintf(` @@ -222,19 +227,20 @@ func FindSosPosts(ctx context.Context, tx *database.Tx, page int, size int, sort LEFT JOIN v_media ON v_sos_posts.id = v_media.sos_post_id LEFT JOIN v_conditions ON v_sos_posts.id = v_conditions.sos_post_id WHERE - %s - AND v_sos_posts.earliest_date_start_at >= '%s' + v_sos_posts.earliest_date_start_at >= '%s' + %s ORDER BY - $1 - LIMIT $2 - OFFSET $3; + %s + LIMIT $1 + OFFSET $2; `, - filterString, utils.FormatDate(time.Now().String()), + filterString, + sortString, ) - rows, err := tx.QueryContext(ctx, query, sortString, size+1, (page-1)*size) + rows, err := tx.QueryContext(ctx, query, size+1, (page-1)*size) if err != nil { return &sos_post.SosPostInfoList{}, pnd.FromPostgresError(err) } @@ -244,7 +250,6 @@ func FindSosPosts(ctx context.Context, tx *database.Tx, page int, size int, sort for rows.Next() { sosPost := sos_post.SosPostInfo{} var datesData, petsData, mediaData, conditionsData string - if err := rows.Scan( &sosPost.ID, &sosPost.Title, @@ -276,7 +281,7 @@ func FindSosPosts(ctx context.Context, tx *database.Tx, page int, size int, sort if err := json.Unmarshal([]byte(conditionsData), &sosPost.Conditions); err != nil { return nil, pnd.FromPostgresError(err) } - + fmt.Println(sosPost.ID) sosPostList.Items = append(sosPostList.Items, sosPost) } if err := rows.Err(); err != nil { @@ -293,20 +298,25 @@ func FindSosPostsByAuthorID(ctx context.Context, tx *database.Tx, authorID int, case "newest": sortString = "v_sos_posts.created_at DESC" case "deadline": - sortString = "earliest_date_start_at ASC" - default: - sortString = "sos_posts.created_at DESC" + sortString = "v_sos_posts.earliest_date_start_at" } var filterString string switch filterType { case "dog": - filterString = "'dog' = ANY(pet_type_list)" + filterString = "AND " + + "NOT EXISTS " + + "(SELECT 1 " + + "FROM unnest(pet_type_list) AS pet_type " + + "WHERE pet_type <> 'dog')" case "cat": - filterString = "'cat' = ANY(pet_type_list)" + filterString = "AND " + + "NOT EXISTS " + + "(SELECT 1 " + + "FROM unnest(pet_type_list) AS pet_type " + + "WHERE pet_type <> 'cat')" case "all": - filterString = "'dog' = ANY(pet_type_list) " + - "OR 'cat' = ANY(pet_type_list)" + filterString = "" } query := fmt.Sprintf(` @@ -332,20 +342,21 @@ func FindSosPostsByAuthorID(ctx context.Context, tx *database.Tx, authorID int, LEFT JOIN v_media ON v_sos_posts.id = v_media.sos_post_id LEFT JOIN v_conditions ON v_sos_posts.id = v_conditions.sos_post_id WHERE - %s - AND v_sos_posts.earliest_date_start_at >= '%s' + v_sos_posts.earliest_date_start_at >= '%s' AND v_sos_posts.author_id = $1 + %s ORDER BY - $2 - LIMIT $3 - OFFSET $4; + %s + LIMIT $2 + OFFSET $3; `, - filterString, utils.FormatDate(time.Now().String()), + filterString, + sortString, ) - rows, err := tx.QueryContext(ctx, query, authorID, sortString, size+1, (page-1)*size) + rows, err := tx.QueryContext(ctx, query, authorID, size+1, (page-1)*size) if err != nil { return &sos_post.SosPostInfoList{}, pnd.FromPostgresError(err) } From 1580aaa362de10a439517d0b9bdc90881d843400 Mon Sep 17 00:00:00 2001 From: choiseyeon Date: Mon, 15 Apr 2024 01:18:53 +0900 Subject: [PATCH 07/21] fix: update SOS post testcode --- internal/service/tests/sos_post_service_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/service/tests/sos_post_service_test.go b/internal/service/tests/sos_post_service_test.go index 05cfdb39..8babb2be 100644 --- a/internal/service/tests/sos_post_service_test.go +++ b/internal/service/tests/sos_post_service_test.go @@ -78,7 +78,7 @@ func TestSosPostService(t *testing.T) { Sex: "male", Neutered: true, Breed: "poodle", - BirthDate: "2020-01-01T00:00:00Z", + BirthDate: "2020-01-01", WeightInKg: 10.0, Remarks: "", ProfileImageID: nil, @@ -193,7 +193,7 @@ func TestSosPostService(t *testing.T) { Sex: "male", Neutered: true, Breed: "poodle", - BirthDate: "2020-01-01T00:00:00Z", + BirthDate: "2020-01-01", WeightInKg: 10.0, Remarks: "", ProfileImageID: nil, @@ -240,7 +240,7 @@ func TestSosPostService(t *testing.T) { Nickname: owner.Nickname, } - sosPostList, err := sosPostService.FindSosPosts(ctx, 1, 3, "newest") + sosPostList, err := sosPostService.FindSosPosts(ctx, 1, 3, "newest", "all") if err != nil { t.Errorf("got %v want %v", err, nil) } @@ -321,7 +321,7 @@ func TestSosPostService(t *testing.T) { Sex: "male", Neutered: true, Breed: "poodle", - BirthDate: "2020-01-01T00:00:00Z", + BirthDate: "2020-01-01", WeightInKg: 10.0, Remarks: "", ProfileImageID: nil, @@ -360,7 +360,7 @@ func TestSosPostService(t *testing.T) { sosPosts = append(sosPosts, *sosPost) } - sosPostListByAuthorID, err := sosPostService.FindSosPostsByAuthorID(ctx, owner.ID, 1, 3, "newest") + sosPostListByAuthorID, err := sosPostService.FindSosPostsByAuthorID(ctx, owner.ID, 1, 3, "newest", "all") if err != nil { t.Errorf("got %v want %v", err, nil) } @@ -451,7 +451,7 @@ func TestSosPostService(t *testing.T) { Sex: "male", Neutered: true, Breed: "poodle", - BirthDate: "2020-01-01T00:00:00Z", + BirthDate: "2020-01-01", WeightInKg: 10.0, Remarks: "", ProfileImageID: nil, @@ -576,7 +576,7 @@ func TestSosPostService(t *testing.T) { Sex: "male", Neutered: true, Breed: "poodle", - BirthDate: "2020-01-01T00:00:00Z", + BirthDate: "2020-01-01", WeightInKg: 10.0, Remarks: "", ProfileImageID: nil, From 7292c30cf5388ab2534dca8bc96454fd76de6515 Mon Sep 17 00:00:00 2001 From: choiseyeon Date: Mon, 15 Apr 2024 01:41:51 +0900 Subject: [PATCH 08/21] fix: update SOS post testcode --- .../service/tests/sos_post_service_test.go | 336 +++++++++++++++++- 1 file changed, 334 insertions(+), 2 deletions(-) diff --git a/internal/service/tests/sos_post_service_test.go b/internal/service/tests/sos_post_service_test.go index 8babb2be..0af4a435 100644 --- a/internal/service/tests/sos_post_service_test.go +++ b/internal/service/tests/sos_post_service_test.go @@ -34,7 +34,7 @@ func TestSosPostService(t *testing.T) { } t.Run("CreateSosPost", func(t *testing.T) { - t.Run("돌봄 급구 게시글을 작성합니다.", func(t *testing.T) { + t.Run("돌봄 급구 게시글을 작성힌다", func(t *testing.T) { ctx := context.Background() db, tearDown := setUp(ctx, t) defer tearDown(t) @@ -150,7 +150,7 @@ func TestSosPostService(t *testing.T) { }) t.Run("FindSosPosts", func(t *testing.T) { - t.Run("전체 돌봄 급구 게시글을 조회합니다.", func(t *testing.T) { + t.Run("전체 돌봄 급구 게시글을 조회한다", func(t *testing.T) { ctx := context.Background() db, tearDown := setUp(ctx, t) defer tearDown(t) @@ -278,6 +278,338 @@ func TestSosPostService(t *testing.T) { } } }) + t.Run("전체 돌봄 급구 게시글의 정렬기준을 'deadline'으로 조회한다", func(t *testing.T) { + ctx := context.Background() + db, tearDown := setUp(ctx, t) + defer tearDown(t) + + mediaService := service.NewMediaService(db, nil) + profileImage, _ := mediaService.CreateMedia(ctx, &media.Media{ + MediaType: media.IMAGE_MEDIA_TYPE, + URL: "https://test.com", + }) + sosPostImage, _ := mediaService.CreateMedia(ctx, &media.Media{ + MediaType: media.IMAGE_MEDIA_TYPE, + URL: "https://test2.com", + }) + sosPostImage2, _ := mediaService.CreateMedia(ctx, &media.Media{ + MediaType: media.IMAGE_MEDIA_TYPE, + URL: "https://test3.com", + }) + + userService := service.NewUserService(db, mediaService) + owner, err := userService.RegisterUser(ctx, &user.RegisterUserRequest{ + Email: "test@example.com", + Nickname: "nickname", + Fullname: "fullname", + ProfileImageID: &profileImage.ID, + FirebaseProviderType: user.FirebaseProviderTypeKakao, + FirebaseUID: "1234", + }) + if err != nil { + t.Errorf("RegisterUser failed: %v", err) + return + } + + uid := owner.FirebaseUID + + pets := pet.AddPetsToOwnerRequest{ + Pets: []pet.AddPetRequest{ + { + Name: "dog_1", + PetType: "dog", + Sex: "male", + Neutered: true, + Breed: "poodle", + BirthDate: "2020-01-01", + WeightInKg: 10.0, + Remarks: "", + ProfileImageID: nil, + }, + { + Name: "dog_2", + PetType: "dog", + Sex: "male", + Neutered: true, + Breed: "poodle", + BirthDate: "2020-02-01", + WeightInKg: 10.0, + Remarks: "", + ProfileImageID: nil, + }, + { + Name: "cat_1", + PetType: "cat", + Sex: "female", + Neutered: true, + Breed: "munchkin", + BirthDate: "2020-03-01", + WeightInKg: 8.0, + Remarks: "", + ProfileImageID: nil, + }, + }, + } + + addPets, err := userService.AddPetsToOwner(ctx, uid, pets) + if err != nil { + t.Errorf(err.Err.Error()) + } + + sosPostService := service.NewSosPostService(db) + + conditionIDs := []int{1, 2} + + var sosPosts []sos_post.WriteSosPostView + + for i := 1; i < 4; i++ { + sosPost, err := sosPostService.WriteSosPost(ctx, uid, &sos_post.WriteSosPostRequest{ + Title: fmt.Sprintf("Title%d", i), + Content: fmt.Sprintf("Test Content%d", i), + ImageIDs: []int{sosPostImage.ID, sosPostImage2.ID}, + Reward: fmt.Sprintf("Test Reward%d", i), + Dates: []sos_post.SosDateView{ + {fmt.Sprintf("2024-04-1%d", i), "2024-04-20"}, + {fmt.Sprintf("2024-05-0%d", i), "2024-05-10"}}, + CareType: sos_post.CareTypeFoster, + CarerGender: sos_post.CarerGenderMale, + RewardType: sos_post.RewardTypeFee, + ConditionIDs: conditionIDs, + PetIDs: []int{addPets[i-1].ID}, + }) + + if err != nil { + t.Errorf(err.Err.Error()) + } + + sosPosts = append(sosPosts, *sosPost) + } + + author := &user.UserWithoutPrivateInfo{ + ID: owner.ID, + ProfileImageURL: owner.ProfileImageURL, + Nickname: owner.Nickname, + } + + sosPostList, err := sosPostService.FindSosPosts(ctx, 1, 3, "newest", "all") + if err != nil { + t.Errorf("got %v want %v", err, nil) + } + + for i, sosPost := range sosPostList.Items { + assertConditionEquals(t, sosPost.Conditions, conditionIDs) + assertPetEquals(t, sosPost.Pets[i-1], addPets[i-1]) + assertMediaEquals(t, sosPost.Media, (&media.MediaList{sosPostImage, sosPostImage2}).ToMediaViewList()) + assertAuthorEquals(t, sosPost.Author, author) + + idx := len(sosPostList.Items) - i - 1 + + assertDatesEquals(t, sosPost.Dates, sosPosts[idx].Dates) + + if sosPost.Title != sosPosts[idx].Title { + t.Errorf("got %v want %v", sosPost.Title, sosPosts[idx].Title) + } + if sosPost.Content != sosPosts[idx].Content { + t.Errorf("got %v want %v", sosPost.Content, sosPosts[idx].Content) + } + if sosPost.Reward != sosPosts[idx].Reward { + t.Errorf("got %v want %v", sosPost.Reward, sosPosts[idx].Reward) + } + if sosPost.CareType != sosPosts[idx].CareType { + t.Errorf("got %v want %v", sosPost.CareType, sosPosts[idx].CareType) + } + if sosPost.CarerGender != sosPosts[idx].CarerGender { + t.Errorf("got %v want %v", sosPost.CarerGender, sosPosts[idx].CarerGender) + } + if sosPost.RewardType != sosPosts[idx].RewardType { + t.Errorf("got %v want %v", sosPost.RewardType, sosPosts[idx].RewardType) + } + if sosPost.ThumbnailID != sosPostImage.ID { + t.Errorf("got %v want %v", sosPost.ThumbnailID, sosPostImage.ID) + } + } + }) + t.Run("전체 돌봄 급구 게시글 중 반려동물이 'dog'인 경우만 조회한다", func(t *testing.T) { + ctx := context.Background() + db, tearDown := setUp(ctx, t) + defer tearDown(t) + + mediaService := service.NewMediaService(db, nil) + profileImage, _ := mediaService.CreateMedia(ctx, &media.Media{ + MediaType: media.IMAGE_MEDIA_TYPE, + URL: "https://test.com", + }) + sosPostImage, _ := mediaService.CreateMedia(ctx, &media.Media{ + MediaType: media.IMAGE_MEDIA_TYPE, + URL: "https://test2.com", + }) + sosPostImage2, _ := mediaService.CreateMedia(ctx, &media.Media{ + MediaType: media.IMAGE_MEDIA_TYPE, + URL: "https://test3.com", + }) + + userService := service.NewUserService(db, mediaService) + owner, err := userService.RegisterUser(ctx, &user.RegisterUserRequest{ + Email: "test@example.com", + Nickname: "nickname", + Fullname: "fullname", + ProfileImageID: &profileImage.ID, + FirebaseProviderType: user.FirebaseProviderTypeKakao, + FirebaseUID: "1234", + }) + if err != nil { + t.Errorf("RegisterUser failed: %v", err) + return + } + + uid := owner.FirebaseUID + + pets := pet.AddPetsToOwnerRequest{ + Pets: []pet.AddPetRequest{ + { + Name: "dog_1", + PetType: "dog", + Sex: "male", + Neutered: true, + Breed: "poodle", + BirthDate: "2020-01-01", + WeightInKg: 10.0, + Remarks: "", + ProfileImageID: nil, + }, + { + Name: "dog_2", + PetType: "dog", + Sex: "male", + Neutered: true, + Breed: "poodle", + BirthDate: "2020-02-01", + WeightInKg: 10.0, + Remarks: "", + ProfileImageID: nil, + }, + { + Name: "cat_1", + PetType: "cat", + Sex: "female", + Neutered: true, + Breed: "munchkin", + BirthDate: "2020-03-01", + WeightInKg: 8.0, + Remarks: "", + ProfileImageID: nil, + }, + }, + } + + addPets, err := userService.AddPetsToOwner(ctx, uid, pets) + if err != nil { + t.Errorf(err.Err.Error()) + } + + sosPostService := service.NewSosPostService(db) + + conditionIDs := []int{1, 2} + + var sosPosts []sos_post.WriteSosPostView + + // 강아지인 경우 + for i := 1; i < 3; i++ { + sosPost, err := sosPostService.WriteSosPost(ctx, uid, &sos_post.WriteSosPostRequest{ + Title: fmt.Sprintf("Title%d", i), + Content: fmt.Sprintf("Test Content%d", i), + ImageIDs: []int{sosPostImage.ID, sosPostImage2.ID}, + Reward: fmt.Sprintf("Test Reward%d", i), + Dates: []sos_post.SosDateView{{"2024-03-30", "2024-03-30"}, + {"2024-04-01", "2024-04-02"}}, + CareType: sos_post.CareTypeFoster, + CarerGender: sos_post.CarerGenderMale, + RewardType: sos_post.RewardTypeFee, + ConditionIDs: conditionIDs, + PetIDs: []int{addPets[i-1].ID}, + }) + + if err != nil { + t.Errorf(err.Err.Error()) + } + + sosPosts = append(sosPosts, *sosPost) + } + + // 고양이인 경우 + _, err = sosPostService.WriteSosPost(ctx, uid, &sos_post.WriteSosPostRequest{ + Title: "Title3", + Content: "Test Content3", + ImageIDs: []int{sosPostImage.ID, sosPostImage2.ID}, + Reward: "Test Reward3", + Dates: []sos_post.SosDateView{{"2024-03-30", "2024-03-30"}, + {"2024-04-01", "2024-04-02"}}, + CareType: sos_post.CareTypeFoster, + CarerGender: sos_post.CarerGenderMale, + RewardType: sos_post.RewardTypeFee, + ConditionIDs: conditionIDs, + PetIDs: []int{addPets[2].ID}, + }) + + // 강아지, 고양이인 경우 + _, err = sosPostService.WriteSosPost(ctx, uid, &sos_post.WriteSosPostRequest{ + Title: "Title4", + Content: "Test Content4", + ImageIDs: []int{sosPostImage.ID, sosPostImage2.ID}, + Reward: "Test Reward4", + Dates: []sos_post.SosDateView{{"2024-03-30", "2024-03-30"}, + {"2024-04-01", "2024-04-02"}}, + CareType: sos_post.CareTypeFoster, + CarerGender: sos_post.CarerGenderMale, + RewardType: sos_post.RewardTypeFee, + ConditionIDs: conditionIDs, + PetIDs: []int{addPets[0].ID, addPets[2].ID}, + }) + + author := &user.UserWithoutPrivateInfo{ + ID: owner.ID, + ProfileImageURL: owner.ProfileImageURL, + Nickname: owner.Nickname, + } + + sosPostList, err := sosPostService.FindSosPosts(ctx, 1, 3, "newest", "all") + if err != nil { + t.Errorf("got %v want %v", err, nil) + } + + for i, sosPost := range sosPostList.Items { + assertConditionEquals(t, sosPost.Conditions, conditionIDs) + assertPetEquals(t, sosPost.Pets[i-1], addPets[i-1]) + assertMediaEquals(t, sosPost.Media, (&media.MediaList{sosPostImage, sosPostImage2}).ToMediaViewList()) + assertAuthorEquals(t, sosPost.Author, author) + + idx := len(sosPostList.Items) - i - 1 + + assertDatesEquals(t, sosPost.Dates, sosPosts[idx].Dates) + + if sosPost.Title != sosPosts[idx].Title { + t.Errorf("got %v want %v", sosPost.Title, sosPosts[idx].Title) + } + if sosPost.Content != sosPosts[idx].Content { + t.Errorf("got %v want %v", sosPost.Content, sosPosts[idx].Content) + } + if sosPost.Reward != sosPosts[idx].Reward { + t.Errorf("got %v want %v", sosPost.Reward, sosPosts[idx].Reward) + } + if sosPost.CareType != sosPosts[idx].CareType { + t.Errorf("got %v want %v", sosPost.CareType, sosPosts[idx].CareType) + } + if sosPost.CarerGender != sosPosts[idx].CarerGender { + t.Errorf("got %v want %v", sosPost.CarerGender, sosPosts[idx].CarerGender) + } + if sosPost.RewardType != sosPosts[idx].RewardType { + t.Errorf("got %v want %v", sosPost.RewardType, sosPosts[idx].RewardType) + } + if sosPost.ThumbnailID != sosPostImage.ID { + t.Errorf("got %v want %v", sosPost.ThumbnailID, sosPostImage.ID) + } + } + }) t.Run("작성자 ID로 돌봄 급구 게시글을 조회합니다.", func(t *testing.T) { ctx := context.Background() db, tearDown := setUp(ctx, t) From a00b5b98966802cbed38242bbf6229fc9452b6b5 Mon Sep 17 00:00:00 2001 From: choiseyeon Date: Mon, 15 Apr 2024 03:10:15 +0900 Subject: [PATCH 09/21] fix: update FindSosPostByID --- cmd/server/handler/sos_post_handler.go | 7 +- internal/postgres/sos_post_store.go | 103 +++++++++++------- internal/service/sos_post_service.go | 30 +---- .../service/tests/sos_post_service_test.go | 4 +- 4 files changed, 76 insertions(+), 68 deletions(-) diff --git a/cmd/server/handler/sos_post_handler.go b/cmd/server/handler/sos_post_handler.go index b191d66f..b1e23738 100644 --- a/cmd/server/handler/sos_post_handler.go +++ b/cmd/server/handler/sos_post_handler.go @@ -104,17 +104,16 @@ func (h *SosPostHandler) FindSosPosts(c echo.Context) error { // @Summary 게시글 ID로 돌봄급구 게시글을 조회합니다. // @Description // @Tags posts -// @Accept json // @Produce json -// @Param id path string true "게시글 ID" +// @Param id path int true "게시글 ID" // @Success 200 {object} sos_post.FindSosPostView // @Router /posts/sos/{id} [get] func (h *SosPostHandler) FindSosPostByID(c echo.Context) error { - SosPostID, err := pnd.ParseIDFromPath(c, "id") + id, err := pnd.ParseIDFromPath(c, "id") if err != nil { return c.JSON(err.StatusCode, err) } - res, err := h.sosPostService.FindSosPostByID(c.Request().Context(), *SosPostID) + res, err := h.sosPostService.FindSosPostByID(c.Request().Context(), *id) if err != nil { return c.JSON(err.StatusCode, err) } diff --git a/internal/postgres/sos_post_store.go b/internal/postgres/sos_post_store.go index 41f9c54d..ca9a43f2 100644 --- a/internal/postgres/sos_post_store.go +++ b/internal/postgres/sos_post_store.go @@ -249,7 +249,7 @@ func FindSosPosts(ctx context.Context, tx *database.Tx, page int, size int, sort sosPostList := sos_post.NewSosPostInfoList(page, size) for rows.Next() { sosPost := sos_post.SosPostInfo{} - var datesData, petsData, mediaData, conditionsData string + var datesData, petsData, mediaData, conditionsData []byte if err := rows.Scan( &sosPost.ID, &sosPost.Title, @@ -269,19 +269,18 @@ func FindSosPosts(ctx context.Context, tx *database.Tx, page int, size int, sort return nil, pnd.FromPostgresError(err) } - if err := json.Unmarshal([]byte(datesData), &sosPost.Dates); err != nil { + if err := json.Unmarshal(datesData, &sosPost.Dates); err != nil { return nil, pnd.FromPostgresError(err) } - if err := json.Unmarshal([]byte(petsData), &sosPost.Pets); err != nil { + if err := json.Unmarshal(petsData, &sosPost.Pets); err != nil { return nil, pnd.FromPostgresError(err) } - if err := json.Unmarshal([]byte(mediaData), &sosPost.Media); err != nil { + if err := json.Unmarshal(mediaData, &sosPost.Media); err != nil { return nil, pnd.FromPostgresError(err) } - if err := json.Unmarshal([]byte(conditionsData), &sosPost.Conditions); err != nil { + if err := json.Unmarshal(conditionsData, &sosPost.Conditions); err != nil { return nil, pnd.FromPostgresError(err) } - fmt.Println(sosPost.ID) sosPostList.Items = append(sosPostList.Items, sosPost) } if err := rows.Err(); err != nil { @@ -358,14 +357,14 @@ func FindSosPostsByAuthorID(ctx context.Context, tx *database.Tx, authorID int, rows, err := tx.QueryContext(ctx, query, authorID, size+1, (page-1)*size) if err != nil { - return &sos_post.SosPostInfoList{}, pnd.FromPostgresError(err) + return nil, pnd.FromPostgresError(err) } defer rows.Close() sosPostList := sos_post.NewSosPostInfoList(page, size) for rows.Next() { sosPost := sos_post.SosPostInfo{} - var datesData, petsData, mediaData, conditionsData string + var datesData, petsData, mediaData, conditionsData []byte if err := rows.Scan( &sosPost.ID, @@ -386,16 +385,16 @@ func FindSosPostsByAuthorID(ctx context.Context, tx *database.Tx, authorID int, return nil, pnd.FromPostgresError(err) } - if err := json.Unmarshal([]byte(datesData), &sosPost.Dates); err != nil { + if err := json.Unmarshal(datesData, &sosPost.Dates); err != nil { return nil, pnd.FromPostgresError(err) } - if err := json.Unmarshal([]byte(petsData), &sosPost.Pets); err != nil { + if err := json.Unmarshal(petsData, &sosPost.Pets); err != nil { return nil, pnd.FromPostgresError(err) } - if err := json.Unmarshal([]byte(mediaData), &sosPost.Media); err != nil { + if err := json.Unmarshal(mediaData, &sosPost.Media); err != nil { return nil, pnd.FromPostgresError(err) } - if err := json.Unmarshal([]byte(conditionsData), &sosPost.Conditions); err != nil { + if err := json.Unmarshal(conditionsData, &sosPost.Conditions); err != nil { return nil, pnd.FromPostgresError(err) } @@ -409,45 +408,73 @@ func FindSosPostsByAuthorID(ctx context.Context, tx *database.Tx, authorID int, return sosPostList, nil } -func FindSosPostByID(ctx context.Context, tx *database.Tx, id int) (*sos_post.SosPost, *pnd.AppError) { - const query = ` - SELECT - id, - author_id, - title, - content, - reward, - care_type, - carer_gender, - reward_type, - thumbnail_id, - created_at, - updated_at - FROM - sos_posts - WHERE - id = $1 AND - deleted_at IS NULL - ` +func FindSosPostByID(ctx context.Context, tx *database.Tx, id int) (*sos_post.SosPostInfo, *pnd.AppError) { + query := fmt.Sprintf(` + SELECT + v_sos_posts.id, + v_sos_posts.title, + v_sos_posts.content, + v_sos_posts.reward, + v_sos_posts.reward_type, + v_sos_posts.care_type, + v_sos_posts.carer_gender, + v_sos_posts.thumbnail_id, + v_sos_posts.author_id, + v_sos_posts.created_at, + v_sos_posts.updated_at, + v_sos_posts.dates, + v_pets.pets_info, + v_media.media_info, + v_conditions.conditions_info + FROM + v_sos_posts + LEFT JOIN v_pets ON v_sos_posts.id = v_pets.sos_post_id + LEFT JOIN v_media ON v_sos_posts.id = v_media.sos_post_id + LEFT JOIN v_conditions ON v_sos_posts.id = v_conditions.sos_post_id + WHERE + v_sos_posts.id = $1; - sosPost := &sos_post.SosPost{} - if err := tx.QueryRowContext(ctx, query, id).Scan( + `, + ) + + row := tx.QueryRowContext(ctx, query, id) + + sosPost := sos_post.SosPostInfo{} + + var datesData, petsData, mediaData, conditionsData []byte + if err := row.Scan( &sosPost.ID, - &sosPost.AuthorID, &sosPost.Title, &sosPost.Content, &sosPost.Reward, + &sosPost.RewardType, &sosPost.CareType, &sosPost.CarerGender, - &sosPost.RewardType, &sosPost.ThumbnailID, + &sosPost.AuthorID, &sosPost.CreatedAt, &sosPost.UpdatedAt, - ); err != nil { + &datesData, + &petsData, + &mediaData, + &conditionsData); err != nil { return nil, pnd.FromPostgresError(err) } - return sosPost, nil + if err := json.Unmarshal(datesData, &sosPost.Dates); err != nil { + return nil, pnd.FromPostgresError(err) + } + if err := json.Unmarshal(petsData, &sosPost.Pets); err != nil { + return nil, pnd.FromPostgresError(err) + } + if err := json.Unmarshal(mediaData, &sosPost.Media); err != nil { + return nil, pnd.FromPostgresError(err) + } + if err := json.Unmarshal(conditionsData, &sosPost.Conditions); err != nil { + return nil, pnd.FromPostgresError(err) + } + + return &sosPost, nil } func UpdateSosPost(ctx context.Context, tx *database.Tx, request *sos_post.UpdateSosPostRequest) (*sos_post.SosPost, *pnd.AppError) { diff --git a/internal/service/sos_post_service.go b/internal/service/sos_post_service.go index 081b813d..44abd91b 100644 --- a/internal/service/sos_post_service.go +++ b/internal/service/sos_post_service.go @@ -145,26 +145,6 @@ func (service *SosPostService) FindSosPostByID(ctx context.Context, id int) (*so return nil, err } - mediaData, err := postgres.FindResourceMediaByResourceID(ctx, tx, sosPost.ID, string(media.SosResourceType)) - if err != nil { - return nil, err - } - - conditions, err := postgres.FindConditionByID(ctx, tx, sosPost.ID) - if err != nil { - return nil, err - } - - pets, err := postgres.FindPetsByID(ctx, tx, sosPost.ID) - if err != nil { - return nil, err - } - - dates, err := postgres.FindDatesBySosPostID(ctx, tx, sosPost.ID) - if err != nil { - return nil, err - } - author, err := postgres.FindUserByID(ctx, tx, sosPost.AuthorID, true) if err != nil { return nil, err @@ -174,12 +154,12 @@ func (service *SosPostService) FindSosPostByID(ctx context.Context, id int) (*so return nil, err } - return sosPost.ToFindSosPostView( + return sosPost.ToFindSosPostInfoView( author.ToUserWithoutPrivateInfo(), - mediaData.ToMediaViewList(), - conditions.ToConditionViewList(), - pets.ToPetViewList(), - dates.ToSosDateViewList(), + sosPost.Media.ToMediaViewList(), + sosPost.Conditions.ToConditionViewList(), + sosPost.Pets.ToPetViewList(), + sosPost.Dates.ToSosDateViewList(), ), nil } diff --git a/internal/service/tests/sos_post_service_test.go b/internal/service/tests/sos_post_service_test.go index 0af4a435..f59230c2 100644 --- a/internal/service/tests/sos_post_service_test.go +++ b/internal/service/tests/sos_post_service_test.go @@ -669,7 +669,6 @@ func TestSosPostService(t *testing.T) { sosPostService := service.NewSosPostService(db) conditionIDs := []int{1, 2} - //krLocation, _ := time.LoadLocation("Asia/Seoul") sosPosts := make([]sos_post.WriteSosPostView, 0) for i := 1; i < 4; i++ { @@ -758,6 +757,9 @@ func TestSosPostService(t *testing.T) { URL: "https://test3.com", }) + sosPostImage.CreatedAt = sosPostImage.CreatedAt[:len(sosPostImage.CreatedAt)-1] + sosPostImage2.CreatedAt = sosPostImage2.CreatedAt[:len(sosPostImage2.CreatedAt)-1] + userService := service.NewUserService(db, mediaService) owner, err := userService.RegisterUser(ctx, &user.RegisterUserRequest{ From b429fe969f2e5944239c59392e3f920772b20c3a Mon Sep 17 00:00:00 2001 From: choiseyeon Date: Mon, 15 Apr 2024 03:20:14 +0900 Subject: [PATCH 10/21] fix: update SOS posts testcode --- internal/service/tests/sos_post_service_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/tests/sos_post_service_test.go b/internal/service/tests/sos_post_service_test.go index f59230c2..1e6fe706 100644 --- a/internal/service/tests/sos_post_service_test.go +++ b/internal/service/tests/sos_post_service_test.go @@ -757,8 +757,8 @@ func TestSosPostService(t *testing.T) { URL: "https://test3.com", }) - sosPostImage.CreatedAt = sosPostImage.CreatedAt[:len(sosPostImage.CreatedAt)-1] - sosPostImage2.CreatedAt = sosPostImage2.CreatedAt[:len(sosPostImage2.CreatedAt)-1] + sosPostImage.CreatedAt = sosPostImage.CreatedAt[:len(sosPostImage.CreatedAt)-6] + sosPostImage2.CreatedAt = sosPostImage2.CreatedAt[:len(sosPostImage2.CreatedAt)-6] userService := service.NewUserService(db, mediaService) From 0bc070cf2f8f084df501b043612119fc6dee5cce Mon Sep 17 00:00:00 2001 From: choiseyeon Date: Mon, 15 Apr 2024 03:29:26 +0900 Subject: [PATCH 11/21] fix: SOS posts test code error correction --- .../service/tests/sos_post_service_test.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/internal/service/tests/sos_post_service_test.go b/internal/service/tests/sos_post_service_test.go index 1e6fe706..29d1d439 100644 --- a/internal/service/tests/sos_post_service_test.go +++ b/internal/service/tests/sos_post_service_test.go @@ -757,9 +757,6 @@ func TestSosPostService(t *testing.T) { URL: "https://test3.com", }) - sosPostImage.CreatedAt = sosPostImage.CreatedAt[:len(sosPostImage.CreatedAt)-6] - sosPostImage2.CreatedAt = sosPostImage2.CreatedAt[:len(sosPostImage2.CreatedAt)-6] - userService := service.NewUserService(db, mediaService) owner, err := userService.RegisterUser(ctx, &user.RegisterUserRequest{ @@ -821,7 +818,6 @@ func TestSosPostService(t *testing.T) { if err != nil { t.Errorf(err.Err.Error()) } - sosPosts = append(sosPosts, *sosPost) } @@ -1011,8 +1007,18 @@ func assertPetEquals(t *testing.T, got pet.PetView, want pet.PetView) { func assertMediaEquals(t *testing.T, got media.MediaViewList, want media.MediaViewList) { for i, media := range want { - if !reflect.DeepEqual(got[i], media) { - t.Errorf("got %v want %v", got[i], media) + if got[i].ID != media.ID { + t.Errorf("got %v want %v", got[i].ID, media.ID) + } + if got[i].MediaType != media.MediaType { + t.Errorf("got %v want %v", got[i].MediaType, media.MediaType) + } + if got[i].URL != media.URL { + t.Errorf("got %v want %v", got[i].URL, media.URL) + } + if got[i].CreatedAt != media.CreatedAt { + t.Errorf("got %v want %v", got[i].CreatedAt[:len(got[i].CreatedAt)-6], media.CreatedAt) + } } } From ddd0ba747856bd8b4c58297bab297ed313a08c31 Mon Sep 17 00:00:00 2001 From: choiseyeon Date: Mon, 15 Apr 2024 03:32:10 +0900 Subject: [PATCH 12/21] fix: SOS posts test code error correction --- internal/service/tests/sos_post_service_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/tests/sos_post_service_test.go b/internal/service/tests/sos_post_service_test.go index 29d1d439..50ea3315 100644 --- a/internal/service/tests/sos_post_service_test.go +++ b/internal/service/tests/sos_post_service_test.go @@ -1017,7 +1017,7 @@ func assertMediaEquals(t *testing.T, got media.MediaViewList, want media.MediaVi t.Errorf("got %v want %v", got[i].URL, media.URL) } if got[i].CreatedAt != media.CreatedAt { - t.Errorf("got %v want %v", got[i].CreatedAt[:len(got[i].CreatedAt)-6], media.CreatedAt) + t.Errorf("got %v want %v", got[i].CreatedAt[:len(got[i].CreatedAt)-6], media.CreatedAt[:len(got[i].CreatedAt)-1]) } } From b8db3adeecc748bd14c93054fb0b7e134aef1a58 Mon Sep 17 00:00:00 2001 From: choiseyeon Date: Mon, 15 Apr 2024 03:39:02 +0900 Subject: [PATCH 13/21] fix: SOS posts test code error correction --- internal/service/tests/sos_post_service_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/tests/sos_post_service_test.go b/internal/service/tests/sos_post_service_test.go index 50ea3315..d669e252 100644 --- a/internal/service/tests/sos_post_service_test.go +++ b/internal/service/tests/sos_post_service_test.go @@ -1017,7 +1017,7 @@ func assertMediaEquals(t *testing.T, got media.MediaViewList, want media.MediaVi t.Errorf("got %v want %v", got[i].URL, media.URL) } if got[i].CreatedAt != media.CreatedAt { - t.Errorf("got %v want %v", got[i].CreatedAt[:len(got[i].CreatedAt)-6], media.CreatedAt[:len(got[i].CreatedAt)-1]) + t.Errorf("got %v want %v", got[i].CreatedAt[:len(got[i].CreatedAt)-6], media.CreatedAt[:len(media.CreatedAt)-1]) } } From 3b5a9679084475bafc90181bbaf24160c7e066bf Mon Sep 17 00:00:00 2001 From: choiseyeon Date: Mon, 15 Apr 2024 03:42:42 +0900 Subject: [PATCH 14/21] fix: SOS posts test code error correction --- internal/service/tests/sos_post_service_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/internal/service/tests/sos_post_service_test.go b/internal/service/tests/sos_post_service_test.go index d669e252..6695c602 100644 --- a/internal/service/tests/sos_post_service_test.go +++ b/internal/service/tests/sos_post_service_test.go @@ -1016,10 +1016,6 @@ func assertMediaEquals(t *testing.T, got media.MediaViewList, want media.MediaVi if got[i].URL != media.URL { t.Errorf("got %v want %v", got[i].URL, media.URL) } - if got[i].CreatedAt != media.CreatedAt { - t.Errorf("got %v want %v", got[i].CreatedAt[:len(got[i].CreatedAt)-6], media.CreatedAt[:len(media.CreatedAt)-1]) - - } } } From d6b3ec124d4b8c54b73f7535fb4ef73f59902814 Mon Sep 17 00:00:00 2001 From: choiseyeon Date: Tue, 16 Apr 2024 00:04:07 +0900 Subject: [PATCH 15/21] feat: update migrate naming --- .../000017_create_posts_view.down.sql | 4 +-- db/migrations/000017_create_posts_view.up.sql | 34 +++++++++++-------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/db/migrations/000017_create_posts_view.down.sql b/db/migrations/000017_create_posts_view.down.sql index 99a4c911..d4c33ab0 100644 --- a/db/migrations/000017_create_posts_view.down.sql +++ b/db/migrations/000017_create_posts_view.down.sql @@ -1,4 +1,4 @@ DROP VIEW IF EXISTS v_sos_posts; -DROP VIEW IF EXISTS v_pets; -DROP VIEW IF EXISTS v_media; DROP VIEW IF EXISTS v_conditions; +DROP VIEW IF EXISTS v_pets_for_sos_posts; +DROP VIEW IF EXISTS v_media_for_sos_posts; \ No newline at end of file diff --git a/db/migrations/000017_create_posts_view.up.sql b/db/migrations/000017_create_posts_view.up.sql index f8a6a737..6dee2e7a 100644 --- a/db/migrations/000017_create_posts_view.up.sql +++ b/db/migrations/000017_create_posts_view.up.sql @@ -1,3 +1,4 @@ +-- 돌봄 급구(SosPosts) 테이블 VIEW 생성 CREATE OR REPLACE VIEW v_sos_posts AS SELECT sos_posts.id, @@ -23,7 +24,21 @@ WHERE AND sos_posts_dates.deleted_at IS NULL GROUP BY sos_posts.id; -CREATE OR REPLACE VIEW v_pets AS +-- 돌봄 급구 Conditions 테이블 VIEW 생성 +CREATE OR REPLACE VIEW v_conditions AS +SELECT + sos_posts_conditions.sos_post_id, + json_agg(sos_conditions.*) FILTER (WHERE sos_conditions.deleted_at IS NULL) AS conditions_info +FROM + sos_posts_conditions + LEFT JOIN sos_conditions ON sos_posts_conditions.sos_condition_id = sos_conditions.id +WHERE + sos_conditions.deleted_at IS NULL AND + sos_posts_conditions.deleted_at IS NULL +GROUP BY sos_posts_conditions.sos_post_id; + +-- 돌봄 급구 관련 Pets 테이블 VIEW 생성 +CREATE OR REPLACE VIEW v_pets_for_sos_posts AS SELECT sos_posts_pets.sos_post_id, array_agg(pets.pet_type) AS pet_type_list, @@ -36,7 +51,8 @@ WHERE AND sos_posts_pets.deleted_at IS NULL GROUP BY sos_posts_pets.sos_post_id; -CREATE OR REPLACE VIEW v_media AS +-- 돌봄 급구 관련 Media 테이블 VIEW 생성 +CREATE OR REPLACE VIEW v_media_for_sos_posts AS SELECT resource_media.resource_id AS sos_post_id, json_agg(media.*) FILTER (WHERE media.deleted_at IS NULL) AS media_info @@ -46,16 +62,4 @@ FROM WHERE media.deleted_at IS NULL AND resource_media.deleted_at IS NULL -GROUP BY resource_media.resource_id; - -CREATE OR REPLACE VIEW v_conditions AS -SELECT - sos_posts_conditions.sos_post_id, - json_agg(sos_conditions.*) FILTER (WHERE sos_conditions.deleted_at IS NULL) AS conditions_info -FROM - sos_posts_conditions - LEFT JOIN sos_conditions ON sos_posts_conditions.sos_condition_id = sos_conditions.id -WHERE - sos_conditions.deleted_at IS NULL AND - sos_posts_conditions.deleted_at IS NULL -GROUP BY sos_posts_conditions.sos_post_id; \ No newline at end of file +GROUP BY resource_media.resource_id; \ No newline at end of file From f63f8a74b5420008e4e62782f85de54cd93455ef Mon Sep 17 00:00:00 2001 From: choiseyeon Date: Tue, 16 Apr 2024 01:14:18 +0900 Subject: [PATCH 16/21] fix: update database view name --- internal/postgres/sos_post_store.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/internal/postgres/sos_post_store.go b/internal/postgres/sos_post_store.go index ca9a43f2..de4edbee 100644 --- a/internal/postgres/sos_post_store.go +++ b/internal/postgres/sos_post_store.go @@ -218,13 +218,13 @@ func FindSosPosts(ctx context.Context, tx *database.Tx, page int, size int, sort v_sos_posts.created_at, v_sos_posts.updated_at, v_sos_posts.dates, - v_pets.pets_info, - v_media.media_info, + v_pets_for_sos_posts.pets_info, + v_media_for_sos_posts.media_info, v_conditions.conditions_info FROM v_sos_posts - LEFT JOIN v_pets ON v_sos_posts.id = v_pets.sos_post_id - LEFT JOIN v_media ON v_sos_posts.id = v_media.sos_post_id + LEFT JOIN v_pets_for_sos_posts ON v_sos_posts.id = v_pets_for_sos_posts.sos_post_id + LEFT JOIN v_media_for_sos_posts ON v_sos_posts.id = v_media_for_sos_posts.sos_post_id LEFT JOIN v_conditions ON v_sos_posts.id = v_conditions.sos_post_id WHERE v_sos_posts.earliest_date_start_at >= '%s' @@ -332,13 +332,13 @@ func FindSosPostsByAuthorID(ctx context.Context, tx *database.Tx, authorID int, v_sos_posts.created_at, v_sos_posts.updated_at, v_sos_posts.dates, - v_pets.pets_info, - v_media.media_info, + v_pets_for_sos_posts.pets_info, + v_media_for_sos_posts.media_info, v_conditions.conditions_info FROM v_sos_posts - LEFT JOIN v_pets ON v_sos_posts.id = v_pets.sos_post_id - LEFT JOIN v_media ON v_sos_posts.id = v_media.sos_post_id + LEFT JOIN v_pets_for_sos_posts ON v_sos_posts.id = v_pets_for_sos_posts.sos_post_id + LEFT JOIN v_media_for_sos_posts ON v_sos_posts.id = v_media_for_sos_posts.sos_post_id LEFT JOIN v_conditions ON v_sos_posts.id = v_conditions.sos_post_id WHERE v_sos_posts.earliest_date_start_at >= '%s' @@ -423,13 +423,13 @@ func FindSosPostByID(ctx context.Context, tx *database.Tx, id int) (*sos_post.So v_sos_posts.created_at, v_sos_posts.updated_at, v_sos_posts.dates, - v_pets.pets_info, - v_media.media_info, + v_pets_for_sos_posts.pets_info, + v_media_for_sos_posts.media_info, v_conditions.conditions_info FROM v_sos_posts - LEFT JOIN v_pets ON v_sos_posts.id = v_pets.sos_post_id - LEFT JOIN v_media ON v_sos_posts.id = v_media.sos_post_id + LEFT JOIN v_pets_for_sos_posts ON v_sos_posts.id = v_pets_for_sos_posts.sos_post_id + LEFT JOIN v_media_for_sos_posts ON v_sos_posts.id = v_media_for_sos_posts.sos_post_id LEFT JOIN v_conditions ON v_sos_posts.id = v_conditions.sos_post_id WHERE v_sos_posts.id = $1; From 50aaf3619edefc62d0c4ed868ab5fe9db2a24df7 Mon Sep 17 00:00:00 2001 From: choiseyeon Date: Tue, 16 Apr 2024 01:30:18 +0900 Subject: [PATCH 17/21] feat: change entity date type --- internal/domain/sos_post/sos_post.go | 24 +++++++++++++----------- internal/domain/sos_post/view.go | 16 ++++++++-------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/internal/domain/sos_post/sos_post.go b/internal/domain/sos_post/sos_post.go index fd7f2d6e..bd2c67a7 100644 --- a/internal/domain/sos_post/sos_post.go +++ b/internal/domain/sos_post/sos_post.go @@ -6,6 +6,7 @@ import ( "github.com/pet-sitter/pets-next-door-api/internal/domain/media" "github.com/pet-sitter/pets-next-door-api/internal/domain/pet" "github.com/pet-sitter/pets-next-door-api/internal/infra/database" + "time" ) type CareType string @@ -39,9 +40,9 @@ type SosPost struct { CarerGender CarerGender `field:"carer_gender"` RewardType RewardType `field:"reward_type"` ThumbnailID int `field:"thumbnail_id"` - CreatedAt string `field:"created_at"` - UpdatedAt string `field:"updated_at"` - DeletedAt string `field:"deleted_at"` + CreatedAt time.Time `field:"created_at"` + UpdatedAt time.Time `field:"updated_at"` + DeletedAt time.Time `field:"deleted_at"` } type SosPostList struct { @@ -62,8 +63,9 @@ type SosPostInfo struct { CarerGender CarerGender `field:"carerGender" json:"carerGender"` RewardType RewardType `field:"rewardType" json:"rewardType"` ThumbnailID int `field:"thumbnailId" json:"thumbnailId"` - CreatedAt string `field:"createdAt" json:"createdAt"` - UpdatedAt string `field:"updatedAt" json:"updatedAt"` + CreatedAt time.Time `field:"createdAt" json:"createdAt"` + UpdatedAt time.Time `field:"updatedAt" json:"updatedAt"` + DeletedAt time.Time `field:"deletedAt" json:"deletedAt"` } type SosPostInfoList struct { @@ -83,12 +85,12 @@ func NewSosPostInfoList(page int, size int) *SosPostInfoList { } type SosDates struct { - ID int `field:"id" json:"id"` - DateStartAt string `field:"date_start_at" json:"date_start_at"` - DateEndAt string `field:"date_end_at" json:"date_end_at"` - CreatedAt string `field:"created_at" json:"created_at"` - UpdatedAt string `field:"updated_at" json:"updated_at"` - DeletedAt string `field:"deleted_at" json:"deleted_at"` + ID int `field:"id" json:"id"` + DateStartAt string `field:"date_start_at" json:"date_start_at"` + DateEndAt string `field:"date_end_at" json:"date_end_at"` + CreatedAt time.Time `field:"created_at" json:"created_at"` + UpdatedAt time.Time `field:"updated_at" json:"updated_at"` + DeletedAt time.Time `field:"deleted_at" json:"deleted_at"` } type SosDatesList []*SosDates diff --git a/internal/domain/sos_post/view.go b/internal/domain/sos_post/view.go index 96b88622..29677e1a 100644 --- a/internal/domain/sos_post/view.go +++ b/internal/domain/sos_post/view.go @@ -81,8 +81,8 @@ func (p *SosPost) ToWriteSosPostView( CarerGender: p.CarerGender, RewardType: p.RewardType, ThumbnailID: p.ThumbnailID, - CreatedAt: p.CreatedAt, - UpdatedAt: p.UpdatedAt, + CreatedAt: p.CreatedAt.String(), + UpdatedAt: p.UpdatedAt.String(), } } @@ -125,8 +125,8 @@ func (p *SosPost) ToFindSosPostView( CarerGender: p.CarerGender, RewardType: p.RewardType, ThumbnailID: p.ThumbnailID, - CreatedAt: p.CreatedAt, - UpdatedAt: p.UpdatedAt, + CreatedAt: p.CreatedAt.String(), + UpdatedAt: p.UpdatedAt.String(), } } @@ -171,8 +171,8 @@ func (p *SosPostInfo) ToFindSosPostInfoView( CarerGender: p.CarerGender, RewardType: p.RewardType, ThumbnailID: p.ThumbnailID, - CreatedAt: p.CreatedAt, - UpdatedAt: p.UpdatedAt, + CreatedAt: p.CreatedAt.String(), + UpdatedAt: p.UpdatedAt.String(), } } @@ -228,8 +228,8 @@ func (p *SosPost) ToUpdateSosPostView( CarerGender: p.CarerGender, RewardType: p.RewardType, ThumbnailID: p.ThumbnailID, - CreatedAt: p.CreatedAt, - UpdatedAt: p.UpdatedAt, + CreatedAt: p.CreatedAt.String(), + UpdatedAt: p.UpdatedAt.String(), } } From a0aff3943ebaaa34ba895a6ed8e4659e4ce44bb7 Mon Sep 17 00:00:00 2001 From: Seyeon_Choi Date: Wed, 17 Apr 2024 06:02:58 +0900 Subject: [PATCH 18/21] feat: add migrate file --- .../000017_timestamp_with_timezone.down.sql | 0 .../000017_timestamp_with_timezone.up.sql | 9 ++++++ ....sql => 000018_create_posts_view.down.sql} | 0 ...up.sql => 000018_create_posts_view.up.sql} | 29 ++++++++++++++++--- 4 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 db/migrations/000017_timestamp_with_timezone.down.sql create mode 100644 db/migrations/000017_timestamp_with_timezone.up.sql rename db/migrations/{000017_create_posts_view.down.sql => 000018_create_posts_view.down.sql} (100%) rename db/migrations/{000017_create_posts_view.up.sql => 000018_create_posts_view.up.sql} (67%) diff --git a/db/migrations/000017_timestamp_with_timezone.down.sql b/db/migrations/000017_timestamp_with_timezone.down.sql new file mode 100644 index 00000000..e69de29b diff --git a/db/migrations/000017_timestamp_with_timezone.up.sql b/db/migrations/000017_timestamp_with_timezone.up.sql new file mode 100644 index 00000000..a72f0c35 --- /dev/null +++ b/db/migrations/000017_timestamp_with_timezone.up.sql @@ -0,0 +1,9 @@ +ALTER TABLE sos_dates + ALTER created_at TYPE timestamptz USING created_at AT TIME ZONE 'UTC', + ALTER updated_at TYPE timestamptz USING updated_at AT TIME ZONE 'UTC', + ALTER deleted_at TYPE timestamptz USING deleted_at AT TIME ZONE 'UTC'; + +ALTER TABLE sos_posts_dates + ALTER created_at TYPE timestamptz USING created_at AT TIME ZONE 'UTC', + ALTER updated_at TYPE timestamptz USING updated_at AT TIME ZONE 'UTC', + ALTER deleted_at TYPE timestamptz USING deleted_at AT TIME ZONE 'UTC'; \ No newline at end of file diff --git a/db/migrations/000017_create_posts_view.down.sql b/db/migrations/000018_create_posts_view.down.sql similarity index 100% rename from db/migrations/000017_create_posts_view.down.sql rename to db/migrations/000018_create_posts_view.down.sql diff --git a/db/migrations/000017_create_posts_view.up.sql b/db/migrations/000018_create_posts_view.up.sql similarity index 67% rename from db/migrations/000017_create_posts_view.up.sql rename to db/migrations/000018_create_posts_view.up.sql index 6dee2e7a..e795ccd3 100644 --- a/db/migrations/000017_create_posts_view.up.sql +++ b/db/migrations/000018_create_posts_view.up.sql @@ -42,15 +42,36 @@ CREATE OR REPLACE VIEW v_pets_for_sos_posts AS SELECT sos_posts_pets.sos_post_id, array_agg(pets.pet_type) AS pet_type_list, - json_agg(pets.*) FILTER (WHERE pets.deleted_at IS NULL) AS pets_info + json_agg( + json_build_object( + 'id', pets.id, + 'owner_id', pets.owner_id, + 'name', pets.name, + 'pet_type', pets.pet_type, + 'sex', pets.sex, + 'neutered', pets.neutered, + 'breed', pets.breed, + 'birth_date', pets.birth_date, + 'weight_in_kg', pets.weight_in_kg, + 'additional_note', pets.additional_note, + 'created_at', pets.created_at, + 'updated_at', pets.updated_at, + 'deleted_at', pets.deleted_at, + 'remarks', pets.remarks, + 'profile_image_id', pets.profile_image_id, + 'profile_image_url', media.url + ) + ) FILTER (WHERE pets.deleted_at IS NULL) AS pets_info FROM sos_posts_pets - LEFT JOIN pets ON sos_posts_pets.pet_id = pets.id + INNER JOIN pets ON sos_posts_pets.pet_id = pets.id AND pets.deleted_at IS NULL + LEFT JOIN media ON pets.profile_image_id = media.id WHERE - pets.deleted_at IS NULL - AND sos_posts_pets.deleted_at IS NULL + sos_posts_pets.deleted_at IS NULL GROUP BY sos_posts_pets.sos_post_id; + + -- 돌봄 급구 관련 Media 테이블 VIEW 생성 CREATE OR REPLACE VIEW v_media_for_sos_posts AS SELECT From 9aebf3088b3589e3d9a2e171787e80c5c7475265 Mon Sep 17 00:00:00 2001 From: Seyeon_Choi Date: Wed, 17 Apr 2024 06:08:44 +0900 Subject: [PATCH 19/21] fix: change SOS post column type --- internal/common/format.go | 6 ++++++ internal/domain/pet/view.go | 2 +- internal/domain/sos_post/sos_post.go | 32 ++++++++++++++-------------- internal/domain/sos_post/view.go | 16 +++++++------- 4 files changed, 31 insertions(+), 25 deletions(-) diff --git a/internal/common/format.go b/internal/common/format.go index f74bf279..cf193729 100644 --- a/internal/common/format.go +++ b/internal/common/format.go @@ -13,3 +13,9 @@ func FormatDate(datetimeStr string) string { func FormatTime(datetime time.Time) string { return datetime.Format("15:04") } + +// FormatDateTime formats datetime time.Time to datetime string. +// Example: 2021-01-01T10:06:23.9999999Z -> 2021-01-01T10:06:23 +func FormatDateTime(datetime time.Time) string { + return datetime.Format("2006-01-02T15:04:05") +} diff --git a/internal/domain/pet/view.go b/internal/domain/pet/view.go index ad2a1cf6..02b84efc 100644 --- a/internal/domain/pet/view.go +++ b/internal/domain/pet/view.go @@ -60,7 +60,7 @@ func (pet *PetWithProfileImage) ToPetView() *PetView { Sex: pet.Sex, Neutered: pet.Neutered, Breed: pet.Breed, - BirthDate: pet.BirthDate, + BirthDate: utils.FormatDate(pet.BirthDate), WeightInKg: pet.WeightInKg, Remarks: pet.Remarks, ProfileImageURL: pet.ProfileImageURL, diff --git a/internal/domain/sos_post/sos_post.go b/internal/domain/sos_post/sos_post.go index bd2c67a7..96d00671 100644 --- a/internal/domain/sos_post/sos_post.go +++ b/internal/domain/sos_post/sos_post.go @@ -50,22 +50,22 @@ type SosPostList struct { } type SosPostInfo struct { - ID int `field:"id" json:"id"` - AuthorID int `field:"author" json:"author"` - Title string `field:"title" json:"title"` - Content string `field:"content" json:"content"` - Media media.MediaList `field:"media" json:"media"` - Conditions ConditionList `field:"conditions" json:"conditions"` - Pets pet.PetList `field:"pets" json:"pets"` - Reward string `field:"reward" json:"reward"` - Dates SosDatesList `field:"dates" json:"dates"` - CareType CareType `field:"careType" json:"careType"` - CarerGender CarerGender `field:"carerGender" json:"carerGender"` - RewardType RewardType `field:"rewardType" json:"rewardType"` - ThumbnailID int `field:"thumbnailId" json:"thumbnailId"` - CreatedAt time.Time `field:"createdAt" json:"createdAt"` - UpdatedAt time.Time `field:"updatedAt" json:"updatedAt"` - DeletedAt time.Time `field:"deletedAt" json:"deletedAt"` + ID int `field:"id" json:"id"` + AuthorID int `field:"author" json:"author"` + Title string `field:"title" json:"title"` + Content string `field:"content" json:"content"` + Media media.MediaList `field:"media" json:"media"` + Conditions ConditionList `field:"conditions" json:"conditions"` + Pets pet.PetWithProfileList `field:"pets" json:"pets"` + Reward string `field:"reward" json:"reward"` + Dates SosDatesList `field:"dates" json:"dates"` + CareType CareType `field:"careType" json:"careType"` + CarerGender CarerGender `field:"carerGender" json:"carerGender"` + RewardType RewardType `field:"rewardType" json:"rewardType"` + ThumbnailID int `field:"thumbnailId" json:"thumbnailId"` + CreatedAt time.Time `field:"createdAt" json:"createdAt"` + UpdatedAt time.Time `field:"updatedAt" json:"updatedAt"` + DeletedAt time.Time `field:"deletedAt" json:"deletedAt"` } type SosPostInfoList struct { diff --git a/internal/domain/sos_post/view.go b/internal/domain/sos_post/view.go index 29677e1a..53ffc90d 100644 --- a/internal/domain/sos_post/view.go +++ b/internal/domain/sos_post/view.go @@ -81,8 +81,8 @@ func (p *SosPost) ToWriteSosPostView( CarerGender: p.CarerGender, RewardType: p.RewardType, ThumbnailID: p.ThumbnailID, - CreatedAt: p.CreatedAt.String(), - UpdatedAt: p.UpdatedAt.String(), + CreatedAt: utils.FormatDateTime(p.CreatedAt), + UpdatedAt: utils.FormatDateTime(p.UpdatedAt), } } @@ -125,8 +125,8 @@ func (p *SosPost) ToFindSosPostView( CarerGender: p.CarerGender, RewardType: p.RewardType, ThumbnailID: p.ThumbnailID, - CreatedAt: p.CreatedAt.String(), - UpdatedAt: p.UpdatedAt.String(), + CreatedAt: utils.FormatDateTime(p.CreatedAt), + UpdatedAt: utils.FormatDateTime(p.UpdatedAt), } } @@ -171,8 +171,8 @@ func (p *SosPostInfo) ToFindSosPostInfoView( CarerGender: p.CarerGender, RewardType: p.RewardType, ThumbnailID: p.ThumbnailID, - CreatedAt: p.CreatedAt.String(), - UpdatedAt: p.UpdatedAt.String(), + CreatedAt: utils.FormatDateTime(p.CreatedAt), + UpdatedAt: utils.FormatDateTime(p.UpdatedAt), } } @@ -228,8 +228,8 @@ func (p *SosPost) ToUpdateSosPostView( CarerGender: p.CarerGender, RewardType: p.RewardType, ThumbnailID: p.ThumbnailID, - CreatedAt: p.CreatedAt.String(), - UpdatedAt: p.UpdatedAt.String(), + CreatedAt: utils.FormatDateTime(p.CreatedAt), + UpdatedAt: utils.FormatDateTime(p.UpdatedAt), } } From 40bdd49c80aa60067b4c45335d471cda0865d778 Mon Sep 17 00:00:00 2001 From: Seyeon_Choi Date: Wed, 17 Apr 2024 06:10:53 +0900 Subject: [PATCH 20/21] fix: FindPetsByID error resolution --- internal/postgres/sos_post_store.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/internal/postgres/sos_post_store.go b/internal/postgres/sos_post_store.go index de4edbee..7f17bfcd 100644 --- a/internal/postgres/sos_post_store.go +++ b/internal/postgres/sos_post_store.go @@ -732,7 +732,7 @@ func FindConditionByID(ctx context.Context, tx *database.Tx, id int) (*sos_post. return &conditions, nil } -func FindPetsByID(ctx context.Context, tx *database.Tx, id int) (*pet.PetList, *pnd.AppError) { +func FindPetsByID(ctx context.Context, tx *database.Tx, id int) (*pet.PetWithProfileList, *pnd.AppError) { const sql = ` SELECT pets.id, @@ -746,19 +746,25 @@ func FindPetsByID(ctx context.Context, tx *database.Tx, id int) (*pet.PetList, * pets.weight_in_kg, pets.remarks, pets.created_at, - pets.updated_at + pets.updated_at, + media.url AS profile_image_url FROM pets INNER JOIN sos_posts_pets ON pets.id = sos_posts_pets.pet_id + LEFT JOIN + media + ON + pets.profile_image_id = media.id WHERE sos_posts_pets.sos_post_id = $1 AND - sos_posts_pets.deleted_at IS NULL + sos_posts_pets.deleted_at IS NULL; + ` - pets := pet.PetList{} + pets := pet.PetWithProfileList{} rows, err := tx.QueryContext(ctx, sql, id) if err != nil { return nil, pnd.FromPostgresError(err) @@ -766,7 +772,7 @@ func FindPetsByID(ctx context.Context, tx *database.Tx, id int) (*pet.PetList, * defer rows.Close() for rows.Next() { - pet := pet.Pet{} + pet := pet.PetWithProfileImage{} if err := rows.Scan( &pet.ID, &pet.OwnerID, @@ -780,6 +786,7 @@ func FindPetsByID(ctx context.Context, tx *database.Tx, id int) (*pet.PetList, * &pet.Remarks, &pet.CreatedAt, &pet.UpdatedAt, + &pet.ProfileImageURL, ); err != nil { return nil, pnd.FromPostgresError(err) } From 511a0eabaab2b6569b01595e4b33459667c31dd9 Mon Sep 17 00:00:00 2001 From: Seyeon_Choi Date: Wed, 17 Apr 2024 06:12:15 +0900 Subject: [PATCH 21/21] refactor: SOS posts testcode refactoring --- .../service/tests/sos_post_service_test.go | 896 ++++-------------- internal/tests/factories.go | 58 ++ internal/tests/service.go | 37 +- 3 files changed, 268 insertions(+), 723 deletions(-) diff --git a/internal/service/tests/sos_post_service_test.go b/internal/service/tests/sos_post_service_test.go index 6695c602..e18f9a49 100644 --- a/internal/service/tests/sos_post_service_test.go +++ b/internal/service/tests/sos_post_service_test.go @@ -2,7 +2,6 @@ package service_test import ( "context" - "fmt" pnd "github.com/pet-sitter/pets-next-door-api/api" "github.com/pet-sitter/pets-next-door-api/internal/domain/media" "github.com/pet-sitter/pets-next-door-api/internal/domain/pet" @@ -32,250 +31,116 @@ func TestSosPostService(t *testing.T) { db.Close() } } - t.Run("CreateSosPost", func(t *testing.T) { - t.Run("돌봄 급구 게시글을 작성힌다", func(t *testing.T) { + t.Run("돌봄 급구 게시글을 작성한다", func(t *testing.T) { ctx := context.Background() db, tearDown := setUp(ctx, t) defer tearDown(t) + // given mediaService := service.NewMediaService(db, nil) - profileImage, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test.com", - }) - sosPostImage, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test2.com", - }) - sosPostImage2, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test3.com", - }) + profileImage := tests.AddDummyMedia(t, ctx, mediaService) + sosPostImage := tests.AddDummyMedia(t, ctx, mediaService) + sosPostImage2 := tests.AddDummyMedia(t, ctx, mediaService) userService := service.NewUserService(db, mediaService) - - owner, err := userService.RegisterUser(ctx, &user.RegisterUserRequest{ - Email: "test@example.com", - Nickname: "nickname", - Fullname: "fullname", - ProfileImageID: &profileImage.ID, - FirebaseProviderType: user.FirebaseProviderTypeKakao, - FirebaseUID: "1234", - }) - if err != nil { - t.Errorf("RegisterUser failed: %v", err) - return - } - + userRequest := tests.GenerateDummyRegisterUserRequest(&profileImage.ID) + owner, _ := userService.RegisterUser(ctx, userRequest) uid := owner.FirebaseUID + addPets := tests.AddDummyPet(t, ctx, userService, uid, &profileImage.ID) - pets := pet.AddPetsToOwnerRequest{ - Pets: []pet.AddPetRequest{ - { - Name: "name", - PetType: "dog", - Sex: "male", - Neutered: true, - Breed: "poodle", - BirthDate: "2020-01-01", - WeightInKg: 10.0, - Remarks: "", - ProfileImageID: nil, - }, - }, - } - - addPets, err := userService.AddPetsToOwner(ctx, uid, pets) - if err != nil { - t.Errorf(err.Err.Error()) - } - + // when sosPostService := service.NewSosPostService(db) + imageIDs := []int{sosPostImage.ID, sosPostImage2.ID} + petIDs := []int{addPets.ID} - conditionIDs := []int{1, 2} - - writeSosPostRequest := &sos_post.WriteSosPostRequest{ - Title: "Test Title", - Content: "Test Content", - ImageIDs: []int{sosPostImage.ID, sosPostImage2.ID}, - Reward: "Test Reward", - Dates: []sos_post.SosDateView{{"2024-03-30", "2024-03-30"}, - {"2024-04-01", "2024-04-02"}}, - CareType: sos_post.CareTypeFoster, - CarerGender: sos_post.CarerGenderMale, - RewardType: sos_post.RewardTypeFee, - ConditionIDs: conditionIDs, - PetIDs: []int{addPets[0].ID}, - } - - sosPost, err := sosPostService.WriteSosPost(ctx, uid, writeSosPostRequest) + sosPostData := tests.GenerateDummyWriteSosPostRequest(imageIDs, petIDs, 0) + sosPost, err := sosPostService.WriteSosPost(ctx, uid, sosPostData) if err != nil { - t.Errorf(err.Err.Error()) + t.Errorf("got %v want %v", err, nil) } - assertConditionEquals(t, sosPost.Conditions, conditionIDs) - assertPetEquals(t, sosPost.Pets[0], addPets[0]) + // then + assertConditionEquals(t, sosPost.Conditions, sosPostData.ConditionIDs) + assertPetEquals(t, sosPost.Pets[0], *addPets) assertMediaEquals(t, sosPost.Media, (&media.MediaList{sosPostImage, sosPostImage2}).ToMediaViewList()) - assertDatesEquals(t, sosPost.Dates, writeSosPostRequest.Dates) + assertDatesEquals(t, sosPost.Dates, sosPostData.Dates) - if err != nil { - t.Errorf("got %v want %v", err, nil) - } - if sosPost.Title != writeSosPostRequest.Title { - t.Errorf("got %v want %v", sosPost.Title, writeSosPostRequest.Title) + if sosPost.Title != sosPostData.Title { + t.Errorf("got %v want %v", sosPost.Title, sosPostData.Title) } - if sosPost.Content != writeSosPostRequest.Content { - t.Errorf("got %v want %v", sosPost.Content, writeSosPostRequest.Content) + if sosPost.Content != sosPostData.Content { + t.Errorf("got %v want %v", sosPost.Content, sosPostData.Content) } - if sosPost.Reward != writeSosPostRequest.Reward { - t.Errorf("got %v want %v", sosPost.Reward, writeSosPostRequest.Reward) + if sosPost.Reward != sosPostData.Reward { + t.Errorf("got %v want %v", sosPost.Reward, sosPostData.Reward) } - if sosPost.CareType != sos_post.CareTypeFoster { - t.Errorf("got %v want %v", sosPost.CareType, sos_post.CareTypeFoster) + if sosPost.CareType != sosPostData.CareType { + t.Errorf("got %v want %v", sosPost.CareType, sosPostData.CareType) } - if sosPost.CarerGender != sos_post.CarerGenderMale { - t.Errorf("got %v want %v", sosPost.CarerGender, sos_post.CarerGenderMale) + if sosPost.CarerGender != sosPostData.CarerGender { + t.Errorf("got %v want %v", sosPost.CarerGender, sosPostData.CarerGender) } - if sosPost.RewardType != sos_post.RewardTypeFee { - t.Errorf("got %v want %v", sosPost.RewardType, sos_post.RewardTypeFee) + if sosPost.RewardType != sosPostData.RewardType { + t.Errorf("got %v want %v", sosPost.RewardType, sosPostData.RewardType) } - if sosPost.ThumbnailID != sosPostImage.ID { - t.Errorf("got %v want %v", sosPost.ThumbnailID, sosPostImage.ID) + if sosPost.ThumbnailID != sosPostData.ImageIDs[0] { + t.Errorf("got %v want %v", sosPost.ThumbnailID, sosPostData.ImageIDs[0]) } if sosPost.AuthorID != owner.ID { t.Errorf("got %v want %v", sosPost.AuthorID, owner.ID) } }) }) - t.Run("FindSosPosts", func(t *testing.T) { t.Run("전체 돌봄 급구 게시글을 조회한다", func(t *testing.T) { ctx := context.Background() db, tearDown := setUp(ctx, t) defer tearDown(t) + // given mediaService := service.NewMediaService(db, nil) - profileImage, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test.com", - }) - sosPostImage, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test2.com", - }) - sosPostImage2, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test3.com", - }) + profileImage := tests.AddDummyMedia(t, ctx, mediaService) + sosPostImage := tests.AddDummyMedia(t, ctx, mediaService) + sosPostImage2 := tests.AddDummyMedia(t, ctx, mediaService) userService := service.NewUserService(db, mediaService) - owner, err := userService.RegisterUser(ctx, &user.RegisterUserRequest{ - Email: "test@example.com", - Nickname: "nickname", - Fullname: "fullname", - ProfileImageID: &profileImage.ID, - FirebaseProviderType: user.FirebaseProviderTypeKakao, - FirebaseUID: "1234", - }) - if err != nil { - t.Errorf("RegisterUser failed: %v", err) - return + userRequest := tests.GenerateDummyRegisterUserRequest(&profileImage.ID) + owner, _ := userService.RegisterUser(ctx, userRequest) + author := &user.UserWithoutPrivateInfo{ + ID: owner.ID, + ProfileImageURL: owner.ProfileImageURL, + Nickname: owner.Nickname, } - uid := owner.FirebaseUID - - pets := pet.AddPetsToOwnerRequest{ - Pets: []pet.AddPetRequest{ - { - Name: "name", - PetType: "dog", - Sex: "male", - Neutered: true, - Breed: "poodle", - BirthDate: "2020-01-01", - WeightInKg: 10.0, - Remarks: "", - ProfileImageID: nil, - }, - }, - } - - addPets, err := userService.AddPetsToOwner(ctx, uid, pets) - if err != nil { - t.Errorf(err.Err.Error()) - } + addPets := tests.AddDummyPet(t, ctx, userService, uid, &profileImage.ID) sosPostService := service.NewSosPostService(db) - + imageIDs := []int{sosPostImage.ID, sosPostImage2.ID} + petIDs := []int{addPets.ID} conditionIDs := []int{1, 2} var sosPosts []sos_post.WriteSosPostView - for i := 1; i < 4; i++ { - sosPost, err := sosPostService.WriteSosPost(ctx, uid, &sos_post.WriteSosPostRequest{ - Title: fmt.Sprintf("Title%d", i), - Content: fmt.Sprintf("Test Content%d", i), - ImageIDs: []int{sosPostImage.ID, sosPostImage2.ID}, - Reward: fmt.Sprintf("Test Reward%d", i), - Dates: []sos_post.SosDateView{{"2024-03-30", "2024-03-30"}, - {"2024-04-01", "2024-04-02"}}, - CareType: sos_post.CareTypeFoster, - CarerGender: sos_post.CarerGenderMale, - RewardType: sos_post.RewardTypeFee, - ConditionIDs: conditionIDs, - PetIDs: []int{addPets[0].ID}, - }) - - if err != nil { - t.Errorf(err.Err.Error()) - } - + sosPost := tests.WriteDummySosPosts(t, ctx, sosPostService, uid, imageIDs, petIDs, i) sosPosts = append(sosPosts, *sosPost) } - author := &user.UserWithoutPrivateInfo{ - ID: owner.ID, - ProfileImageURL: owner.ProfileImageURL, - Nickname: owner.Nickname, - } - + // when sosPostList, err := sosPostService.FindSosPosts(ctx, 1, 3, "newest", "all") if err != nil { t.Errorf("got %v want %v", err, nil) } + // then for i, sosPost := range sosPostList.Items { + idx := len(sosPostList.Items) - i - 1 assertConditionEquals(t, sosPost.Conditions, conditionIDs) - assertPetEquals(t, sosPost.Pets[0], addPets[0]) + assertPetEquals(t, sosPost.Pets[0], *addPets) assertMediaEquals(t, sosPost.Media, (&media.MediaList{sosPostImage, sosPostImage2}).ToMediaViewList()) assertAuthorEquals(t, sosPost.Author, author) - - idx := len(sosPostList.Items) - i - 1 - assertDatesEquals(t, sosPost.Dates, sosPosts[idx].Dates) - - if sosPost.Title != sosPosts[idx].Title { - t.Errorf("got %v want %v", sosPost.Title, sosPosts[idx].Title) - } - if sosPost.Content != sosPosts[idx].Content { - t.Errorf("got %v want %v", sosPost.Content, sosPosts[idx].Content) - } - if sosPost.Reward != sosPosts[idx].Reward { - t.Errorf("got %v want %v", sosPost.Reward, sosPosts[idx].Reward) - } - if sosPost.CareType != sosPosts[idx].CareType { - t.Errorf("got %v want %v", sosPost.CareType, sosPosts[idx].CareType) - } - if sosPost.CarerGender != sosPosts[idx].CarerGender { - t.Errorf("got %v want %v", sosPost.CarerGender, sosPosts[idx].CarerGender) - } - if sosPost.RewardType != sosPosts[idx].RewardType { - t.Errorf("got %v want %v", sosPost.RewardType, sosPosts[idx].RewardType) - } - if sosPost.ThumbnailID != sosPostImage.ID { - t.Errorf("got %v want %v", sosPost.ThumbnailID, sosPostImage.ID) - } + assertFindSosPostEquals(t, sosPost, sosPosts[idx]) } }) t.Run("전체 돌봄 급구 게시글의 정렬기준을 'deadline'으로 조회한다", func(t *testing.T) { @@ -283,150 +148,48 @@ func TestSosPostService(t *testing.T) { db, tearDown := setUp(ctx, t) defer tearDown(t) + // given mediaService := service.NewMediaService(db, nil) - profileImage, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test.com", - }) - sosPostImage, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test2.com", - }) - sosPostImage2, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test3.com", - }) + profileImage := tests.AddDummyMedia(t, ctx, mediaService) + sosPostImage := tests.AddDummyMedia(t, ctx, mediaService) + sosPostImage2 := tests.AddDummyMedia(t, ctx, mediaService) userService := service.NewUserService(db, mediaService) - owner, err := userService.RegisterUser(ctx, &user.RegisterUserRequest{ - Email: "test@example.com", - Nickname: "nickname", - Fullname: "fullname", - ProfileImageID: &profileImage.ID, - FirebaseProviderType: user.FirebaseProviderTypeKakao, - FirebaseUID: "1234", - }) - if err != nil { - t.Errorf("RegisterUser failed: %v", err) - return + userRequest := tests.GenerateDummyRegisterUserRequest(&profileImage.ID) + owner, _ := userService.RegisterUser(ctx, userRequest) + author := &user.UserWithoutPrivateInfo{ + ID: owner.ID, + ProfileImageURL: owner.ProfileImageURL, + Nickname: owner.Nickname, } - uid := owner.FirebaseUID - - pets := pet.AddPetsToOwnerRequest{ - Pets: []pet.AddPetRequest{ - { - Name: "dog_1", - PetType: "dog", - Sex: "male", - Neutered: true, - Breed: "poodle", - BirthDate: "2020-01-01", - WeightInKg: 10.0, - Remarks: "", - ProfileImageID: nil, - }, - { - Name: "dog_2", - PetType: "dog", - Sex: "male", - Neutered: true, - Breed: "poodle", - BirthDate: "2020-02-01", - WeightInKg: 10.0, - Remarks: "", - ProfileImageID: nil, - }, - { - Name: "cat_1", - PetType: "cat", - Sex: "female", - Neutered: true, - Breed: "munchkin", - BirthDate: "2020-03-01", - WeightInKg: 8.0, - Remarks: "", - ProfileImageID: nil, - }, - }, - } - - addPets, err := userService.AddPetsToOwner(ctx, uid, pets) - if err != nil { - t.Errorf(err.Err.Error()) - } + addPets := tests.AddDummyPets(t, ctx, userService, uid, &profileImage.ID) sosPostService := service.NewSosPostService(db) - + imageIDs := []int{sosPostImage.ID, sosPostImage2.ID} conditionIDs := []int{1, 2} var sosPosts []sos_post.WriteSosPostView - for i := 1; i < 4; i++ { - sosPost, err := sosPostService.WriteSosPost(ctx, uid, &sos_post.WriteSosPostRequest{ - Title: fmt.Sprintf("Title%d", i), - Content: fmt.Sprintf("Test Content%d", i), - ImageIDs: []int{sosPostImage.ID, sosPostImage2.ID}, - Reward: fmt.Sprintf("Test Reward%d", i), - Dates: []sos_post.SosDateView{ - {fmt.Sprintf("2024-04-1%d", i), "2024-04-20"}, - {fmt.Sprintf("2024-05-0%d", i), "2024-05-10"}}, - CareType: sos_post.CareTypeFoster, - CarerGender: sos_post.CarerGenderMale, - RewardType: sos_post.RewardTypeFee, - ConditionIDs: conditionIDs, - PetIDs: []int{addPets[i-1].ID}, - }) - - if err != nil { - t.Errorf(err.Err.Error()) - } - + sosPost := tests.WriteDummySosPosts(t, ctx, sosPostService, uid, imageIDs, []int{addPets[i-1].ID}, i) sosPosts = append(sosPosts, *sosPost) } - author := &user.UserWithoutPrivateInfo{ - ID: owner.ID, - ProfileImageURL: owner.ProfileImageURL, - Nickname: owner.Nickname, - } - + // when sosPostList, err := sosPostService.FindSosPosts(ctx, 1, 3, "newest", "all") if err != nil { t.Errorf("got %v want %v", err, nil) } + // then for i, sosPost := range sosPostList.Items { + idx := len(sosPostList.Items) - i - 1 assertConditionEquals(t, sosPost.Conditions, conditionIDs) assertPetEquals(t, sosPost.Pets[i-1], addPets[i-1]) assertMediaEquals(t, sosPost.Media, (&media.MediaList{sosPostImage, sosPostImage2}).ToMediaViewList()) assertAuthorEquals(t, sosPost.Author, author) - - idx := len(sosPostList.Items) - i - 1 - assertDatesEquals(t, sosPost.Dates, sosPosts[idx].Dates) - - if sosPost.Title != sosPosts[idx].Title { - t.Errorf("got %v want %v", sosPost.Title, sosPosts[idx].Title) - } - if sosPost.Content != sosPosts[idx].Content { - t.Errorf("got %v want %v", sosPost.Content, sosPosts[idx].Content) - } - if sosPost.Reward != sosPosts[idx].Reward { - t.Errorf("got %v want %v", sosPost.Reward, sosPosts[idx].Reward) - } - if sosPost.CareType != sosPosts[idx].CareType { - t.Errorf("got %v want %v", sosPost.CareType, sosPosts[idx].CareType) - } - if sosPost.CarerGender != sosPosts[idx].CarerGender { - t.Errorf("got %v want %v", sosPost.CarerGender, sosPosts[idx].CarerGender) - } - if sosPost.RewardType != sosPosts[idx].RewardType { - t.Errorf("got %v want %v", sosPost.RewardType, sosPosts[idx].RewardType) - } - if sosPost.ThumbnailID != sosPostImage.ID { - t.Errorf("got %v want %v", sosPost.ThumbnailID, sosPostImage.ID) - } + assertFindSosPostEquals(t, sosPost, sosPosts[idx]) } }) t.Run("전체 돌봄 급구 게시글 중 반려동물이 'dog'인 경우만 조회한다", func(t *testing.T) { @@ -434,180 +197,57 @@ func TestSosPostService(t *testing.T) { db, tearDown := setUp(ctx, t) defer tearDown(t) + // given mediaService := service.NewMediaService(db, nil) - profileImage, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test.com", - }) - sosPostImage, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test2.com", - }) - sosPostImage2, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test3.com", - }) + profileImage := tests.AddDummyMedia(t, ctx, mediaService) + sosPostImage := tests.AddDummyMedia(t, ctx, mediaService) + sosPostImage2 := tests.AddDummyMedia(t, ctx, mediaService) userService := service.NewUserService(db, mediaService) - owner, err := userService.RegisterUser(ctx, &user.RegisterUserRequest{ - Email: "test@example.com", - Nickname: "nickname", - Fullname: "fullname", - ProfileImageID: &profileImage.ID, - FirebaseProviderType: user.FirebaseProviderTypeKakao, - FirebaseUID: "1234", - }) - if err != nil { - t.Errorf("RegisterUser failed: %v", err) - return + userRequest := tests.GenerateDummyRegisterUserRequest(&profileImage.ID) + owner, _ := userService.RegisterUser(ctx, userRequest) + author := &user.UserWithoutPrivateInfo{ + ID: owner.ID, + ProfileImageURL: owner.ProfileImageURL, + Nickname: owner.Nickname, } - uid := owner.FirebaseUID - - pets := pet.AddPetsToOwnerRequest{ - Pets: []pet.AddPetRequest{ - { - Name: "dog_1", - PetType: "dog", - Sex: "male", - Neutered: true, - Breed: "poodle", - BirthDate: "2020-01-01", - WeightInKg: 10.0, - Remarks: "", - ProfileImageID: nil, - }, - { - Name: "dog_2", - PetType: "dog", - Sex: "male", - Neutered: true, - Breed: "poodle", - BirthDate: "2020-02-01", - WeightInKg: 10.0, - Remarks: "", - ProfileImageID: nil, - }, - { - Name: "cat_1", - PetType: "cat", - Sex: "female", - Neutered: true, - Breed: "munchkin", - BirthDate: "2020-03-01", - WeightInKg: 8.0, - Remarks: "", - ProfileImageID: nil, - }, - }, - } - - addPets, err := userService.AddPetsToOwner(ctx, uid, pets) - if err != nil { - t.Errorf(err.Err.Error()) - } + addPets := tests.AddDummyPets(t, ctx, userService, uid, &profileImage.ID) sosPostService := service.NewSosPostService(db) - + imageIDs := []int{sosPostImage.ID, sosPostImage2.ID} conditionIDs := []int{1, 2} var sosPosts []sos_post.WriteSosPostView - // 강아지인 경우 for i := 1; i < 3; i++ { - sosPost, err := sosPostService.WriteSosPost(ctx, uid, &sos_post.WriteSosPostRequest{ - Title: fmt.Sprintf("Title%d", i), - Content: fmt.Sprintf("Test Content%d", i), - ImageIDs: []int{sosPostImage.ID, sosPostImage2.ID}, - Reward: fmt.Sprintf("Test Reward%d", i), - Dates: []sos_post.SosDateView{{"2024-03-30", "2024-03-30"}, - {"2024-04-01", "2024-04-02"}}, - CareType: sos_post.CareTypeFoster, - CarerGender: sos_post.CarerGenderMale, - RewardType: sos_post.RewardTypeFee, - ConditionIDs: conditionIDs, - PetIDs: []int{addPets[i-1].ID}, - }) - - if err != nil { - t.Errorf(err.Err.Error()) - } - + sosPost := tests.WriteDummySosPosts(t, ctx, sosPostService, uid, imageIDs, []int{addPets[i-1].ID}, i) sosPosts = append(sosPosts, *sosPost) } // 고양이인 경우 - _, err = sosPostService.WriteSosPost(ctx, uid, &sos_post.WriteSosPostRequest{ - Title: "Title3", - Content: "Test Content3", - ImageIDs: []int{sosPostImage.ID, sosPostImage2.ID}, - Reward: "Test Reward3", - Dates: []sos_post.SosDateView{{"2024-03-30", "2024-03-30"}, - {"2024-04-01", "2024-04-02"}}, - CareType: sos_post.CareTypeFoster, - CarerGender: sos_post.CarerGenderMale, - RewardType: sos_post.RewardTypeFee, - ConditionIDs: conditionIDs, - PetIDs: []int{addPets[2].ID}, - }) + sosPosts = append(sosPosts, + *tests.WriteDummySosPosts(t, ctx, sosPostService, uid, imageIDs, []int{addPets[2].ID}, 3)) // 강아지, 고양이인 경우 - _, err = sosPostService.WriteSosPost(ctx, uid, &sos_post.WriteSosPostRequest{ - Title: "Title4", - Content: "Test Content4", - ImageIDs: []int{sosPostImage.ID, sosPostImage2.ID}, - Reward: "Test Reward4", - Dates: []sos_post.SosDateView{{"2024-03-30", "2024-03-30"}, - {"2024-04-01", "2024-04-02"}}, - CareType: sos_post.CareTypeFoster, - CarerGender: sos_post.CarerGenderMale, - RewardType: sos_post.RewardTypeFee, - ConditionIDs: conditionIDs, - PetIDs: []int{addPets[0].ID, addPets[2].ID}, - }) - - author := &user.UserWithoutPrivateInfo{ - ID: owner.ID, - ProfileImageURL: owner.ProfileImageURL, - Nickname: owner.Nickname, - } + sosPosts = append(sosPosts, + *tests.WriteDummySosPosts(t, ctx, sosPostService, uid, imageIDs, []int{addPets[1].ID, addPets[2].ID}, 4)) + // when sosPostList, err := sosPostService.FindSosPosts(ctx, 1, 3, "newest", "all") if err != nil { t.Errorf("got %v want %v", err, nil) } + // then for i, sosPost := range sosPostList.Items { + idx := len(sosPostList.Items) - i - 1 assertConditionEquals(t, sosPost.Conditions, conditionIDs) assertPetEquals(t, sosPost.Pets[i-1], addPets[i-1]) assertMediaEquals(t, sosPost.Media, (&media.MediaList{sosPostImage, sosPostImage2}).ToMediaViewList()) assertAuthorEquals(t, sosPost.Author, author) - - idx := len(sosPostList.Items) - i - 1 - assertDatesEquals(t, sosPost.Dates, sosPosts[idx].Dates) - - if sosPost.Title != sosPosts[idx].Title { - t.Errorf("got %v want %v", sosPost.Title, sosPosts[idx].Title) - } - if sosPost.Content != sosPosts[idx].Content { - t.Errorf("got %v want %v", sosPost.Content, sosPosts[idx].Content) - } - if sosPost.Reward != sosPosts[idx].Reward { - t.Errorf("got %v want %v", sosPost.Reward, sosPosts[idx].Reward) - } - if sosPost.CareType != sosPosts[idx].CareType { - t.Errorf("got %v want %v", sosPost.CareType, sosPosts[idx].CareType) - } - if sosPost.CarerGender != sosPosts[idx].CarerGender { - t.Errorf("got %v want %v", sosPost.CarerGender, sosPosts[idx].CarerGender) - } - if sosPost.RewardType != sosPosts[idx].RewardType { - t.Errorf("got %v want %v", sosPost.RewardType, sosPosts[idx].RewardType) - } - if sosPost.ThumbnailID != sosPostImage.ID { - t.Errorf("got %v want %v", sosPost.ThumbnailID, sosPostImage.ID) - } + assertFindSosPostEquals(t, sosPost, sosPosts[idx]) } }) t.Run("작성자 ID로 돌봄 급구 게시글을 조회합니다.", func(t *testing.T) { @@ -616,127 +256,49 @@ func TestSosPostService(t *testing.T) { defer tearDown(t) mediaService := service.NewMediaService(db, nil) - profileImage, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test.com", - }) - sosPostImage, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test2.com", - }) - sosPostImage2, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test3.com", - }) + profileImage := tests.AddDummyMedia(t, ctx, mediaService) + sosPostImage := tests.AddDummyMedia(t, ctx, mediaService) + sosPostImage2 := tests.AddDummyMedia(t, ctx, mediaService) userService := service.NewUserService(db, mediaService) - - owner, err := userService.RegisterUser(ctx, &user.RegisterUserRequest{ - Email: "test@example.com", - Nickname: "nickname", - Fullname: "fullname", - ProfileImageID: &profileImage.ID, - FirebaseProviderType: user.FirebaseProviderTypeKakao, - FirebaseUID: "1234", - }) - if err != nil { - t.Errorf("RegisterUser failed: %v", err) - return + userRequest := tests.GenerateDummyRegisterUserRequest(&profileImage.ID) + owner, _ := userService.RegisterUser(ctx, userRequest) + author := &user.UserWithoutPrivateInfo{ + ID: owner.ID, + ProfileImageURL: owner.ProfileImageURL, + Nickname: owner.Nickname, } - uid := owner.FirebaseUID - pets := pet.AddPetsToOwnerRequest{ - Pets: []pet.AddPetRequest{ - { - Name: "name", - PetType: "dog", - Sex: "male", - Neutered: true, - Breed: "poodle", - BirthDate: "2020-01-01", - WeightInKg: 10.0, - Remarks: "", - ProfileImageID: nil, - }, - }, - } - - addPets, err := userService.AddPetsToOwner(ctx, uid, pets) - if err != nil { - t.Errorf(err.Err.Error()) - } + addPet := tests.AddDummyPet(t, ctx, userService, uid, &profileImage.ID) sosPostService := service.NewSosPostService(db) - + imageIDs := []int{sosPostImage.ID, sosPostImage2.ID} conditionIDs := []int{1, 2} sosPosts := make([]sos_post.WriteSosPostView, 0) for i := 1; i < 4; i++ { - sosPost, err := sosPostService.WriteSosPost(ctx, uid, &sos_post.WriteSosPostRequest{ - Title: fmt.Sprintf("Title%d", i), - Content: fmt.Sprintf("Test Content%d", i), - ImageIDs: []int{sosPostImage.ID, sosPostImage2.ID}, - Reward: fmt.Sprintf("Test Reward%d", i), - CareType: sos_post.CareTypeFoster, - CarerGender: sos_post.CarerGenderMale, - RewardType: sos_post.RewardTypeFee, - ConditionIDs: conditionIDs, - PetIDs: []int{addPets[0].ID}, - }) - - if err != nil { - t.Errorf(err.Err.Error()) - } - + sosPost := tests.WriteDummySosPosts(t, ctx, sosPostService, uid, imageIDs, []int{addPet.ID}, i) sosPosts = append(sosPosts, *sosPost) } + // when sosPostListByAuthorID, err := sosPostService.FindSosPostsByAuthorID(ctx, owner.ID, 1, 3, "newest", "all") if err != nil { t.Errorf("got %v want %v", err, nil) } - author := &user.UserWithoutPrivateInfo{ - ID: owner.ID, - ProfileImageURL: owner.ProfileImageURL, - Nickname: owner.Nickname, - } - + // then for i, sosPost := range sosPostListByAuthorID.Items { + idx := len(sosPostListByAuthorID.Items) - i - 1 assertConditionEquals(t, sosPost.Conditions, conditionIDs) - assertPetEquals(t, sosPost.Pets[0], addPets[0]) + assertPetEquals(t, sosPost.Pets[0], *addPet) assertMediaEquals(t, sosPost.Media, (&media.MediaList{sosPostImage, sosPostImage2}).ToMediaViewList()) assertAuthorEquals(t, sosPost.Author, author) - - idx := len(sosPostListByAuthorID.Items) - i - 1 - assertDatesEquals(t, sosPost.Dates, sosPosts[idx].Dates) - - if sosPost.Title != sosPosts[idx].Title { - t.Errorf("got %v want %v", sosPost.Title, sosPosts[idx].Title) - } - if sosPost.Content != sosPosts[idx].Content { - t.Errorf("got %v want %v", sosPost.Content, sosPosts[idx].Content) - } - if sosPost.Reward != sosPosts[idx].Reward { - t.Errorf("got %v want %v", sosPost.Reward, sosPosts[idx].Reward) - } - if sosPost.CareType != sosPosts[idx].CareType { - t.Errorf("got %v want %v", sosPost.CareType, sosPosts[idx].CareType) - } - if sosPost.CarerGender != sosPosts[idx].CarerGender { - t.Errorf("got %v want %v", sosPost.CarerGender, sosPosts[idx].CarerGender) - } - if sosPost.RewardType != sosPosts[idx].RewardType { - t.Errorf("got %v want %v", sosPost.RewardType, sosPosts[idx].RewardType) - } - if sosPost.ThumbnailID != sosPostImage.ID { - t.Errorf("got %v want %v", sosPost.ThumbnailID, sosPostImage.ID) - } + assertFindSosPostEquals(t, sosPost, sosPosts[idx]) } }) }) - t.Run("FindSosPostByID", func(t *testing.T) { t.Run("게시글 ID로 돌봄 급구 게시글을 조회합니다.", func(t *testing.T) { ctx := context.Background() @@ -744,120 +306,44 @@ func TestSosPostService(t *testing.T) { defer tearDown(t) mediaService := service.NewMediaService(db, nil) - profileImage, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test.com", - }) - sosPostImage, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test2.com", - }) - sosPostImage2, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test3.com", - }) + profileImage := tests.AddDummyMedia(t, ctx, mediaService) + sosPostImage := tests.AddDummyMedia(t, ctx, mediaService) + sosPostImage2 := tests.AddDummyMedia(t, ctx, mediaService) userService := service.NewUserService(db, mediaService) - - owner, err := userService.RegisterUser(ctx, &user.RegisterUserRequest{ - Email: "test@example.com", - Nickname: "nickname", - Fullname: "fullname", - ProfileImageID: &profileImage.ID, - FirebaseProviderType: user.FirebaseProviderTypeKakao, - FirebaseUID: "1234", - }) - if err != nil { - t.Errorf("RegisterUser failed: %v", err) - return + userRequest := tests.GenerateDummyRegisterUserRequest(&profileImage.ID) + owner, _ := userService.RegisterUser(ctx, userRequest) + author := &user.UserWithoutPrivateInfo{ + ID: owner.ID, + ProfileImageURL: owner.ProfileImageURL, + Nickname: owner.Nickname, } - uid := owner.FirebaseUID - - pets := pet.AddPetsToOwnerRequest{ - Pets: []pet.AddPetRequest{ - { - Name: "name", - PetType: "dog", - Sex: "male", - Neutered: true, - Breed: "poodle", - BirthDate: "2020-01-01", - WeightInKg: 10.0, - Remarks: "", - ProfileImageID: nil, - }, - }, - } - - addPets, err := userService.AddPetsToOwner(ctx, uid, pets) - if err != nil { - t.Errorf(err.Err.Error()) - } + addPet := tests.AddDummyPet(t, ctx, userService, uid, &profileImage.ID) sosPostService := service.NewSosPostService(db) - + imageIDs := []int{sosPostImage.ID, sosPostImage2.ID} conditionIDs := []int{1, 2} sosPosts := make([]sos_post.WriteSosPostView, 0) for i := 1; i < 4; i++ { - sosPost, err := sosPostService.WriteSosPost(ctx, uid, &sos_post.WriteSosPostRequest{ - Title: fmt.Sprintf("Title%d", i), - Content: fmt.Sprintf("Test Content%d", i), - ImageIDs: []int{sosPostImage.ID, sosPostImage2.ID}, - Reward: fmt.Sprintf("Test Reward%d", i), - Dates: []sos_post.SosDateView{{"2024-03-30", "2024-03-30"}, - {"2024-04-01", "2024-04-02"}}, - CareType: sos_post.CareTypeFoster, - CarerGender: sos_post.CarerGenderMale, - RewardType: sos_post.RewardTypeFee, - ConditionIDs: conditionIDs, - PetIDs: []int{addPets[0].ID}, - }) - - if err != nil { - t.Errorf(err.Err.Error()) - } + sosPost := tests.WriteDummySosPosts(t, ctx, sosPostService, uid, imageIDs, []int{addPet.ID}, i) sosPosts = append(sosPosts, *sosPost) } - author := &user.UserWithoutPrivateInfo{ - ID: owner.ID, - ProfileImageURL: owner.ProfileImageURL, - Nickname: owner.Nickname, - } - + // when findSosPostByID, err := sosPostService.FindSosPostByID(ctx, sosPosts[0].ID) + if err != nil { + t.Errorf("got %v want %v", err, nil) + } + // then assertConditionEquals(t, sosPosts[0].Conditions, conditionIDs) - assertPetEquals(t, sosPosts[0].Pets[0], addPets[0]) + assertPetEquals(t, sosPosts[0].Pets[0], *addPet) assertMediaEquals(t, findSosPostByID.Media, (&media.MediaList{sosPostImage, sosPostImage2}).ToMediaViewList()) assertAuthorEquals(t, findSosPostByID.Author, author) assertDatesEquals(t, findSosPostByID.Dates, sosPosts[0].Dates) - if err != nil { - t.Errorf("got %v want %v", err, nil) - } - if findSosPostByID.Title != sosPosts[0].Title { - t.Errorf("got %v want %v", findSosPostByID.Title, sosPosts[0].Title) - } - if findSosPostByID.Content != sosPosts[0].Content { - t.Errorf("got %v want %v", findSosPostByID.Content, sosPosts[0].Content) - } - if findSosPostByID.Reward != sosPosts[0].Reward { - t.Errorf("got %v want %v", findSosPostByID.Reward, sosPosts[0].Reward) - } - if findSosPostByID.CareType != sosPosts[0].CareType { - t.Errorf("got %v want %v", findSosPostByID.CareType, sosPosts[0].CareType) - } - if findSosPostByID.CarerGender != sosPosts[0].CarerGender { - t.Errorf("got %v want %v", findSosPostByID.CarerGender, sosPosts[0].CarerGender) - } - if findSosPostByID.RewardType != sosPosts[0].RewardType { - t.Errorf("got %v want %v", findSosPostByID.RewardType, sosPosts[0].RewardType) - } - if findSosPostByID.ThumbnailID != sosPostImage.ID { - t.Errorf("got %v want %v", findSosPostByID.ThumbnailID, sosPostImage.ID) - } + assertFindSosPostEquals(t, *findSosPostByID, sosPosts[0]) }) }) @@ -867,103 +353,49 @@ func TestSosPostService(t *testing.T) { db, tearDown := setUp(ctx, t) defer tearDown(t) + // given mediaService := service.NewMediaService(db, nil) - profileImage, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test.com", - }) - sosPostImage, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test2.com", - }) - sosPostImage2, _ := mediaService.CreateMedia(ctx, &media.Media{ - MediaType: media.IMAGE_MEDIA_TYPE, - URL: "https://test3.com", - }) + profileImage := tests.AddDummyMedia(t, ctx, mediaService) + sosPostImage := tests.AddDummyMedia(t, ctx, mediaService) + sosPostImage2 := tests.AddDummyMedia(t, ctx, mediaService) userService := service.NewUserService(db, mediaService) - - owner, err := userService.RegisterUser(ctx, &user.RegisterUserRequest{ - Email: "test@example.com", - Nickname: "nickname", - Fullname: "fullname", - ProfileImageID: &profileImage.ID, - FirebaseProviderType: user.FirebaseProviderTypeKakao, - FirebaseUID: "1234", - }) - if err != nil { - t.Errorf("RegisterUser failed: %v", err) - return - } - + userRequest := tests.GenerateDummyRegisterUserRequest(&profileImage.ID) + owner, _ := userService.RegisterUser(ctx, userRequest) uid := owner.FirebaseUID - - pets := pet.AddPetsToOwnerRequest{ - Pets: []pet.AddPetRequest{ - { - Name: "name", - PetType: "dog", - Sex: "male", - Neutered: true, - Breed: "poodle", - BirthDate: "2020-01-01", - WeightInKg: 10.0, - Remarks: "", - ProfileImageID: nil, - }, - }, - } - - addPets, err := userService.AddPetsToOwner(ctx, uid, pets) - if err != nil { - t.Errorf(err.Err.Error()) - } + addPet := tests.AddDummyPet(t, ctx, userService, uid, &profileImage.ID) sosPostService := service.NewSosPostService(db) - - conditionIDs := []int{1, 2} - - sosPost, err := sosPostService.WriteSosPost(ctx, uid, &sos_post.WriteSosPostRequest{ - Title: "Title1", - Content: "Test Content1", - ImageIDs: []int{sosPostImage.ID, sosPostImage2.ID}, - Reward: "Test Reward1", - CareType: sos_post.CareTypeFoster, - CarerGender: sos_post.CarerGenderMale, - RewardType: sos_post.RewardTypeFee, - ConditionIDs: conditionIDs, - PetIDs: []int{addPets[0].ID}, - }) - - if err != nil { - t.Errorf(err.Err.Error()) - } + sosPost := tests.WriteDummySosPosts(t, ctx, sosPostService, uid, []int{sosPostImage.ID}, []int{addPet.ID}, 1) updateSosPostData := &sos_post.UpdateSosPostRequest{ ID: sosPost.ID, Title: "Title2", - Content: "Test Content2", + Content: "Content2", ImageIDs: []int{sosPostImage.ID, sosPostImage2.ID}, - Reward: "Test Reward2", - Dates: []sos_post.SosDateView{{"2024-03-30", "2024-03-30"}, - {"2024-04-01", "2024-04-02"}}, + Reward: "Reward2", + Dates: []sos_post.SosDateView{ + {"2024-04-10", "2024-04-20"}, + {"2024-05-10", "2024-05-20"}, + }, CareType: sos_post.CareTypeFoster, CarerGender: sos_post.CarerGenderMale, RewardType: sos_post.RewardTypeFee, - ConditionIDs: []int{1, 2, 3}, - PetIDs: []int{addPets[0].ID}, + ConditionIDs: []int{1, 2}, + PetIDs: []int{addPet.ID}, } + // when updateSosPost, err := sosPostService.UpdateSosPost(ctx, updateSosPostData) + if err != nil { + t.Errorf("got %v want %v", err, nil) + } - assertConditionEquals(t, sosPost.Conditions, conditionIDs) - assertPetEquals(t, sosPost.Pets[0], addPets[0]) + assertConditionEquals(t, sosPost.Conditions, updateSosPostData.ConditionIDs) + assertPetEquals(t, sosPost.Pets[0], *addPet) assertMediaEquals(t, updateSosPost.Media, (&media.MediaList{sosPostImage, sosPostImage2}).ToMediaViewList()) assertDatesEquals(t, updateSosPost.Dates, updateSosPostData.Dates) - if err != nil { - t.Errorf("got %v want %v", err, nil) - } if updateSosPost.Title != updateSosPostData.Title { t.Errorf("got %v want %v", updateSosPost.Title, updateSosPostData.Title) } @@ -991,6 +423,31 @@ func TestSosPostService(t *testing.T) { }) }) } + +func assertFindSosPostEquals(t *testing.T, got sos_post.FindSosPostView, want sos_post.WriteSosPostView) { + if got.Title != want.Title { + t.Errorf("got %v want %v", got.Title, want.Title) + } + if got.Content != want.Content { + t.Errorf("got %v want %v", got.Content, want.Content) + } + if got.Reward != want.Reward { + t.Errorf("got %v want %v", got.Reward, want.Reward) + } + if got.CareType != want.CareType { + t.Errorf("got %v want %v", got.CareType, want.CareType) + } + if got.CarerGender != want.CarerGender { + t.Errorf("got %v want %v", got.CarerGender, want.CarerGender) + } + if got.RewardType != want.RewardType { + t.Errorf("got %v want %v", got.RewardType, want.RewardType) + } + if got.ThumbnailID != want.ThumbnailID { + t.Errorf("got %v want %v", got.ThumbnailID, want.ThumbnailID) + } +} + func assertConditionEquals(t *testing.T, got []sos_post.ConditionView, want []int) { for i := range want { if i+1 != got[i].ID { @@ -1026,12 +483,7 @@ func assertAuthorEquals(t *testing.T, got *user.UserWithoutPrivateInfo, want *us } func assertDatesEquals(t *testing.T, got []sos_post.SosDateView, want []sos_post.SosDateView) { - for i, date := range want { - if got[i].DateStartAt != date.DateStartAt { - t.Errorf("got %v want %v", got[i].DateStartAt, date.DateStartAt) - } - if got[i].DateEndAt != date.DateEndAt { - t.Errorf("got %v want %v", got[i].DateEndAt, date.DateEndAt) - } + if !reflect.DeepEqual(got, want) { + t.Errorf("got %v want %v", got, want) } } diff --git a/internal/tests/factories.go b/internal/tests/factories.go index 298444e2..e4d92966 100644 --- a/internal/tests/factories.go +++ b/internal/tests/factories.go @@ -1,7 +1,9 @@ package tests import ( + "fmt" "github.com/pet-sitter/pets-next-door-api/internal/domain/pet" + "github.com/pet-sitter/pets-next-door-api/internal/domain/sos_post" "github.com/pet-sitter/pets-next-door-api/internal/domain/user" ) @@ -28,3 +30,59 @@ func GenerateDummyAddPetRequest(profileImageID *int) *pet.AddPetRequest { ProfileImageID: profileImageID, } } + +func GenerateDummyAddPetsRequest(profileImageID *int) []pet.AddPetRequest { + return []pet.AddPetRequest{ + { + Name: "dog_1", + PetType: "dog", + Sex: "male", + Neutered: true, + Breed: "poodle", + BirthDate: "2020-01-01", + WeightInKg: 10.0, + Remarks: "remarks", + ProfileImageID: profileImageID, + }, + { + Name: "dog_2", + PetType: "dog", + Sex: "male", + Neutered: true, + Breed: "poodle", + BirthDate: "2020-02-01", + WeightInKg: 10.0, + Remarks: "remarks", + ProfileImageID: profileImageID, + }, + { + Name: "cat_1", + PetType: "cat", + Sex: "female", + Neutered: true, + Breed: "munchkin", + BirthDate: "2020-03-01", + WeightInKg: 8.0, + Remarks: "remarks", + ProfileImageID: profileImageID, + }, + } +} + +func GenerateDummyWriteSosPostRequest(imageID []int, petIDs []int, sosPostCnt int) *sos_post.WriteSosPostRequest { + return &sos_post.WriteSosPostRequest{ + Title: fmt.Sprintf("Title%d", sosPostCnt), + Content: fmt.Sprintf("Content%d", sosPostCnt), + ImageIDs: imageID, + Reward: "Reward", + Dates: []sos_post.SosDateView{ + {fmt.Sprintf("2024-04-1%d", sosPostCnt), fmt.Sprintf("2024-04-2%d", sosPostCnt)}, + {fmt.Sprintf("2024-05-1%d", sosPostCnt), fmt.Sprintf("2024-05-2%d", sosPostCnt)}, + }, + CareType: sos_post.CareTypeFoster, + CarerGender: sos_post.CarerGenderMale, + RewardType: sos_post.RewardTypeFee, + ConditionIDs: []int{1, 2}, + PetIDs: petIDs, + } +} diff --git a/internal/tests/service.go b/internal/tests/service.go index 53c77115..d2fc9ced 100644 --- a/internal/tests/service.go +++ b/internal/tests/service.go @@ -4,6 +4,7 @@ import ( "context" "github.com/pet-sitter/pets-next-door-api/internal/domain/media" "github.com/pet-sitter/pets-next-door-api/internal/domain/pet" + "github.com/pet-sitter/pets-next-door-api/internal/domain/sos_post" "github.com/pet-sitter/pets-next-door-api/internal/domain/user" "github.com/pet-sitter/pets-next-door-api/internal/service" "testing" @@ -37,7 +38,7 @@ func RegisterDummyUser( return registeredUser } -func AddDummyPets( +func AddDummyPet( t *testing.T, ctx context.Context, userService *service.UserService, @@ -53,3 +54,37 @@ func AddDummyPets( return &pets[0] } + +func AddDummyPets( + t *testing.T, + ctx context.Context, + userService *service.UserService, + ownerUID string, + profileImageID *int, +) []pet.PetView { + pets, err := userService.AddPetsToOwner(ctx, ownerUID, pet.AddPetsToOwnerRequest{ + Pets: GenerateDummyAddPetsRequest(profileImageID), + }) + if err != nil { + t.Errorf("got %v want %v", err, nil) + } + + return pets +} + +func WriteDummySosPosts( + t *testing.T, + ctx context.Context, + sosPostService *service.SosPostService, + uid string, + imageID []int, + petIDs []int, + sosPostCnt int, +) *sos_post.WriteSosPostView { + sosPostRequest := GenerateDummyWriteSosPostRequest(imageID, petIDs, sosPostCnt) + sosPost, err := sosPostService.WriteSosPost(ctx, uid, sosPostRequest) + if err != nil { + t.Errorf("got %v want %v", err, nil) + } + return sosPost +}