203 lines
7.5 KiB
Go
203 lines
7.5 KiB
Go
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)
|
|
}
|
|
}
|