Files
kandev/apps/backend/internal/task/handlers/task_lifecycle_postcommit_test.go
T
Clément Fiere 01b0dedd6c fix: harden task archive lifecycle recovery (#3651)
Co-authored-by: Carlos Florencio <carlosmflorencio@gmail.com>
2026-09-14 16:34:25 +01:00

91 lines
2.4 KiB
Go

package handlers
import (
"context"
"errors"
"github.com/gin-gonic/gin"
"net/http"
"strings"
"testing"
"github.com/kandev/kandev/internal/task/models"
"github.com/kandev/kandev/internal/task/service"
"github.com/stretchr/testify/require"
)
type postCommitCleanupFailure struct {
err error
}
func (c *postCommitCleanupFailure) CleanupTaskResources(context.Context, string, bool) {}
func (c *postCommitCleanupFailure) PrepareTaskResourceCleanup(
context.Context,
string,
models.TaskResourceCleanupTrigger,
string,
bool,
) error {
return nil
}
func (c *postCommitCleanupFailure) StartPreparedTaskResourceCleanup(context.Context, string) error {
return c.err
}
func (c *postCommitCleanupFailure) CancelPreparedTaskResourceCleanup(context.Context, string) error {
return nil
}
func (r *authzDeleteRepo) ListStructuralChildrenLimited(context.Context, string, int) ([]*models.Task, error) {
return nil, nil
}
func (r *authzDeleteRepo) ReparentDirectChildrenInWorkspace(context.Context, string, string, string) error {
return nil
}
func (r *authzDeleteRepo) archivedTaskIDs() []string {
r.mu.Lock()
defer r.mu.Unlock()
ids := make([]string, 0, len(r.archived))
for _, archived := range r.archived {
if index := strings.IndexByte(archived, '/'); index >= 0 {
ids = append(ids, archived[:index])
} else {
ids = append(ids, archived)
}
}
return ids
}
func TestHTTPTaskLifecycleReturnsPendingAfterPostCommitHousekeepingFailure(t *testing.T) {
for _, tc := range []struct {
name string
call func(*TaskHandlers, *gin.Context)
want []string
}{
{name: "delete", call: (*TaskHandlers).httpDeleteTask, want: []string{"task-b"}},
{name: "archive", call: (*TaskHandlers).httpArchiveTask, want: []string{"task-b"}},
} {
t.Run(tc.name, func(t *testing.T) {
repo := &authzDeleteRepo{}
h := newAuthzTaskHandlers(t, repo)
handoff := service.NewHandoffService(repo, nil, nil, nil, nil, h.logger)
handoff.SetTaskResourceCleaner(&postCommitCleanupFailure{err: errors.New("cleanup unavailable")})
h.SetHandoffService(handoff)
c, rec := authzDeleteRequest(t, "user-b", "task-b")
tc.call(h, c)
require.Equal(t, http.StatusServiceUnavailable, rec.Code, rec.Body.String())
require.JSONEq(t, `{"success":false,"pending":true,"task_id":"task-b"}`, rec.Body.String())
if tc.name == "delete" {
require.Equal(t, tc.want, repo.deletes())
} else {
require.Equal(t, tc.want, repo.archivedTaskIDs())
}
})
}
}