Skip to content

Commit

Permalink
add requesting user to returned values of article methods
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthieu Jacquot committed Aug 5, 2018
1 parent 888693d commit 1afefcc
Show file tree
Hide file tree
Showing 19 changed files with 216 additions and 144 deletions.
5 changes: 2 additions & 3 deletions domain/article.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ type Article struct {
CreatedAt time.Time
UpdatedAt time.Time
FavoritedBy []User
//FavoritesCount int
Author User
Comments []Comment
Author User
Comments []Comment
}

type ArticleFilter func(Article) bool
Expand Down
1 change: 1 addition & 0 deletions domain/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ func (user User) Follows(userName string) bool {
if user.FollowIDs == nil {
return false
}

sort.Strings(user.FollowIDs)
i := sort.SearchStrings(user.FollowIDs, userName)
return i < len(user.FollowIDs) && user.FollowIDs[i] == userName
Expand Down
12 changes: 6 additions & 6 deletions implem/gin.server/article.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ func (rH RouterHandler) articlePost(c *gin.Context) {
return
}

article, err := rH.ucHandler.ArticlePost(rH.getUserName(c), articleFromReq(req))
user, article, err := rH.ucHandler.ArticlePost(rH.getUserName(c), articleFromReq(req))
if err != nil {
log(err)
c.Status(http.StatusUnprocessableEntity)
return
}

c.JSON(http.StatusCreated, gin.H{"article": formatter.NewArticleFromDomain(*article, rH.getUserName(c))})
c.JSON(http.StatusCreated, gin.H{"article": formatter.NewArticleFromDomain(*article, user)})
}

func (rH RouterHandler) articlePut(c *gin.Context) {
Expand All @@ -55,26 +55,26 @@ func (rH RouterHandler) articlePut(c *gin.Context) {
c.Status(http.StatusBadRequest)
return
}
article, err := rH.ucHandler.ArticlePut(rH.getUserName(c), c.Param("slug"), articleFromReq(req))
user, article, err := rH.ucHandler.ArticlePut(rH.getUserName(c), c.Param("slug"), articleFromReq(req))
if err != nil {
log(err)
c.Status(http.StatusUnprocessableEntity)
return
}

c.JSON(http.StatusOK, gin.H{"article": formatter.NewArticleFromDomain(*article, rH.getUserName(c))})
c.JSON(http.StatusOK, gin.H{"article": formatter.NewArticleFromDomain(*article, user)})
}

func (rH RouterHandler) articleGet(c *gin.Context) {
log := rH.log(rH.MethodAndPath(c))

article, err := rH.ucHandler.ArticleGet(c.Param("slug"))
user, article, err := rH.ucHandler.ArticleGet(rH.getUserName(c), c.Param("slug")) // todo add requesting username here
if err != nil {
log(err)
c.Status(http.StatusUnprocessableEntity)
return
}
c.JSON(http.StatusOK, gin.H{"article": formatter.NewArticleFromDomain(*article, rH.getUserName(c))})
c.JSON(http.StatusOK, gin.H{"article": formatter.NewArticleFromDomain(*article, user)})
}

