diff --git a/adapters/secondary/gateways/articleRepository.go b/adapters/secondary/gateways/articleRepository.go deleted file mode 100644 index 34eda9d..0000000 --- a/adapters/secondary/gateways/articleRepository.go +++ /dev/null @@ -1,62 +0,0 @@ -package gateways - -import ( - entity "GohCMS2/adapters/secondary/gateways/models" - domain "GohCMS2/domain/article" - "GohCMS2/domain/gateways" - "gorm.io/gorm" -) - -type ArticleRepository struct { - db *gorm.DB -} - -func NewArticleRepository(db *gorm.DB) *ArticleRepository { - return &ArticleRepository{db} -} - -func mapArticleToDomain(article entity.Article) domain.Article { - return domain.FromDb(article.ID, article.Title, article.Body, article.CreatedAt, article.UpdatedAt) -} - -func (a *ArticleRepository) Get(id uint32) (domain.Article, error) { - var article entity.Article - err := a.db.Model(&entity.Article{}).First(&article, id).Error - if err != nil { - return domain.Article{}, err - } - - return mapArticleToDomain(article), nil -} - -func (a *ArticleRepository) Create(article domain.Article) (domain.Article, error) { - creationResult := a.db.Create(&entity.Article{ - Title: article.Title, - Body: article.Body, - }) - if creationResult.Error != nil { - return domain.Article{}, creationResult.Error - } - - var createdArticle entity.Article - creationResult.Scan(&createdArticle) - - return mapArticleToDomain(createdArticle), nil -} - -func (a *ArticleRepository) GetAll() []domain.Article { - var articles []entity.Article - err := a.db.Model(&entity.Article{}).Find(&articles).Error - if err != nil { - return []domain.Article{} - } - - var domainArticles = make([]domain.Article, 0) - for _, article := range articles { - domainArticles = append(domainArticles, mapArticleToDomain(article)) - } - - return domainArticles -} - -var _ gateways.IArticleRepository = &ArticleRepository{} diff --git a/adapters/secondary/gateways/models/article.go b/adapters/secondary/gateways/models/post.go similarity index 92% rename from adapters/secondary/gateways/models/article.go rename to adapters/secondary/gateways/models/post.go index 1c22d92..f0bd730 100644 --- a/adapters/secondary/gateways/models/article.go +++ b/adapters/secondary/gateways/models/post.go @@ -5,7 +5,7 @@ import ( "time" ) -type Article struct { +type Post struct { gorm.Model ID uint32 `gorm:"primary_key;auto_increment;not_null"` Title string diff --git a/adapters/secondary/gateways/postRepository.go b/adapters/secondary/gateways/postRepository.go new file mode 100644 index 0000000..15a1bd9 --- /dev/null +++ b/adapters/secondary/gateways/postRepository.go @@ -0,0 +1,62 @@ +package gateways + +import ( + entity "GohCMS2/adapters/secondary/gateways/models" + "GohCMS2/domain/gateways" + domain "GohCMS2/domain/post" + "gorm.io/gorm" +) + +type PostRepository struct { + db *gorm.DB +} + +func NewPostRepository(db *gorm.DB) *PostRepository { + return &PostRepository{db} +} + +func mapPostToDomain(post entity.Post) domain.Post { + return domain.FromDb(post.ID, post.Title, post.Body, post.CreatedAt, post.UpdatedAt) +} + +func (a *PostRepository) Get(id uint32) (domain.Post, error) { + var article entity.Post + err := a.db.Model(&entity.Post{}).First(&article, id).Error + if err != nil { + return domain.Post{}, err + } + + return mapPostToDomain(article), nil +} + +func (a *PostRepository) Create(article domain.Post) (domain.Post, error) { + creationResult := a.db.Create(&entity.Post{ + Title: article.Title, + Body: article.Body, + }) + if creationResult.Error != nil { + return domain.Post{}, creationResult.Error + } + + var createdArticle entity.Post + creationResult.Scan(&createdArticle) + + return mapPostToDomain(createdArticle), nil +} + +func (a *PostRepository) GetAll() []domain.Post { + var articles []entity.Post + err := a.db.Model(&entity.Post{}).Find(&articles).Error + if err != nil { + return []domain.Post{} + } + + var domainArticles = make([]domain.Post, 0) + for _, article := range articles { + domainArticles = append(domainArticles, mapPostToDomain(article)) + } + + return domainArticles +} + +var _ gateways.IArticleRepository = &PostRepository{} diff --git a/adapters/secondary/gateways/web/templates/home.html b/adapters/secondary/gateways/web/templates/home.html index 14ef0ae..35e0e39 100644 --- a/adapters/secondary/gateways/web/templates/home.html +++ b/adapters/secondary/gateways/web/templates/home.html @@ -16,6 +16,7 @@

Accueil

Bienvenue sur GohCMS !

+
diff --git a/api/dependecyInjection.go b/api/dependecyInjection.go index 92ec0c2..863657c 100644 --- a/api/dependecyInjection.go +++ b/api/dependecyInjection.go @@ -11,7 +11,7 @@ import ( ) type LocalContainer struct { - CreateArticleUseCase *useCases.CreateArticleUseCase + CreateArticleUseCase *useCases.CreatePostUseCase GetArticleUseCase *useCases.GetArticleUseCase ListArticlesUseCase *useCases.ListArticlesUseCase GetUserUseCase *useCases.GetUserUseCase @@ -23,7 +23,7 @@ type LocalContainer struct { var Container *LocalContainer func setContainer( - createArticle *useCases.CreateArticleUseCase, + createArticle *useCases.CreatePostUseCase, getArticle *useCases.GetArticleUseCase, listArticle *useCases.ListArticlesUseCase, getUser *useCases.GetUserUseCase, @@ -60,11 +60,11 @@ func InitContainer() { panic("Unable to open the database: " + err.Error()) } - _ = db.AutoMigrate(&models.Article{}, &models.User{}) + _ = db.AutoMigrate(&models.Post{}, &models.User{}) _ = digContainer.Provide(func() *gorm.DB { return db }) - _ = digContainer.Provide(func(db *gorm.DB) *useCases.CreateArticleUseCase { return useCases.NewCreateArticleUseCase(db) }) + _ = digContainer.Provide(func(db *gorm.DB) *useCases.CreatePostUseCase { return useCases.NewCreatePostUseCase(db) }) _ = digContainer.Provide(func(db *gorm.DB) *useCases.GetArticleUseCase { return useCases.NewGetArticleUseCase(db) }) _ = digContainer.Provide(func(db *gorm.DB) *useCases.ListArticlesUseCase { return useCases.NewListArticlesUseCase(db) }) _ = digContainer.Provide(func(db *gorm.DB) *useCases.GetUserUseCase { return useCases.NewGetUserUseCase(db) }) diff --git a/api/article.go b/api/post.go similarity index 94% rename from api/article.go rename to api/post.go index 8d0cfbc..ddb95f8 100644 --- a/api/article.go +++ b/api/post.go @@ -44,7 +44,7 @@ func postArticle(w http.ResponseWriter, r *http.Request) { return } - createdArticle, err := Container.CreateArticleUseCase.CreateArticle(useCases.CreateArticleCommand{ + createdArticle, err := Container.CreateArticleUseCase.CreatePost(useCases.CreatePostCommand{ Title: article.Title, Body: article.Body, }) diff --git a/domain/gateways/IArticleRepository.go b/domain/gateways/IArticleRepository.go deleted file mode 100644 index 7373471..0000000 --- a/domain/gateways/IArticleRepository.go +++ /dev/null @@ -1,11 +0,0 @@ -package gateways - -import ( - "GohCMS2/domain/article" -) - -type IArticleRepository interface { - Get(id uint32) (article.Article, error) - GetAll() []article.Article - Create(article article.Article) (article.Article, error) -} diff --git a/domain/gateways/IPostRepository.go b/domain/gateways/IPostRepository.go new file mode 100644 index 0000000..cb7974a --- /dev/null +++ b/domain/gateways/IPostRepository.go @@ -0,0 +1,11 @@ +package gateways + +import ( + "GohCMS2/domain/post" +) + +type IArticleRepository interface { + Get(id uint32) (post.Post, error) + GetAll() []post.Post + Create(article post.Post) (post.Post, error) +} diff --git a/domain/article/article.go b/domain/post/post.go similarity index 83% rename from domain/article/article.go rename to domain/post/post.go index 184b76a..2a42e0f 100644 --- a/domain/article/article.go +++ b/domain/post/post.go @@ -1,8 +1,8 @@ -package article +package post import "time" -type Article struct { +type Post struct { ID uint32 `json:"id"` Title string `json:"title"` Body string `json:"body"` @@ -13,8 +13,8 @@ type Article struct { func FromApi( title string, body string, -) Article { - return Article{ +) Post { + return Post{ Title: title, Body: body, } @@ -26,8 +26,8 @@ func FromDb( body string, createdAt time.Time, updatedAt time.Time, -) Article { - return Article{ +) Post { + return Post{ ID: id, Title: title, Body: body, diff --git a/main.exe b/main.exe new file mode 100644 index 0000000..b161ee8 Binary files /dev/null and b/main.exe differ diff --git a/main/route/route.go b/main/route/route.go index 1b1ae38..89ea87e 100644 --- a/main/route/route.go +++ b/main/route/route.go @@ -46,7 +46,7 @@ func InitBackendRoutes() *chi.Mux { r.Group(func(r chi.Router) { r.Use(jwtauth.Verifier(api.TokenAuth)) r.Use(jwtauth.Authenticator) - r.Mount("/article", api.NewArticleRouter()) + r.Mount("/post", api.NewArticleRouter()) }) r.Mount("/auth", api.NewAuthRouter()) diff --git a/test/article_test.go b/test/article_test.go deleted file mode 100644 index 606a6eb..0000000 --- a/test/article_test.go +++ /dev/null @@ -1,144 +0,0 @@ -package test - -import ( - "GohCMS2/domain/article" - "bytes" - "encoding/json" - "github.com/stretchr/testify/assert" - "io" - "net/http" - "strconv" - "testing" -) - -var TestCreateArticleSuccess = func(t *testing.T) { - jsonBody, err := json.Marshal(map[string]string{ - "title": "Test Title", - "body": "Test Body", - }) - if err != nil { - t.Fatal(err) - } - - r, _ := ApiRequest("POST", "/article", bytes.NewBuffer(jsonBody)) - - var response article.Article - bd, err := io.ReadAll(r.Body) - if err != nil { - t.Fatal(err) - } - - err = json.Unmarshal(bd, &response) - if err != nil { - t.Fatal(err) - } - - assert.Equal(t, http.StatusOK, r.StatusCode) - assert.Equal(t, "Test Title", response.Title) - assert.Equal(t, "Test Body", response.Body) -} - -var TestCreateArticleFailTitleMissing = func(t *testing.T) { - jsonBody, err := json.Marshal(map[string]string{ - "body": "Test Body", - }) - if err != nil { - t.Fatal(err) - } - - r, _ := ApiRequest("POST", "/article", bytes.NewBuffer(jsonBody)) - - assert.Equal(t, http.StatusBadRequest, r.StatusCode) -} - -var TestCreateArticleTitleTooShort = func(t *testing.T) { - jsonBody, err := json.Marshal(map[string]string{ - "title": "Te", - "body": "Test Body", - }) - if err != nil { - t.Fatal(err) - } - - r, _ := ApiRequest("POST", "/article", bytes.NewBuffer(jsonBody)) - - assert.Equal(t, http.StatusBadRequest, r.StatusCode) -} - -var TestGetArticleSuccess = func(t *testing.T) { - var createdArticle article.Article - var articleToCreate = article.Article{ - Title: "Test Title", - Body: "Test Body", - } - db := GetDb() - db.Create(&articleToCreate).Scan(&createdArticle) - - r, _ := ApiRequest("GET", "/article/"+strconv.Itoa(int(createdArticle.ID)), nil) - - var response article.Article - bd, err := io.ReadAll(r.Body) - if err != nil { - t.Fatal(err) - } - - err = json.Unmarshal(bd, &response) - if err != nil { - t.Fatal(err) - } - - assert.Equal(t, http.StatusOK, r.StatusCode) - assert.Equal(t, createdArticle.ID, response.ID) - assert.Equal(t, createdArticle.Title, response.Title) - assert.Equal(t, createdArticle.Body, response.Body) -} - -var TestGetAllArticlesSuccess = func(t *testing.T) { - var createdArticle article.Article - var articleToCreate = article.Article{ - Title: "Test Title", - Body: "Test Body", - } - db := GetDb() - db.Create(&articleToCreate).Scan(&createdArticle) - - r, _ := ApiRequest("GET", "/article", nil) - - var response []article.Article - bd, err := io.ReadAll(r.Body) - if err != nil { - t.Fatal(err) - } - - err = json.Unmarshal(bd, &response) - if err != nil { - t.Fatal(err) - } - - assert.Equal(t, http.StatusOK, r.StatusCode) - assert.Equal(t, createdArticle.Title, response[0].Title) - assert.Equal(t, createdArticle.Body, response[0].Body) -} - -var TestArticleCreate = func(t *testing.T) { - t.Run("Should return an article with the given title and body", TestCreateArticleSuccess) - t.Run("Should return an error if the title is missing", TestCreateArticleFailTitleMissing) - t.Run("Should return an error if the title is too short", TestCreateArticleTitleTooShort) -} - -var TestArticleGet = func(t *testing.T) { - t.Run("Should return an article with the given id", TestGetArticleSuccess) -} - -var TestArticleGetAll = func(t *testing.T) { - t.Run("Should return all articles", TestGetAllArticlesSuccess) -} - -func TestArticle(t *testing.T) { - StartServerIfNotAlready() - WaitForServer() - - t.Run("Create", TestArticleCreate) - t.Run("Get", TestArticleGet) - t.Run("GetAll", TestArticleGetAll) -} diff --git a/test/post_test.go b/test/post_test.go new file mode 100644 index 0000000..b663610 --- /dev/null +++ b/test/post_test.go @@ -0,0 +1,144 @@ +package test + +import ( + "GohCMS2/domain/post" + "bytes" + "encoding/json" + "github.com/stretchr/testify/assert" + "io" + "net/http" + "strconv" + "testing" +) + +var TestCreatePostSuccess = func(t *testing.T) { + jsonBody, err := json.Marshal(map[string]string{ + "title": "Test Title", + "body": "Test Body", + }) + if err != nil { + t.Fatal(err) + } + + r, _ := ApiRequest("POST", "/post", bytes.NewBuffer(jsonBody)) + + var response post.Post + bd, err := io.ReadAll(r.Body) + if err != nil { + t.Fatal(err) + } + + err = json.Unmarshal(bd, &response) + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, http.StatusOK, r.StatusCode) + assert.Equal(t, "Test Title", response.Title) + assert.Equal(t, "Test Body", response.Body) +} + +var TestCreatePostFailTitleMissing = func(t *testing.T) { + jsonBody, err := json.Marshal(map[string]string{ + "body": "Test Body", + }) + if err != nil { + t.Fatal(err) + } + + r, _ := ApiRequest("POST", "/post", bytes.NewBuffer(jsonBody)) + + assert.Equal(t, http.StatusBadRequest, r.StatusCode) +} + +var TestCreatePostTitleTooShort = func(t *testing.T) { + jsonBody, err := json.Marshal(map[string]string{ + "title": "Te", + "body": "Test Body", + }) + if err != nil { + t.Fatal(err) + } + + r, _ := ApiRequest("POST", "/post", bytes.NewBuffer(jsonBody)) + + assert.Equal(t, http.StatusBadRequest, r.StatusCode) +} + +var TestGetPostSuccess = func(t *testing.T) { + var createdPost post.Post + var articleToCreate = post.Post{ + Title: "Test Title", + Body: "Test Body", + } + db := GetDb() + db.Create(&articleToCreate).Scan(&createdPost) + + r, _ := ApiRequest("GET", "/post/"+strconv.Itoa(int(createdPost.ID)), nil) + + var response post.Post + bd, err := io.ReadAll(r.Body) + if err != nil { + t.Fatal(err) + } + + err = json.Unmarshal(bd, &response) + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, http.StatusOK, r.StatusCode) + assert.Equal(t, createdPost.ID, response.ID) + assert.Equal(t, createdPost.Title, response.Title) + assert.Equal(t, createdPost.Body, response.Body) +} + +var TestGetAllPostsSuccess = func(t *testing.T) { + var createdPost post.Post + var articleToCreate = post.Post{ + Title: "Test Title", + Body: "Test Body", + } + db := GetDb() + db.Create(&articleToCreate).Scan(&createdPost) + + r, _ := ApiRequest("GET", "/post", nil) + + var response []post.Post + bd, err := io.ReadAll(r.Body) + if err != nil { + t.Fatal(err) + } + + err = json.Unmarshal(bd, &response) + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, http.StatusOK, r.StatusCode) + assert.Equal(t, createdPost.Title, response[0].Title) + assert.Equal(t, createdPost.Body, response[0].Body) +} + +var TestPostCreate = func(t *testing.T) { + t.Run("Should return an post with the given title and body", TestCreatePostSuccess) + t.Run("Should return an error if the title is missing", TestCreatePostFailTitleMissing) + t.Run("Should return an error if the title is too short", TestCreatePostTitleTooShort) +} + +var TestPostGet = func(t *testing.T) { + t.Run("Should return an post with the given id", TestGetPostSuccess) +} + +var TestPostGetAll = func(t *testing.T) { + t.Run("Should return all articles", TestGetAllPostsSuccess) +} + +func TestPost(t *testing.T) { + StartServerIfNotAlready() + WaitForServer() + + t.Run("Create", TestPostCreate) + t.Run("Get", TestPostGet) + t.Run("GetAll", TestPostGetAll) +} diff --git a/test/utils.go b/test/utils.go index e5b8481..37e920e 100644 --- a/test/utils.go +++ b/test/utils.go @@ -12,16 +12,18 @@ import ( "time" ) +const testDbFile = "test.db" + var ApiUrl string var AuthorizationCookie *http.Cookie var HttpClient = http.Client{} func GetDb() *gorm.DB { - db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{}) + db, err := gorm.Open(sqlite.Open(testDbFile), &gorm.Config{}) if err != nil { panic(err) } - _ = db.AutoMigrate(&models.Article{}, &models.User{}) + _ = db.AutoMigrate(&models.Post{}, &models.User{}) return db } @@ -30,8 +32,8 @@ func StartServerIfNotAlready() { if err == nil { return } - _ = os.Remove("test.db") - _ = os.Setenv("DB_FILE", "test.db") + _ = os.Remove(testDbFile) + _ = os.Setenv("DB_FILE", testDbFile) go func(url *string) { router := server.InitServer() *url = "http://localhost:" + os.Getenv("PORT") + "/v1" diff --git a/useCases/CreateArticleUseCase.go b/useCases/CreateArticleUseCase.go deleted file mode 100644 index 6382616..0000000 --- a/useCases/CreateArticleUseCase.go +++ /dev/null @@ -1,29 +0,0 @@ -package useCases - -import ( - "GohCMS2/adapters/secondary/gateways" - "GohCMS2/domain/article" - "gorm.io/gorm" -) - -type CreateArticleUseCase struct { - articleRepository gateways.ArticleRepository -} - -type CreateArticleCommand struct { - Title string - Body string -} - -func NewCreateArticleUseCase(db *gorm.DB) *CreateArticleUseCase { - return &CreateArticleUseCase{ - articleRepository: *gateways.NewArticleRepository(db), - } -} - -func (g *CreateArticleUseCase) CreateArticle(createArticle CreateArticleCommand) (article.Article, error) { - return g.articleRepository.Create(article.FromApi( - createArticle.Title, - createArticle.Body, - )) -} diff --git a/useCases/CreatePostUseCase.go b/useCases/CreatePostUseCase.go new file mode 100644 index 0000000..7f2eb0f --- /dev/null +++ b/useCases/CreatePostUseCase.go @@ -0,0 +1,29 @@ +package useCases + +import ( + "GohCMS2/adapters/secondary/gateways" + "GohCMS2/domain/post" + "gorm.io/gorm" +) + +type CreatePostUseCase struct { + postRepository gateways.PostRepository +} + +type CreatePostCommand struct { + Title string + Body string +} + +func NewCreatePostUseCase(db *gorm.DB) *CreatePostUseCase { + return &CreatePostUseCase{ + postRepository: *gateways.NewPostRepository(db), + } +} + +func (g *CreatePostUseCase) CreatePost(createPost CreatePostCommand) (post.Post, error) { + return g.postRepository.Create(post.FromApi( + createPost.Title, + createPost.Body, + )) +} diff --git a/useCases/GetArticleUseCase.go b/useCases/GetPostUseCase.go similarity index 55% rename from useCases/GetArticleUseCase.go rename to useCases/GetPostUseCase.go index 85f6a59..7c8a967 100644 --- a/useCases/GetArticleUseCase.go +++ b/useCases/GetPostUseCase.go @@ -2,20 +2,20 @@ package useCases import ( "GohCMS2/adapters/secondary/gateways" - "GohCMS2/domain/article" + "GohCMS2/domain/post" "gorm.io/gorm" ) type GetArticleUseCase struct { - articleRepository gateways.ArticleRepository + articleRepository gateways.PostRepository } func NewGetArticleUseCase(db *gorm.DB) *GetArticleUseCase { return &GetArticleUseCase{ - articleRepository: *gateways.NewArticleRepository(db), + articleRepository: *gateways.NewPostRepository(db), } } -func (g *GetArticleUseCase) GetArticle(id uint32) (article.Article, error) { +func (g *GetArticleUseCase) GetArticle(id uint32) (post.Post, error) { return g.articleRepository.Get(id) } diff --git a/useCases/ListArticlesUseCase.go b/useCases/ListPostsUseCase.go similarity index 57% rename from useCases/ListArticlesUseCase.go rename to useCases/ListPostsUseCase.go index b95167b..67ba9b4 100644 --- a/useCases/ListArticlesUseCase.go +++ b/useCases/ListPostsUseCase.go @@ -2,20 +2,20 @@ package useCases import ( "GohCMS2/adapters/secondary/gateways" - "GohCMS2/domain/article" + "GohCMS2/domain/post" "gorm.io/gorm" ) type ListArticlesUseCase struct { - articleRepository gateways.ArticleRepository + articleRepository gateways.PostRepository } func NewListArticlesUseCase(db *gorm.DB) *ListArticlesUseCase { return &ListArticlesUseCase{ - articleRepository: *gateways.NewArticleRepository(db), + articleRepository: *gateways.NewPostRepository(db), } } -func (g *ListArticlesUseCase) ListArticles() []article.Article { +func (g *ListArticlesUseCase) ListArticles() []post.Post { return g.articleRepository.GetAll() }