package feeds import ( "errors" "os" "path/filepath" "strings" "testing" "github.com/google/uuid" ) func TestResolveCompanyPath(t *testing.T) { t.Parallel() base := t.TempDir() cid := uuid.New() rel := cid.String() + "/sample.csv" absWant := filepath.Join(base, filepath.FromSlash(rel)) if err := os.MkdirAll(filepath.Dir(absWant), 0o750); err != nil { t.Fatal(err) } if err := os.WriteFile(absWant, []byte("a,b\n1,2\n"), 0o640); err != nil { t.Fatal(err) } got, err := resolveCompanyPath(base, cid, rel) if err != nil { t.Fatalf("resolve: %v", err) } if filepath.Clean(got) != filepath.Clean(absWant) { t.Fatalf("got %q want %q", got, absWant) } if _, err := resolveCompanyPath(base, cid, "../etc/passwd"); err == nil { t.Fatal("expected traversal reject") } other := uuid.New() if _, err := resolveCompanyPath(base, cid, other.String()+"/x.csv"); err == nil { t.Fatal("expected company mismatch reject") } } func TestReadLocalFeed(t *testing.T) { t.Parallel() base := t.TempDir() cid := uuid.New() rel := cid.String() + "/products.csv" abs := filepath.Join(base, filepath.FromSlash(rel)) if err := os.MkdirAll(filepath.Dir(abs), 0o750); err != nil { t.Fatal(err) } payload := []byte("ean,title\n123,Widget\n") if err := os.WriteFile(abs, payload, 0o640); err != nil { t.Fatal(err) } svc := &Service{UploadDir: base} blob, err := svc.readLocalFeed(cid, rel) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = blob.Close() }) if blob.contentType != "text/csv" { t.Fatalf("content-type %q", blob.contentType) } data, err := os.ReadFile(blob.path) if err != nil { t.Fatal(err) } if string(data) != string(payload) { t.Fatalf("payload mismatch") } if blob.owned { t.Fatal("local feed must not own path") } } func TestReadLocalFeedRejectsOversized(t *testing.T) { t.Parallel() old := maxDownloadBytes maxDownloadBytes = 32 t.Cleanup(func() { maxDownloadBytes = old }) base := t.TempDir() cid := uuid.New() rel := cid.String() + "/big.csv" abs := filepath.Join(base, filepath.FromSlash(rel)) if err := os.MkdirAll(filepath.Dir(abs), 0o750); err != nil { t.Fatal(err) } if err := os.WriteFile(abs, []byte(strings.Repeat("x", 40)), 0o640); err != nil { t.Fatal(err) } svc := &Service{UploadDir: base} _, err := svc.readLocalFeed(cid, rel) if !errors.Is(err, errDownloadTooLarge) { t.Fatalf("err=%v want errDownloadTooLarge", err) } } func TestSourcePathFromOptions(t *testing.T) { t.Parallel() if p := sourcePathFromOptions(map[string]any{"source_path": " a/b.csv "}); p != "a/b.csv" { t.Fatalf("got %q", p) } if p := sourcePathFromOptions(nil); p != "" { t.Fatalf("got %q", p) } }