func (rH RouterHandler) articleDelete(c *gin.Context) {
Expand Down
4 changes: 2 additions & 2 deletions implem/gin.server/articleFavorite.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ func (rH RouterHandler) updateFavorite(c *gin.Context) {
return
}

article, err := rH.ucHandler.FavoritesUpdate(rH.getUserName(c), c.Param("slug"), favorite)
user, article, err := rH.ucHandler.FavoritesUpdate(rH.getUserName(c), c.Param("slug"), favorite)
if err != nil {
log(err)
c.Status(http.StatusUnprocessableEntity)
return
}

c.JSON(http.StatusOK, gin.H{"article": formatter.NewArticleFromDomain(*article, rH.getUserName(c))})
c.JSON(http.StatusOK, gin.H{"article": formatter.NewArticleFromDomain(*article, user)})
}
10 changes: 6 additions & 4 deletions implem/gin.server/articleFavorite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ func TestArticleFavoritePost(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

testUser := testData.User("jane")
expectedComment := testData.Article("")
ucHandler := uc.NewMockHandler(mockCtrl)
ucHandler.EXPECT().
FavoritesUpdate(
testData.User("jane").Name,
testUser.Name,
testData.Article("jane").Slug,
true,
).
Return(&expectedComment, nil).
Return(&testUser, &expectedComment, nil).
Times(1)

jwtHandler := jwt.NewTokenHandler("mySalt")
Expand Down Expand Up @@ -65,14 +66,15 @@ func TestArticleFavoriteDelete(t *testing.T) {
defer mockCtrl.Finish()

expectedComment := testData.Article("")
testUser := testData.User("jane")
ucHandler := uc.NewMockHandler(mockCtrl)
ucHandler.EXPECT().
FavoritesUpdate(
testData.User("jane").Name,
testUser.Name,
testData.Article("jane").Slug,
false,
).
Return(&expectedComment, nil).
Return(&testUser, &expectedComment, nil).
Times(1)

jwtHandler := jwt.NewTokenHandler("mySalt")
Expand Down
16 changes: 10 additions & 6 deletions implem/gin.server/article_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ func TestRouterHandler_articlePost(t *testing.T) {
defer mockCtrl.Finish()

expectedArticle := testData.Article("jane")
testUser := testData.User("jane")

ucHandler := uc.NewMockHandler(mockCtrl)
ucHandler.EXPECT().
ArticlePost(testData.User("jane").Name, gomock.Any()).
Return(&expectedArticle, nil).
ArticlePost(testUser.Name, gomock.Any()).
Return(&testUser, &expectedArticle, nil).
Times(1)

jwtHandler := jwt.NewTokenHandler("mySalt")
Expand Down Expand Up @@ -80,13 +82,14 @@ func TestRouterHandler_articlePut(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

testUser := testData.User("jane")
expectedArticle := testData.Article("jane")
jwtHandler := jwt.NewTokenHandler("mySalt")

ucHandler := uc.NewMockHandler(mockCtrl)
ucHandler.EXPECT().
ArticlePut(testData.User("jane").Name, expectedArticle.Slug, gomock.Any()).
Return(&expectedArticle, nil).
ArticlePut(testUser.Name, expectedArticle.Slug, gomock.Any()).
Return(&testUser, &expectedArticle, nil).
Times(1)

gE := gin.Default()
Expand Down Expand Up @@ -143,10 +146,11 @@ func TestRouterHandler_articleGet(t *testing.T) {
defer mockCtrl.Finish()

expectedArticle := testData.Article("jane")
//testUser := testData.User("jane")
ucHandler := uc.NewMockHandler(mockCtrl)
ucHandler.EXPECT().
ArticleGet(expectedArticle.Slug).
Return(&expectedArticle, nil).
ArticleGet("", expectedArticle.Slug).
Return(nil, &expectedArticle, nil).
Times(1)

gE := gin.Default()
Expand Down
9 changes: 5 additions & 4 deletions implem/gin.server/articles.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ func (rH RouterHandler) articlesFilteredGet(c *gin.Context) {
offset = defaultOffset
}

articles, count, err := rH.ucHandler.GetArticles(
user, articles, count, err := rH.ucHandler.GetArticles(
rH.getUserName(c),
limit,
offset,
uc.NewFilters(
Expand All @@ -43,7 +44,7 @@ func (rH RouterHandler) articlesFilteredGet(c *gin.Context) {
return
}

c.JSON(http.StatusOK, gin.H{"articles": formatter.NewArticlesFromDomain(rH.getUserName(c), articles...), "articlesCount": count})
c.JSON(http.StatusOK, gin.H{"articles": formatter.NewArticlesFromDomain(user, articles...), "articlesCount": count})
}

func (rH RouterHandler) articlesFeedGet(c *gin.Context) {
Expand All @@ -59,12 +60,12 @@ func (rH RouterHandler) articlesFeedGet(c *gin.Context) {
offset = defaultOffset
}

articles, count, err := rH.ucHandler.ArticlesFeed(rH.getUserName(c), limit, offset)
user, articles, count, err := rH.ucHandler.ArticlesFeed(rH.getUserName(c), limit, offset)
if err != nil {
log(err)
c.Status(http.StatusUnprocessableEntity)
return
}

c.JSON(http.StatusOK, gin.H{"articles": formatter.NewArticlesFromDomain(rH.getUserName(c), articles...), "articlesCount": count})
c.JSON(http.StatusOK, gin.H{"articles": formatter.NewArticlesFromDomain(user, articles...), "articlesCount": count})
}
9 changes: 5 additions & 4 deletions implem/gin.server/articles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ var articlesFilteredPath = "/api/articles"
var articlesFeedPath = "/api/articles/feed"

func TestArticlesFiltered(t *testing.T) {
// todo : add test with auth
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

Expand All @@ -32,8 +33,8 @@ func TestArticlesFiltered(t *testing.T) {

ucHandler := mock.NewMockHandler(mockCtrl)
ucHandler.EXPECT().
GetArticles(limit, offset, gomock.Any()).
Return(domain.ArticleCollection{testData.Article("jane")}, 10, nil).
GetArticles("", limit, offset, gomock.Any()).
Return(nil, domain.ArticleCollection{testData.Article("jane")}, 10, nil).
Times(1)

gE := gin.Default()
Expand Down Expand Up @@ -69,7 +70,7 @@ func TestArticlesFeed(t *testing.T) {
ucHandler := mock.NewMockHandler(mockCtrl)
ucHandler.EXPECT().
ArticlesFeed(jane.Name, limit, offset).
Return(domain.ArticleCollection{testData.Article("jane")}, 10, nil).
Return(nil, domain.ArticleCollection{testData.Article("jane")}, 10, nil).
Times(1)

jwtHandler := jwt.NewTokenHandler("mySalt")
Expand Down Expand Up @@ -106,7 +107,7 @@ func TestArticlesFeed(t *testing.T) {
ucHandler := mock.NewMockHandler(mockCtrl)
ucHandler.EXPECT().
ArticlesFeed(jane.Name, limit, offset).
Return(nil, 0, nil).
Return(&jane, nil, 0, nil).
Times(1)

jwtHandler := jwt.NewTokenHandler("mySalt")
Expand Down
35 changes: 25 additions & 10 deletions implem/json.formatter/article.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package formatter

import "github.com/err0r500/go-realworld-clean/domain"
import (
"time"

const dateFormat = "2006-01-02T15:04:05.999Z"
"github.com/err0r500/go-realworld-clean/domain"
)

type Article struct {
Title string `json:"title"`
Expand All @@ -17,26 +19,39 @@ type Article struct {
FavoritesCount int `json:"favoritesCount"`
}

func NewArticleFromDomain(article domain.Article, username string) Article {
func NewArticleFromDomain(article domain.Article, user *domain.User) Article {
isFollowingAuthor := false
favorite := false
if user != nil {
for _, userName := range user.FollowIDs {
if userName == article.Author.Name {
isFollowingAuthor = true
break
}
}

favorite = domain.ArticleIsFavoritedBy(user.Name)(article)
}

return Article{
Slug: article.Slug,
Title: article.Title,
Description: article.Description,
Body: article.Body,
CreatedAt: article.CreatedAt.UTC().Format(dateFormat),
UpdatedAt: article.UpdatedAt.UTC().Format(dateFormat),
Author: NewProfileFromDomain(article.Author, false), //fixme : check this !
CreatedAt: article.CreatedAt.UTC().Format(time.RFC3339),
UpdatedAt: article.UpdatedAt.UTC().Format(time.RFC3339),
Author: NewProfileFromDomain(article.Author, isFollowingAuthor),
Tags: article.TagList,
Favorite: domain.ArticleIsFavoritedBy(username)(article),
Favorite: favorite,
FavoritesCount: len(article.FavoritedBy),
}
}

func NewArticlesFromDomain(username string, articles ...domain.Article) []Article {
ret := []Article{}
func NewArticlesFromDomain(user *domain.User, articles ...domain.Article) []Article {
ret := []Article{} // return at least an empty array (not nil)

for _, article := range articles {
ret = append(ret, NewArticleFromDomain(article, username))
ret = append(ret, NewArticleFromDomain(article, user))
}

return ret
Expand Down
6 changes: 4 additions & 2 deletions implem/json.formatter/comment.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package formatter

import (
"time"

"github.com/err0r500/go-realworld-clean/domain"
)

Expand All @@ -24,8 +26,8 @@ func NewCommentsFromDomain(comments ...domain.Comment) []Comment {
func NewCommentFromDomain(comment domain.Comment) Comment {
return Comment{
ID: comment.ID,
CreatedAt: comment.CreatedAt.UTC().Format(dateFormat),
UpdatedAt: comment.UpdatedAt.UTC().Format(dateFormat),
CreatedAt: comment.CreatedAt.UTC().Format(time.RFC3339),
UpdatedAt: comment.UpdatedAt.UTC().Format(time.RFC3339),
Body: comment.Body,
Author: NewProfileFromDomain(comment.Author, false), //fixme check this
}
Expand Down
Loading

0 comments on commit 1afefcc

Please sign in to comment.