237 lines
8.1 KiB
Go
237 lines
8.1 KiB
Go
package usecase_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"apps/backend/internal/module/appnotif/repository"
|
|
appUC "apps/backend/internal/module/appnotif/usecase"
|
|
"apps/backend/internal/module/job/domain"
|
|
jobRepo "apps/backend/internal/module/job/repository"
|
|
"apps/backend/internal/module/job/usecase"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func newJobSvc() (*usecase.Service, *appUC.Service) {
|
|
jr := jobRepo.NewMemory()
|
|
nr := repository.NewMemory()
|
|
notif := appUC.New(nr)
|
|
svc := usecase.New(jr)
|
|
svc.Notifier = notif
|
|
return svc, notif
|
|
}
|
|
|
|
func TestJB_01_CreateDemo(t *testing.T) {
|
|
svc, _ := newJobSvc()
|
|
j, err := svc.StartDemo(context.Background(), 1_000_100)
|
|
require.NoError(t, err)
|
|
require.Equal(t, domain.StatusQueued, j.Status)
|
|
require.Equal(t, domain.TemplateDemo, j.TemplateType)
|
|
list, err := svc.List(context.Background(), 1_000_100)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, list)
|
|
}
|
|
|
|
func TestJB_02_ProgressMonotonic(t *testing.T) {
|
|
svc, _ := newJobSvc()
|
|
j, err := svc.StartDemo(context.Background(), 1_000_101)
|
|
require.NoError(t, err)
|
|
claimed, err := svc.ClaimNext(context.Background(), "worker-test")
|
|
require.NoError(t, err)
|
|
require.Equal(t, j.ID, claimed.ID)
|
|
require.Equal(t, domain.StatusRunning, claimed.Status)
|
|
out, err := svc.RunDemoToSuccess(context.Background(), claimed.ID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, 100, out.ProgressPercent)
|
|
require.Equal(t, domain.StatusSucceeded, out.Status)
|
|
// cannot go backwards
|
|
err = domain.ApplyProgress(out, 50, "nope")
|
|
require.ErrorIs(t, err, domain.ErrIllegalStatus)
|
|
}
|
|
|
|
func TestJB_03_JobSucceeded(t *testing.T) {
|
|
svc, _ := newJobSvc()
|
|
j, _ := svc.StartDemo(context.Background(), 1_000_102)
|
|
_, _ = svc.ClaimNext(context.Background(), "w1")
|
|
out, err := svc.RunDemoToSuccess(context.Background(), j.ID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, domain.StatusSucceeded, out.Status)
|
|
require.True(t, out.CompletedAt > 0)
|
|
}
|
|
|
|
func TestJB_04_JobFailed(t *testing.T) {
|
|
svc, _ := newJobSvc()
|
|
j, _ := svc.StartDemo(context.Background(), 1_000_103)
|
|
_, _ = svc.ClaimNext(context.Background(), "w1")
|
|
out, err := svc.FailJob(context.Background(), j.ID, "boom")
|
|
require.NoError(t, err)
|
|
require.Equal(t, domain.StatusFailed, out.Status)
|
|
require.NotEmpty(t, out.Error)
|
|
require.True(t, out.CompletedAt > 0)
|
|
}
|
|
|
|
func TestJB_05_JobTerminalCreatesNotification(t *testing.T) {
|
|
svc, notif := newJobSvc()
|
|
uid := int64(1_000_104)
|
|
j, _ := svc.StartDemo(context.Background(), uid)
|
|
_, _ = svc.ClaimNext(context.Background(), "w1")
|
|
_, err := svc.RunDemoToSuccess(context.Background(), j.ID)
|
|
require.NoError(t, err)
|
|
list, err := notif.List(context.Background(), uid)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, list)
|
|
}
|
|
|
|
func TestJB_06_UnreadCount(t *testing.T) {
|
|
svc, notif := newJobSvc()
|
|
uid := int64(1_000_105)
|
|
j, _ := svc.StartDemo(context.Background(), uid)
|
|
_, _ = svc.ClaimNext(context.Background(), "w1")
|
|
_, _ = svc.FailJob(context.Background(), j.ID, "x")
|
|
c, err := notif.UnreadCount(context.Background(), uid)
|
|
require.NoError(t, err)
|
|
require.Equal(t, int64(1), c)
|
|
}
|
|
|
|
func TestJB_07_MarkRead(t *testing.T) {
|
|
svc, notif := newJobSvc()
|
|
uid := int64(1_000_106)
|
|
j, _ := svc.StartDemo(context.Background(), uid)
|
|
_, _ = svc.ClaimNext(context.Background(), "w1")
|
|
_, _ = svc.RunDemoToSuccess(context.Background(), j.ID)
|
|
list, _ := notif.List(context.Background(), uid)
|
|
require.NotEmpty(t, list)
|
|
require.NoError(t, notif.MarkRead(context.Background(), uid, list[0].ID))
|
|
c, _ := notif.UnreadCount(context.Background(), uid)
|
|
require.Equal(t, int64(0), c)
|
|
require.True(t, list[0].ReadAt == 0) // old snapshot
|
|
}
|
|
|
|
func TestJB_08_MarkAllRead(t *testing.T) {
|
|
svc, notif := newJobSvc()
|
|
uid := int64(1_000_107)
|
|
for i := 0; i < 2; i++ {
|
|
j, _ := svc.StartDemo(context.Background(), uid)
|
|
_, _ = svc.ClaimNext(context.Background(), "w1")
|
|
_, _ = svc.RunDemoToSuccess(context.Background(), j.ID)
|
|
}
|
|
c, _ := notif.UnreadCount(context.Background(), uid)
|
|
require.GreaterOrEqual(t, c, int64(2))
|
|
require.NoError(t, notif.MarkAllRead(context.Background(), uid))
|
|
c2, _ := notif.UnreadCount(context.Background(), uid)
|
|
require.Equal(t, int64(0), c2)
|
|
}
|
|
|
|
func TestJB_09_GetOtherUIDDenied(t *testing.T) {
|
|
svc, _ := newJobSvc()
|
|
j, _ := svc.StartDemo(context.Background(), 1_000_108)
|
|
_, err := svc.Get(context.Background(), 1_000_109, j.ID)
|
|
require.ErrorIs(t, err, domain.ErrForbidden)
|
|
}
|
|
|
|
func TestJB_10_GuardedReject(t *testing.T) {
|
|
svc, _ := newJobSvc()
|
|
j, _ := svc.StartDemo(context.Background(), 1_000_110)
|
|
_, _ = svc.ClaimNext(context.Background(), "w1")
|
|
_, _ = svc.RunDemoToSuccess(context.Background(), j.ID)
|
|
_, err := svc.Transition(context.Background(), j.ID, domain.StatusRunning, "nope", 10)
|
|
require.ErrorIs(t, err, domain.ErrIllegalStatus)
|
|
}
|
|
|
|
func TestJB_11_ManualDeleteTerminal(t *testing.T) {
|
|
svc, _ := newJobSvc()
|
|
uid := int64(1_000_111)
|
|
j, _ := svc.StartDemo(context.Background(), uid)
|
|
_, _ = svc.ClaimNext(context.Background(), "w1")
|
|
out, err := svc.RunDemoToSuccess(context.Background(), j.ID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, domain.StatusSucceeded, out.Status)
|
|
|
|
require.NoError(t, svc.Delete(context.Background(), uid, j.ID))
|
|
_, err = svc.Get(context.Background(), uid, j.ID)
|
|
require.ErrorIs(t, err, domain.ErrNotFound)
|
|
}
|
|
|
|
func TestJB_12_DeleteRunningRefused(t *testing.T) {
|
|
svc, _ := newJobSvc()
|
|
uid := int64(1_000_112)
|
|
j, _ := svc.StartDemo(context.Background(), uid)
|
|
claimed, err := svc.ClaimNext(context.Background(), "w1")
|
|
require.NoError(t, err)
|
|
require.Equal(t, domain.StatusRunning, claimed.Status)
|
|
err = svc.Delete(context.Background(), uid, j.ID)
|
|
require.ErrorIs(t, err, domain.ErrIllegalStatus)
|
|
}
|
|
|
|
func TestJB_13_PurgeExpiredTerminal(t *testing.T) {
|
|
svc, _ := newJobSvc()
|
|
uid := int64(1_000_113)
|
|
j, _ := svc.StartDemo(context.Background(), uid)
|
|
_, _ = svc.ClaimNext(context.Background(), "w1")
|
|
out, err := svc.RunDemoToSuccess(context.Background(), j.ID)
|
|
require.NoError(t, err)
|
|
|
|
// 模擬完成時間在 2 天前
|
|
out.CompletedAt = domain.NowNano() - domain.TerminalRetentionNs - 1
|
|
out.UpdatedAt = out.CompletedAt
|
|
require.NoError(t, svc.Repo.Update(context.Background(), out))
|
|
|
|
n, err := svc.PurgeExpiredTerminal(context.Background())
|
|
require.NoError(t, err)
|
|
require.Equal(t, int64(1), n)
|
|
_, err = svc.Get(context.Background(), uid, j.ID)
|
|
require.ErrorIs(t, err, domain.ErrNotFound)
|
|
}
|
|
|
|
func TestJB_14_PurgeKeepsRecentTerminal(t *testing.T) {
|
|
svc, _ := newJobSvc()
|
|
uid := int64(1_000_114)
|
|
j, _ := svc.StartDemo(context.Background(), uid)
|
|
_, _ = svc.ClaimNext(context.Background(), "w1")
|
|
_, err := svc.RunDemoToSuccess(context.Background(), j.ID)
|
|
require.NoError(t, err)
|
|
|
|
n, err := svc.PurgeExpiredTerminal(context.Background())
|
|
require.NoError(t, err)
|
|
require.Equal(t, int64(0), n)
|
|
got, err := svc.Get(context.Background(), uid, j.ID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, j.ID, got.ID)
|
|
}
|
|
|
|
func TestJB_15_SchedulePersonaAnalyzeAccount(t *testing.T) {
|
|
svc, _ := newJobSvc()
|
|
uid := int64(1_000_115)
|
|
j, err := svc.SchedulePersonaAnalyzeAccount(context.Background(), uid, "pe_abc", "ultralab_tw", "zh-TW")
|
|
require.NoError(t, err)
|
|
require.Equal(t, domain.TemplatePersonaAnalyzeAccount, j.TemplateType)
|
|
require.Equal(t, domain.StatusQueued, j.Status)
|
|
require.Equal(t, "pe_abc", j.RefID)
|
|
require.Contains(t, j.Payload, "ultralab_tw")
|
|
require.Contains(t, j.ProgressSummary, "@ultralab_tw")
|
|
|
|
// re-schedule cancels previous pending
|
|
j2, err := svc.SchedulePersonaAnalyzeAccount(context.Background(), uid, "pe_abc", "other", "en")
|
|
require.NoError(t, err)
|
|
require.NotEqual(t, j.ID, j2.ID)
|
|
old, err := svc.Get(context.Background(), uid, j.ID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, domain.StatusCancelled, old.Status)
|
|
|
|
claimed, err := svc.ClaimNext(context.Background(), "w1")
|
|
require.NoError(t, err)
|
|
require.Equal(t, j2.ID, claimed.ID)
|
|
require.Equal(t, domain.StatusRunning, claimed.Status)
|
|
}
|
|
|
|
func TestJB_16_SchedulePersonaAnalyzeText(t *testing.T) {
|
|
svc, _ := newJobSvc()
|
|
uid := int64(1_000_116)
|
|
j, err := svc.SchedulePersonaAnalyzeText(context.Background(), uid, "pe_txt", "hello world\n---\nsecond sample text here", "手動", "zh-TW")
|
|
require.NoError(t, err)
|
|
require.Equal(t, domain.TemplatePersonaAnalyzeText, j.TemplateType)
|
|
require.Equal(t, "pe_txt", j.RefID)
|
|
require.Contains(t, j.Payload, "raw_text")
|
|
}
|