package api import ( "archive/tar" "bytes" "net/http/httptest" "os" "path/filepath" "testing" "time" ) func TestGenerateAndCheckETag(t *testing.T) { etag := generateETag(map[string]interface{}{"a": 1}) if etag == "" { t.Fatal("expected non-empty etag") } req := httptest.NewRequest("GET", "/x", nil) req.Header.Set("If-None-Match", etag) if !checkETag(req, etag) { t.Fatal("expected etag match") } } func TestUploadSessionPhase(t *testing.T) { if got := uploadSessionPhase("uploading"); got != "upload" { t.Fatalf("unexpected phase: %q", got) } if got := uploadSessionPhase("select_blend"); got != "action_required" { t.Fatalf("unexpected phase: %q", got) } if got := uploadSessionPhase("something_else"); got != "processing" { t.Fatalf("unexpected fallback phase: %q", got) } } func TestParseTarHeader_AndTruncateString(t *testing.T) { var buf bytes.Buffer tw := tar.NewWriter(&buf) _ = tw.WriteHeader(&tar.Header{Name: "a.txt", Mode: 0644, Size: 3, Typeflag: tar.TypeReg}) _, _ = tw.Write([]byte("abc")) _ = tw.Close() raw := buf.Bytes() if len(raw) < 512 { t.Fatal("tar buffer unexpectedly small") } var h tar.Header if err := parseTarHeader(raw[:512], &h); err != nil { t.Fatalf("parseTarHeader failed: %v", err) } if h.Name != "a.txt" { t.Fatalf("unexpected parsed name: %q", h.Name) } if got := truncateString("abcdef", 5); got != "ab..." { t.Fatalf("truncateString = %q, want %q", got, "ab...") } } func TestValidateUploadSessionForJobCreation_MissingSession(t *testing.T) { s := &Manager{ uploadSessions: map[string]*UploadSession{}, } _, _, err := s.validateUploadSessionForJobCreation("missing", 1) if err == nil { t.Fatal("expected validation error for missing session") } sessionErr, ok := err.(*uploadSessionValidationError) if !ok || sessionErr.Code != uploadSessionExpiredCode { t.Fatalf("expected %s validation error, got %#v", uploadSessionExpiredCode, err) } } func TestValidateUploadSessionForJobCreation_ContextMissing(t *testing.T) { tmpDir := t.TempDir() s := &Manager{ uploadSessions: map[string]*UploadSession{ "s1": { SessionID: "s1", UserID: 9, TempDir: tmpDir, Status: "completed", CreatedAt: time.Now(), }, }, } if _, _, err := s.validateUploadSessionForJobCreation("s1", 9); err == nil { t.Fatal("expected error when context.tar is missing") } } func TestValidateUploadSessionForJobCreation_NotReady(t *testing.T) { tmpDir := t.TempDir() s := &Manager{ uploadSessions: map[string]*UploadSession{ "s1": { SessionID: "s1", UserID: 9, TempDir: tmpDir, Status: "processing", CreatedAt: time.Now(), }, }, } _, _, err := s.validateUploadSessionForJobCreation("s1", 9) if err == nil { t.Fatal("expected error for session that is not completed") } sessionErr, ok := err.(*uploadSessionValidationError) if !ok || sessionErr.Code != uploadSessionNotReadyCode { t.Fatalf("expected %s validation error, got %#v", uploadSessionNotReadyCode, err) } } func TestValidateUploadSessionForJobCreation_Success(t *testing.T) { tmpDir := t.TempDir() contextPath := filepath.Join(tmpDir, "context.tar") if err := os.WriteFile(contextPath, []byte("tar-bytes"), 0644); err != nil { t.Fatalf("write context.tar: %v", err) } s := &Manager{ uploadSessions: map[string]*UploadSession{ "s1": { SessionID: "s1", UserID: 9, TempDir: tmpDir, Status: "completed", CreatedAt: time.Now(), }, }, } session, gotPath, err := s.validateUploadSessionForJobCreation("s1", 9) if err != nil { t.Fatalf("expected valid session, got error: %v", err) } if session == nil || gotPath != contextPath { t.Fatalf("unexpected result: session=%v path=%q", session, gotPath) } }