Files
gochat/backend/internal/repository/widget_file_upload_repo_test.go
T
rogee aeddedf2a3 Reorganize repo: backend/, deploy/, docs/ layout + AGENTS.md
Restructure the monorepo into clear top-level directories:
- backend/: Go module root (cmd, internal, pkg, configs, migrations,
  docs/swagger, scripts, tests, go.mod, Makefile, .air.toml)
- deploy/: Docker (Dockerfile, docker-compose*), quickstart, fluentd
- docs/: project documentation + reports/ (moved from repo root)
- AGENTS.md: new AI coding-agent guide at repo root

Update all references to the new layout:
- Dockerfile: COPY backend/go.mod, COPY backend/ (context = repo root)
- docker-compose files: context ../.., dockerfile deploy/docker/Dockerfile,
  env_file ../../.env, volume mounts ../../backend:/app
- deploy/quickstart/compose.yaml: dockerfile deploy/docker/Dockerfile
- CI: working-directory: backend for go commands, file deploy/docker/Dockerfile,
  coverage path backend/coverage.out, health_check backend/scripts/
- backend/Makefile: docker target uses -f ../deploy/docker/Dockerfile ../
- README: architecture tree, quickstart, config paths updated

Move root stray scripts (rename_models.*, run_m11_tests.sh, verify_build.sh,
gorm_bool_main.go) to backend/scripts/legacy/. All moves via git mv to
preserve history. Build, vet, SQLite tests, and docker compose config verified.
2026-07-07 14:44:12 +08:00

278 lines
8.8 KiB
Go

