Skip to content

Commit

Permalink
basic storing
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthieu Jacquot committed Aug 2, 2018
1 parent c917199 commit 47e32d0
Show file tree
Hide file tree
Showing 19 changed files with 313 additions and 57 deletions.
16 changes: 16 additions & 0 deletions implem/dummy.articleValidator/validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package articleValidator

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

type validator struct {
}

func New() uc.ArticleValidator {
return validator{}
}

func (validator) BeforeCreationCheck(article *domain.Article) error { return nil }
func (validator) BeforeUpdateCheck(article *domain.Article) error { return nil }
74 changes: 56 additions & 18 deletions implem/gin.server/articles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,31 +57,32 @@ func TestArticlesFiltered(t *testing.T) {
}

func TestArticlesFeed(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
t.Run("happyCase", func(t *testing.T) {

limit := 10
offset := 2
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

jane := testData.User("jane")
limit := 10
offset := 2

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

jwtHandler := jwt.NewTokenHandler("mySalt")
ucHandler := mock.NewMockHandler(mockCtrl)
ucHandler.EXPECT().
ArticlesFeed(jane.Name, limit, offset).
Return(domain.ArticleCollection{testData.Article("jane")}, 10, nil).
Times(1)

gE := gin.Default()
server.NewRouter(ucHandler, jwtHandler).SetRoutes(gE)
ts := httptest.NewServer(gE)
defer ts.Close()
jwtHandler := jwt.NewTokenHandler("mySalt")

authToken, err := jwtHandler.GenUserToken(jane.Name)
assert.NoError(t, err)
gE := gin.Default()
server.NewRouter(ucHandler, jwtHandler).SetRoutes(gE)
ts := httptest.NewServer(gE)
defer ts.Close()

authToken, err := jwtHandler.GenUserToken(jane.Name)
assert.NoError(t, err)

t.Run("happyCase", func(t *testing.T) {
baloo.New(ts.URL).
Get(articlesFeedPath).
AddHeader("Authorization", authToken).
Expand All @@ -92,4 +93,41 @@ func TestArticlesFeed(t *testing.T) {
JSONSchema(testData.ArticleMultipleRespDefinition).
Done()
})

t.Run("empty", func(t *testing.T) {

mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

limit := 10
offset := 2

jane := testData.User("jane")

ucHandler := mock.NewMockHandler(mockCtrl)
ucHandler.EXPECT().
ArticlesFeed(jane.Name, limit, offset).
Return(nil, 0, nil).
Times(1)

jwtHandler := jwt.NewTokenHandler("mySalt")

gE := gin.Default()
server.NewRouter(ucHandler, jwtHandler).SetRoutes(gE)
ts := httptest.NewServer(gE)
defer ts.Close()

authToken, err := jwtHandler.GenUserToken(jane.Name)
assert.NoError(t, err)

baloo.New(ts.URL).
Get(articlesFeedPath).
AddHeader("Authorization", authToken).
AddQuery("limit", strconv.Itoa(limit)).
AddQuery("offset", strconv.Itoa(offset)).
Expect(t).
Status(200).
BodyEquals(`{"articles":[],"articlesCount":0}`).
Done()
})
}
3 changes: 3 additions & 0 deletions implem/gin.server/tagsGet.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,8 @@ func (rH RouterHandler) tagsGet(c *gin.Context) {
return
}

if tags == nil {
tags = []string{}
}
c.JSON(http.StatusOK, gin.H{"tags": tags})
}
62 changes: 44 additions & 18 deletions implem/gin.server/tagsGet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,54 @@ import (
var tagsPath = "/api/tags"

func TestTagsGet_happyCase(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
t.Run("simple", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

tags := []string{"tag1", "tag2"}
ucHandler := uc.NewMockHandler(mockCtrl)
ucHandler.EXPECT().
Tags().
Return(tags, nil).
Times(1)
tags := []string{"tag1", "tag2"}
ucHandler := uc.NewMockHandler(mockCtrl)
ucHandler.EXPECT().
Tags().
Return(tags, nil).
Times(1)

gE := gin.Default()
server.NewRouter(ucHandler, nil).SetRoutes(gE)
gE := gin.Default()
server.NewRouter(ucHandler, nil).SetRoutes(gE)

ts := httptest.NewServer(gE)
defer ts.Close()
ts := httptest.NewServer(gE)
defer ts.Close()

baloo.New(ts.URL).
Get(tagsPath).
Expect(t).
Status(http.StatusOK).
JSONSchema(testData.TagsResponse).
Done()
})
t.Run("empty", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

ucHandler := uc.NewMockHandler(mockCtrl)
ucHandler.EXPECT().
Tags().
Return(nil, nil).
Times(1)

gE := gin.Default()
server.NewRouter(ucHandler, nil).SetRoutes(gE)

ts := httptest.NewServer(gE)
defer ts.Close()

baloo.New(ts.URL).
Get(tagsPath).
Expect(t).
Status(http.StatusOK).
BodyEquals(`{"tags":[]}`).
Done()
})

baloo.New(ts.URL).
Get(tagsPath).
Expect(t).
Status(http.StatusOK).
JSONSchema(testData.TagsResponse).
Done()
}

func TestTagsGet_fail(t *testing.T) {
Expand Down
16 changes: 16 additions & 0 deletions implem/gosimple.slugger/slugger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package slugger

import (
"github.com/err0r500/go-realworld-clean/uc"
"github.com/gosimple/slug"
)

type slugger struct{}

func New() uc.Slugger {
return slugger{}
}

func (slugger) NewSlug(initial string) string {
return slug.Make(initial)
}
2 changes: 1 addition & 1 deletion implem/json.formatter/article.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func NewArticleFromDomain(article domain.Article) Article {
}

func NewArticlesFromDomain(articles ...domain.Article) []Article {
var ret []Article
ret := []Article{}
for _, article := range articles {
ret = append(ret, NewArticleFromDomain(article))
}
Expand Down
67 changes: 61 additions & 6 deletions implem/memory.articleRW/readWriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package articleRW
import (
"sync"

"errors"

"github.com/err0r500/go-realworld-clean/domain"
"github.com/err0r500/go-realworld-clean/uc"
)
Expand All @@ -16,14 +18,67 @@ func New() uc.ArticleRW {
store: &sync.Map{},
}
}
func (rw rw) Create(article domain.Article) (*domain.Article, error) {
if _, err := rw.GetBySlug(article.Slug); err == nil {
return nil, uc.ErrAlreadyInUse
}

rw.store.Store(article.Slug, article)

return rw.GetBySlug(article.Slug)
}

func (rw rw) GetByAuthorsNameOrderedByMostRecentAsc(usernames []string) ([]domain.Article, error) {
var toReturn []domain.Article

rw.store.Range(func(key, value interface{}) bool {
article, ok := value.(domain.Article)
if !ok {
return true // log this but continue
}
for _, username := range usernames {
if article.Author.Name == username {
toReturn = append(toReturn, article)
}
}
return true
})

return toReturn, nil
}

func (rw) GetRecentFiltered(filters uc.Filters) ([]domain.Article, error) {
// todo => check if its AND or OR filters

func (rw) GetByAuthorsNameOrderedByMostRecentAsc(usernames []string) ([]domain.Article, error) {
return nil, nil
}

func (rw) GetRecentFiltered(filters uc.Filters) ([]domain.Article, error) { return nil, nil }
func (rw rw) Save(article domain.Article) (*domain.Article, error) {
if _, err := rw.GetBySlug(article.Slug); err != nil {
return nil, uc.ErrNotFound
}

rw.store.Store(article.Slug, article)

return rw.GetBySlug(article.Slug)
}

func (rw rw) GetBySlug(slug string) (*domain.Article, error) {
value, ok := rw.store.Load(slug)
if !ok {
return nil, uc.ErrNotFound
}

func (rw) Create(domain.Article) (*domain.Article, error) { return nil, nil }
func (rw) Save(domain.Article) (*domain.Article, error) { return nil, nil }
func (rw) GetBySlug(slug string) (*domain.Article, error) { return nil, nil }
func (rw) Delete(slug string) error { return nil }
article, ok := value.(domain.Article)
if !ok {
return nil, errors.New("not an article stored at key")
}

return &article, nil
}

func (rw rw) Delete(slug string) error {
rw.store.Delete(slug)

return nil
}
1 change: 1 addition & 0 deletions implem/memory.articleRW/readWriter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package articleRW
50 changes: 50 additions & 0 deletions implem/memory.commentRW/readWriter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package commentRW

import (
"sync"

"errors"

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

type rw struct {
store *sync.Map
}

func New() uc.CommentRW {
return rw{
store: &sync.Map{},
}
}

func (rw rw) Create(comment domain.Comment) (*domain.Comment, error) {
if _, err := rw.GetByID(comment.ID); err == nil {
return nil, uc.ErrAlreadyInUse
}

rw.store.Store(comment.ID, comment)

return rw.GetByID(comment.ID)
}

func (rw rw) GetByID(id int) (*domain.Comment, error) {
value, ok := rw.store.Load(id)
if !ok {
return nil, uc.ErrNotFound
}

comment, ok := value.(domain.Comment)
if !ok {
return nil, errors.New("not an article stored at key")
}

return &comment, nil
}

func (rw rw) Delete(id int) error {
rw.store.Delete(id)

return nil
}
1 change: 1 addition & 0 deletions implem/memory.commentRW/readWriter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package commentRW_test
43 changes: 43 additions & 0 deletions implem/memory.tagsRW/readWriter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package tagsRW

import (
"sync"

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

type rw struct {
store *sync.Map
}

func New() uc.TagsRW {
return rw{
store: &sync.Map{},
}
}

// lots of ways to improve this (use an array as cache, use index access instead of append...)
// no perf problem for now => no optimisation :)
func (rw rw) GetAll() ([]string, error) {
var toReturn []string

rw.store.Range(func(key, value interface{}) bool {
tag, ok := key.(string)
if !ok {
return true
}
toReturn = append(toReturn, tag)
return true
})

return toReturn, nil
}

func (rw rw) Add(newTags []string) error {

for _, tag := range newTags {
rw.store.Store(tag, true)
}

return nil
}
Loading

0 comments on commit 47e32d0

Please sign in to comment.