feat: connect explore datasets to backend
This commit is contained in:
139
backend/internal/logic/dataset/handlers_test.go
Normal file
139
backend/internal/logic/dataset/handlers_test.go
Normal file
@@ -0,0 +1,139 @@
|
||||
package dataset
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/glebarez/sqlite"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
"senlinai-agent/backend/internal/config"
|
||||
"senlinai-agent/backend/internal/httpx"
|
||||
"senlinai-agent/backend/internal/models"
|
||||
)
|
||||
|
||||
func TestDatasetAPIConnectsSourcesItemsAndSyncTasks(t *testing.T) {
|
||||
database := newDatasetTestDatabase(t)
|
||||
owner := createDatasetTestUser(t, database, "owner@example.com")
|
||||
other := createDatasetTestUser(t, database, "other@example.com")
|
||||
ownerRouter := datasetTestRouter(database, owner.ID)
|
||||
|
||||
invalid := performDatasetRequest(t, ownerRouter, http.MethodPost, "/api/v1/dataset-sources", map[string]any{
|
||||
"name": "Invalid RSS", "kind": "rss", "url": "",
|
||||
})
|
||||
require.Equal(t, http.StatusBadRequest, invalid.Code)
|
||||
|
||||
createdSource := performDatasetRequest(t, ownerRouter, http.MethodPost, "/api/v1/dataset-sources", map[string]any{
|
||||
"name": "Industry feed", "kind": "rss", "url": "https://example.com/feed",
|
||||
"description": "Industry updates", "enabled": true,
|
||||
})
|
||||
require.Equal(t, http.StatusCreated, createdSource.Code)
|
||||
var source SourceDTO
|
||||
require.NoError(t, json.Unmarshal(createdSource.Body.Bytes(), &source))
|
||||
require.NotEmpty(t, source.ID)
|
||||
require.Equal(t, "Industry feed", source.Name)
|
||||
|
||||
createdItem := performDatasetRequest(t, ownerRouter, http.MethodPost, "/api/v1/dataset-items", map[string]any{
|
||||
"sourceId": source.ID, "title": "A collected article", "summary": "Summary",
|
||||
"url": "https://example.com/article",
|
||||
})
|
||||
require.Equal(t, http.StatusCreated, createdItem.Code)
|
||||
var item ItemDTO
|
||||
require.NoError(t, json.Unmarshal(createdItem.Body.Bytes(), &item))
|
||||
require.Equal(t, source.ID, item.SourceID)
|
||||
|
||||
listSources := performDatasetRequest(t, ownerRouter, http.MethodGet, "/api/v1/dataset-sources", nil)
|
||||
require.Equal(t, http.StatusOK, listSources.Code)
|
||||
var sources []SourceDTO
|
||||
require.NoError(t, json.Unmarshal(listSources.Body.Bytes(), &sources))
|
||||
require.Len(t, sources, 1)
|
||||
require.Equal(t, int64(1), sources[0].ItemCount)
|
||||
|
||||
updatedItem := performDatasetRequest(t, ownerRouter, http.MethodPatch, "/api/v1/dataset-items/"+item.ID, map[string]any{
|
||||
"status": "read", "starred": true,
|
||||
})
|
||||
require.Equal(t, http.StatusOK, updatedItem.Code)
|
||||
require.NoError(t, json.Unmarshal(updatedItem.Body.Bytes(), &item))
|
||||
require.Equal(t, "read", item.Status)
|
||||
require.True(t, item.Starred)
|
||||
|
||||
firstSync := performDatasetRequest(t, ownerRouter, http.MethodPost, "/api/v1/dataset-crons/sync", map[string]any{})
|
||||
require.Equal(t, http.StatusAccepted, firstSync.Code)
|
||||
var firstCrons []CronDTO
|
||||
require.NoError(t, json.Unmarshal(firstSync.Body.Bytes(), &firstCrons))
|
||||
require.Len(t, firstCrons, 1)
|
||||
require.Equal(t, "pending", firstCrons[0].Status)
|
||||
|
||||
secondSync := performDatasetRequest(t, ownerRouter, http.MethodPost, "/api/v1/dataset-crons/sync", map[string]any{})
|
||||
require.Equal(t, http.StatusAccepted, secondSync.Code)
|
||||
var secondCrons []CronDTO
|
||||
require.NoError(t, json.Unmarshal(secondSync.Body.Bytes(), &secondCrons))
|
||||
require.Equal(t, firstCrons[0].ID, secondCrons[0].ID)
|
||||
|
||||
otherRouter := datasetTestRouter(database, other.ID)
|
||||
otherSources := performDatasetRequest(t, otherRouter, http.MethodGet, "/api/v1/dataset-sources", nil)
|
||||
require.Equal(t, http.StatusOK, otherSources.Code)
|
||||
require.JSONEq(t, `[]`, otherSources.Body.String())
|
||||
otherUpdate := performDatasetRequest(t, otherRouter, http.MethodPatch, "/api/v1/dataset-sources/"+source.ID, map[string]any{
|
||||
"name": "Stolen", "kind": "manual", "enabled": true,
|
||||
})
|
||||
require.Equal(t, http.StatusNotFound, otherUpdate.Code)
|
||||
|
||||
deleted := performDatasetRequest(t, ownerRouter, http.MethodDelete, "/api/v1/dataset-sources/"+source.ID, nil)
|
||||
require.Equal(t, http.StatusNoContent, deleted.Code)
|
||||
var itemCount, cronCount int64
|
||||
require.NoError(t, database.Model(&models.SaDatasetItem{}).Count(&itemCount).Error)
|
||||
require.NoError(t, database.Model(&models.SaDatasetCron{}).Count(&cronCount).Error)
|
||||
require.Zero(t, itemCount)
|
||||
require.Zero(t, cronCount)
|
||||
}
|
||||
|
||||
func newDatasetTestDatabase(t *testing.T) *gorm.DB {
|
||||
t.Helper()
|
||||
database, err := gorm.Open(sqlite.Open(fmt.Sprintf("file:%s?mode=memory&cache=shared", t.Name())), &gorm.Config{})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, database.AutoMigrate(
|
||||
&models.SaUser{},
|
||||
&models.SaDatasetSource{},
|
||||
&models.SaDatasetItem{},
|
||||
&models.SaDatasetCron{},
|
||||
))
|
||||
return database
|
||||
}
|
||||
|
||||
func createDatasetTestUser(t *testing.T, database *gorm.DB, email string) models.SaUser {
|
||||
t.Helper()
|
||||
user := models.SaUser{Email: email, DisplayName: email, PasswordHash: "hash", Role: "user"}
|
||||
require.NoError(t, database.Create(&user).Error)
|
||||
return user
|
||||
}
|
||||
|
||||
func datasetTestRouter(database *gorm.DB, userID uint) http.Handler {
|
||||
return httpx.NewProtectedRouter(
|
||||
config.Config{Env: "test"},
|
||||
func(string) (uint, error) { return userID, nil },
|
||||
NewHandler(NewService(database)),
|
||||
)
|
||||
}
|
||||
|
||||
func performDatasetRequest(t *testing.T, router http.Handler, method, path string, body any) *httptest.ResponseRecorder {
|
||||
t.Helper()
|
||||
var encoded []byte
|
||||
if body != nil {
|
||||
var err error
|
||||
encoded, err = json.Marshal(body)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
request := httptest.NewRequest(method, path, bytes.NewReader(encoded))
|
||||
request.Header.Set("Authorization", "Bearer test-token")
|
||||
if body != nil {
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
recorder := httptest.NewRecorder()
|
||||
router.ServeHTTP(recorder, request)
|
||||
return recorder
|
||||
}
|
||||
Reference in New Issue
Block a user