package repository
import (
"context"
"fmt"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/gochat/gochat/internal/model"
)
// helper to create a minimal test file upload
func newTestFileUpload(inboxID uint, widgetToken string) *model.WidgetFileUpload {
return &model.WidgetFileUpload{
UploadUUID: "uuid-" + widgetToken,
WidgetToken: widgetToken,
InboxID: inboxID,
ContactID: 0,
Status: model.WidgetFileUploadStatusPending,
OriginalName: "test.png",
FileType: "image",
MimeType: "image/png",
FileSize: 1024,
ExpiresAt: time.Now().Add(24 * time.Hour),
}
}
// --- Test: Create ---
func TestWidgetFileUploadRepo_Create(t *testing.T) {
db := setupTestDB(t, &model.WidgetFileUpload{})
repo := NewWidgetFileUploadRepo(db)
upload := newTestFileUpload(1, "token-abc")
err := repo.Create(context.Background(), upload)
require.NoError(t, err)
assert.NotZero(t, upload.ID)
assert.Equal(t, uint(1), upload.InboxID)
assert.Equal(t, model.WidgetFileUploadStatusPending, upload.Status)
assert.Equal(t, "test.png", upload.OriginalName)
}
// --- Test: FindByID ---
func TestWidgetFileUploadRepo_FindByID(t *testing.T) {
db := setupTestDB(t, &model.WidgetFileUpload{})
repo := NewWidgetFileUploadRepo(db)
upload := newTestFileUpload(10, "token-find")
require.NoError(t, repo.Create(context.Background(), upload))
found, err := repo.FindByID(context.Background(), upload.ID)
require.NoError(t, err)
assert.Equal(t, upload.ID, found.ID)
assert.Equal(t, "token-find", found.WidgetToken)
assert.Equal(t, "test.png", found.OriginalName)
}
// --- Test: FindByID Not Found ---
func TestWidgetFileUploadRepo_FindByID_NotFound(t *testing.T) {
db := setupTestDB(t, &model.WidgetFileUpload{})
repo := NewWidgetFileUploadRepo(db)
found, err := repo.FindByID(context.Background(), 9999)
assert.Error(t, err)
assert.Nil(t, found)
}
// --- Test: FindByWidgetToken ---
func TestWidgetFileUploadRepo_FindByWidgetToken(t *testing.T) {
db := setupTestDB(t, &model.WidgetFileUpload{})
repo := NewWidgetFileUploadRepo(db)
upload := newTestFileUpload(10, "token-unique-xyz")
require.NoError(t, repo.Create(context.Background(), upload))
found, err := repo.FindByWidgetToken(context.Background(), "token-unique-xyz")
require.NoError(t, err)
assert.Equal(t, upload.ID, found.ID)
assert.Equal(t, "token-unique-xyz", found.WidgetToken)
}
// --- Test: FindByWidgetToken Not Found ---
func TestWidgetFileUploadRepo_FindByWidgetToken_NotFound(t *testing.T) {
db := setupTestDB(t, &model.WidgetFileUpload{})
repo := NewWidgetFileUploadRepo(db)
found, err := repo.FindByWidgetToken(context.Background(), "nonexistent-token")
assert.Error(t, err)
assert.Nil(t, found)
}
// --- Test: FindByUUID ---
func TestWidgetFileUploadRepo_FindByUUID(t *testing.T) {
db := setupTestDB(t, &model.WidgetFileUpload{})
repo := NewWidgetFileUploadRepo(db)
upload := newTestFileUpload(10, "token-uuid-test")
require.NoError(t, repo.Create(context.Background(), upload))
found, err := repo.FindByUUID(context.Background(), upload.UploadUUID)
require.NoError(t, err)
assert.Equal(t, upload.ID, found.ID)
assert.Equal(t, upload.UploadUUID, found.UploadUUID)
}
// --- Test: FindByUUID Not Found ---
func TestWidgetFileUploadRepo_FindByUUID_NotFound(t *testing.T) {
db := setupTestDB(t, &model.WidgetFileUpload{})
repo := NewWidgetFileUploadRepo(db)
found, err := repo.FindByUUID(context.Background(), "nonexistent-uuid")
assert.Error(t, err)
assert.Nil(t, found)
}
// --- Test: Update ---
func TestWidgetFileUploadRepo_Update(t *testing.T) {
db := setupTestDB(t, &model.WidgetFileUpload{})
repo := NewWidgetFileUploadRepo(db)
upload := newTestFileUpload(10, "token-update")
require.NoError(t, repo.Create(context.Background(), upload))
upload.FileURL = "https://storage.example.com/test.png"
upload.Status = model.WidgetFileUploadStatusAttached
err := repo.Update(context.Background(), upload)
require.NoError(t, err)
found, err := repo.FindByID(context.Background(), upload.ID)
require.NoError(t, err)
assert.Equal(t, "https://storage.example.com/test.png", found.FileURL)
assert.Equal(t, model.WidgetFileUploadStatusAttached, found.Status)
}
// --- Test: UpdateStatus ---
func TestWidgetFileUploadRepo_UpdateStatus(t *testing.T) {
db := setupTestDB(t, &model.WidgetFileUpload{})
repo := NewWidgetFileUploadRepo(db)
upload := newTestFileUpload(10, "token-status")
require.NoError(t, repo.Create(context.Background(), upload))
err := repo.UpdateStatus(context.Background(), upload.ID, model.WidgetFileUploadStatusAttached)
require.NoError(t, err)
found, err := repo.FindByID(context.Background(), upload.ID)
require.NoError(t, err)
assert.Equal(t, model.WidgetFileUploadStatusAttached, found.Status)
}
// --- Test: UpdateStatus to expired ---
func TestWidgetFileUploadRepo_UpdateStatus_Expired(t *testing.T) {
db := setupTestDB(t, &model.WidgetFileUpload{})
repo := NewWidgetFileUploadRepo(db)
upload := newTestFileUpload(10, "token-expire")
require.NoError(t, repo.Create(context.Background(), upload))
err := repo.UpdateStatus(context.Background(), upload.ID, model.WidgetFileUploadStatusExpired)
require.NoError(t, err)
found, err := repo.FindByID(context.Background(), upload.ID)
require.NoError(t, err)
assert.Equal(t, model.WidgetFileUploadStatusExpired, found.Status)
}
// --- Test: Delete ---
func TestWidgetFileUploadRepo_Delete(t *testing.T) {
db := setupTestDB(t, &model.WidgetFileUpload{})
repo := NewWidgetFileUploadRepo(db)
upload := newTestFileUpload(10, "token-delete")
require.NoError(t, repo.Create(context.Background(), upload))
err := repo.Delete(context.Background(), upload.ID)
require.NoError(t, err)
found, err := repo.FindByID(context.Background(), upload.ID)
assert.Error(t, err)
assert.Nil(t, found)
}
// --- Test: FindExpired ---
func TestWidgetFileUploadRepo_FindExpired(t *testing.T) {
db := setupTestDB(t, &model.WidgetFileUpload{})
repo := NewWidgetFileUploadRepo(db)
// Create an expired pending upload
expiredUpload := &model.WidgetFileUpload{
UploadUUID: "uuid-expired",
WidgetToken: "token-expired",
InboxID: 10,
Status: model.WidgetFileUploadStatusPending,
OriginalName: "expired.png",
FileType: "image",
FileSize: 512,
ExpiresAt: time.Now().Add(-1 * time.Hour), // already expired
}
require.NoError(t, repo.Create(context.Background(), expiredUpload))
// Create a non-expired pending upload
freshUpload := &model.WidgetFileUpload{
UploadUUID: "uuid-fresh",
WidgetToken: "token-fresh",
InboxID: 10,
Status: model.WidgetFileUploadStatusPending,
OriginalName: "fresh.png",
FileType: "image",
FileSize: 512,
ExpiresAt: time.Now().Add(24 * time.Hour), // still valid
}
require.NoError(t, repo.Create(context.Background(), freshUpload))
// Create an attached upload (should not be returned even if expired time)
attachedUpload := &model.WidgetFileUpload{
UploadUUID: "uuid-attached",
WidgetToken: "token-attached",
InboxID: 10,
Status: model.WidgetFileUploadStatusAttached,
OriginalName: "attached.png",
FileType: "image",
FileSize: 512,
ExpiresAt: time.Now().Add(-1 * time.Hour),
}
require.NoError(t, repo.Create(context.Background(), attachedUpload))
expired, err := repo.FindExpired(context.Background(), time.Now())
require.NoError(t, err)
assert.Len(t, expired, 1)
assert.Equal(t, "uuid-expired", expired[0].UploadUUID)
}
// --- Test: FindByInboxAndContact ---
func TestWidgetFileUploadRepo_FindByInboxAndContact(t *testing.T) {
db := setupTestDB(t, &model.WidgetFileUpload{})
repo := NewWidgetFileUploadRepo(db)
// Create uploads for inbox 10, contact 5
for i := 0; i < 3; i++ {
upload := &model.WidgetFileUpload{
UploadUUID: fmt.Sprintf("uuid-inbox10-contact5-%d", i),
WidgetToken: "token-inbox10-contact5",
InboxID: 10,
ContactID: 5,
Status: model.WidgetFileUploadStatusPending,
OriginalName: "file" + string(rune('a'+i)) + ".png",
FileType: "image",
FileSize: 1024,
ExpiresAt: time.Now().Add(24 * time.Hour),
}
require.NoError(t, repo.Create(context.Background(), upload))
}
// Create upload for same inbox, different contact
otherContactUpload := &model.WidgetFileUpload{
UploadUUID: "uuid-inbox10-contact99",
WidgetToken: "token-inbox10-contact99",
InboxID: 10,
ContactID: 99,
Status: model.WidgetFileUploadStatusPending,
OriginalName: "other.png",
FileType: "image",
FileSize: 1024,
ExpiresAt: time.Now().Add(24 * time.Hour),
}
require.NoError(t, repo.Create(context.Background(), otherContactUpload))
uploads, err := repo.FindByInboxAndContact(context.Background(), 10, 5)
require.NoError(t, err)
assert.Len(t, uploads, 3)
for _, u := range uploads {
assert.Equal(t, uint(10), u.InboxID)
assert.Equal(t, uint(5), u.ContactID)
}
}