first commit
This commit is contained in:
202
app/blogs/handlers/blog_test.go
Normal file
202
app/blogs/handlers/blog_test.go
Normal file
@@ -0,0 +1,202 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
blogModels "ginimageApi/app/blogs/models"
|
||||
"ginimageApi/configs"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func setupBlogHandlersTestDB(t *testing.T) {
|
||||
t.Helper()
|
||||
prev := configs.DB
|
||||
dsn := "file:" + t.Name() + "?mode=memory&cache=shared"
|
||||
db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{})
|
||||
if err != nil {
|
||||
t.Fatalf("sqlite open failed: %v", err)
|
||||
}
|
||||
if err := db.AutoMigrate(&blogModels.Category{}, &blogModels.Tag{}, &blogModels.Post{}, &blogModels.CategoryView{}, &blogModels.Comment{}); err != nil {
|
||||
t.Fatalf("migrate failed: %v", err)
|
||||
}
|
||||
configs.DB = db
|
||||
t.Cleanup(func() {
|
||||
if sqlDB, err := db.DB(); err == nil {
|
||||
_ = sqlDB.Close()
|
||||
}
|
||||
configs.DB = prev
|
||||
})
|
||||
}
|
||||
|
||||
func withUser(userID uint) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Set("user_id", userID)
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func TestListPostsReturnsOnlyActive(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
setupBlogHandlersTestDB(t)
|
||||
|
||||
posts := []blogModels.Post{
|
||||
{Title: "Active Post", Content: "A", IsActive: true, IsFront: true},
|
||||
{Title: "Passive Post", Content: "B", IsActive: true, IsFront: false},
|
||||
}
|
||||
if err := configs.DB.Create(&posts).Error; err != nil {
|
||||
t.Fatalf("seed failed: %v", err)
|
||||
}
|
||||
if err := configs.DB.Model(&blogModels.Post{}).Where("title = ?", "Passive Post").Update("is_active", false).Error; err != nil {
|
||||
t.Fatalf("seed update failed: %v", err)
|
||||
}
|
||||
|
||||
r := gin.New()
|
||||
r.GET("/blogs", ListPosts)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
r.ServeHTTP(w, httptest.NewRequest(http.MethodGet, "/blogs", nil))
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d body=%s", w.Code, w.Body.String())
|
||||
}
|
||||
|
||||
var resp struct {
|
||||
Count int `json:"count"`
|
||||
}
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("json parse failed: %v", err)
|
||||
}
|
||||
if resp.Count != 1 {
|
||||
t.Fatalf("expected only active posts, got %d", resp.Count)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdminCreateUpdateDeletePost(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
setupBlogHandlersTestDB(t)
|
||||
|
||||
r := gin.New()
|
||||
r.POST("/blogs", withUser(1), CreatePost)
|
||||
r.PUT("/blogs/:id", withUser(1), UpdatePost)
|
||||
r.DELETE("/blogs/:id", withUser(1), DeletePost)
|
||||
|
||||
createBody := []byte(`{"title":"Yeni Blog","content":"icerik"}`)
|
||||
wCreate := httptest.NewRecorder()
|
||||
reqCreate := httptest.NewRequest(http.MethodPost, "/blogs", bytes.NewReader(createBody))
|
||||
reqCreate.Header.Set("Content-Type", "application/json")
|
||||
r.ServeHTTP(wCreate, reqCreate)
|
||||
if wCreate.Code != http.StatusCreated {
|
||||
t.Fatalf("expected 201, got %d body=%s", wCreate.Code, wCreate.Body.String())
|
||||
}
|
||||
|
||||
// SQLite'da mevcut model taniminda auto ID davranisi tutarsiz olabildigi icin
|
||||
// update/delete senaryosunu explicit ID ile seed edilen kayit uzerinden dogruluyoruz.
|
||||
seedForUpdate := blogModels.Post{ID: 77, Title: "Seeded Blog", Content: "x", IsActive: true, IsFront: true}
|
||||
if err := configs.DB.Create(&seedForUpdate).Error; err != nil {
|
||||
t.Fatalf("seed for update failed: %v", err)
|
||||
}
|
||||
|
||||
updateBody := []byte(`{"title":"Guncel Blog"}`)
|
||||
wUpdate := httptest.NewRecorder()
|
||||
reqUpdate := httptest.NewRequest(http.MethodPut, "/blogs/"+strconv.FormatUint(seedForUpdate.ID, 10), bytes.NewReader(updateBody))
|
||||
reqUpdate.Header.Set("Content-Type", "application/json")
|
||||
r.ServeHTTP(wUpdate, reqUpdate)
|
||||
if wUpdate.Code != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d body=%s", wUpdate.Code, wUpdate.Body.String())
|
||||
}
|
||||
|
||||
wDelete := httptest.NewRecorder()
|
||||
r.ServeHTTP(wDelete, httptest.NewRequest(http.MethodDelete, "/blogs/"+strconv.FormatUint(seedForUpdate.ID, 10), nil))
|
||||
if wDelete.Code != http.StatusNoContent {
|
||||
t.Fatalf("expected 204, got %d", wDelete.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCategoryAndTagEndpoints(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
setupBlogHandlersTestDB(t)
|
||||
|
||||
r := gin.New()
|
||||
r.GET("/blogs/categories", ListCategories)
|
||||
r.GET("/blogs/tags", ListTags)
|
||||
r.POST("/blogs/categories", withUser(1), CreateCategory)
|
||||
r.PUT("/blogs/categories/:id", withUser(1), UpdateCategory)
|
||||
r.DELETE("/blogs/categories/:id", withUser(1), DeleteCategory)
|
||||
r.POST("/blogs/tags", withUser(1), CreateTag)
|
||||
r.PUT("/blogs/tags/:id", withUser(1), UpdateTag)
|
||||
r.DELETE("/blogs/tags/:id", withUser(1), DeleteTag)
|
||||
|
||||
wCreateCategory := httptest.NewRecorder()
|
||||
reqCreateCategory := httptest.NewRequest(http.MethodPost, "/blogs/categories", bytes.NewReader([]byte(`{"title":"Genel"}`)))
|
||||
reqCreateCategory.Header.Set("Content-Type", "application/json")
|
||||
r.ServeHTTP(wCreateCategory, reqCreateCategory)
|
||||
if wCreateCategory.Code != http.StatusCreated {
|
||||
t.Fatalf("category create expected 201, got %d body=%s", wCreateCategory.Code, wCreateCategory.Body.String())
|
||||
}
|
||||
|
||||
wCreateTag := httptest.NewRecorder()
|
||||
reqCreateTag := httptest.NewRequest(http.MethodPost, "/blogs/tags", bytes.NewReader([]byte(`{"tag":"Go"}`)))
|
||||
reqCreateTag.Header.Set("Content-Type", "application/json")
|
||||
r.ServeHTTP(wCreateTag, reqCreateTag)
|
||||
if wCreateTag.Code != http.StatusCreated {
|
||||
t.Fatalf("tag create expected 201, got %d body=%s", wCreateTag.Code, wCreateTag.Body.String())
|
||||
}
|
||||
|
||||
// SQLite'da mevcut model taniminda auto ID davranisi tutarsiz olabildigi icin
|
||||
// kategori/tag update-delete senaryosunu explicit ID ile seed edilen kayitlar uzerinden dogruluyoruz.
|
||||
seedCategory := blogModels.Category{ID: 77, Title: "SeedCategory", IsActive: true, Order: 1}
|
||||
if err := configs.DB.Create(&seedCategory).Error; err != nil {
|
||||
t.Fatalf("seed category for update failed: %v", err)
|
||||
}
|
||||
seedTag := blogModels.Tag{ID: 88, Tag: "SeedTag", IsActive: true}
|
||||
if err := configs.DB.Create(&seedTag).Error; err != nil {
|
||||
t.Fatalf("seed tag for update failed: %v", err)
|
||||
}
|
||||
|
||||
wListCategories := httptest.NewRecorder()
|
||||
r.ServeHTTP(wListCategories, httptest.NewRequest(http.MethodGet, "/blogs/categories", nil))
|
||||
if wListCategories.Code != http.StatusOK {
|
||||
t.Fatalf("category list expected 200, got %d", wListCategories.Code)
|
||||
}
|
||||
|
||||
wListTags := httptest.NewRecorder()
|
||||
r.ServeHTTP(wListTags, httptest.NewRequest(http.MethodGet, "/blogs/tags", nil))
|
||||
if wListTags.Code != http.StatusOK {
|
||||
t.Fatalf("tag list expected 200, got %d", wListTags.Code)
|
||||
}
|
||||
|
||||
wUpdateCategory := httptest.NewRecorder()
|
||||
reqUpdateCategory := httptest.NewRequest(http.MethodPut, "/blogs/categories/"+strconv.FormatUint(seedCategory.ID, 10), bytes.NewReader([]byte(`{"title":"Teknoloji"}`)))
|
||||
reqUpdateCategory.Header.Set("Content-Type", "application/json")
|
||||
r.ServeHTTP(wUpdateCategory, reqUpdateCategory)
|
||||
if wUpdateCategory.Code != http.StatusOK {
|
||||
t.Fatalf("category update expected 200, got %d body=%s", wUpdateCategory.Code, wUpdateCategory.Body.String())
|
||||
}
|
||||
|
||||
wUpdateTag := httptest.NewRecorder()
|
||||
reqUpdateTag := httptest.NewRequest(http.MethodPut, "/blogs/tags/"+strconv.FormatUint(seedTag.ID, 10), bytes.NewReader([]byte(`{"tag":"Golang"}`)))
|
||||
reqUpdateTag.Header.Set("Content-Type", "application/json")
|
||||
r.ServeHTTP(wUpdateTag, reqUpdateTag)
|
||||
if wUpdateTag.Code != http.StatusOK {
|
||||
t.Fatalf("tag update expected 200, got %d body=%s", wUpdateTag.Code, wUpdateTag.Body.String())
|
||||
}
|
||||
|
||||
wDeleteCategory := httptest.NewRecorder()
|
||||
r.ServeHTTP(wDeleteCategory, httptest.NewRequest(http.MethodDelete, "/blogs/categories/"+strconv.FormatUint(seedCategory.ID, 10), nil))
|
||||
if wDeleteCategory.Code != http.StatusNoContent {
|
||||
t.Fatalf("category delete expected 204, got %d", wDeleteCategory.Code)
|
||||
}
|
||||
|
||||
wDeleteTag := httptest.NewRecorder()
|
||||
r.ServeHTTP(wDeleteTag, httptest.NewRequest(http.MethodDelete, "/blogs/tags/"+strconv.FormatUint(seedTag.ID, 10), nil))
|
||||
if wDeleteTag.Code != http.StatusNoContent {
|
||||
t.Fatalf("tag delete expected 204, got %d", wDeleteTag.Code)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user