package verification import ( "os" "path/filepath" "testing" protobundle "github.com/sigstore/protobuf-specs/gen/pb-go/bundle/v1" dsse "github.com/sigstore/protobuf-specs/gen/pb-go/dsse" "github.com/sigstore/sigstore-go/pkg/bundle" "github.com/stretchr/testify/require" "github.com/cli/cli/v2/pkg/cmd/attestation/api" ) func TestLoadBundlesFromJSONLinesFile(t *testing.T) { t.Run("with original file", func(t *testing.T) { path := "../test/data/sigstore-js-2.1.0_with_2_bundles.jsonl" attestations, err := loadBundlesFromJSONLinesFile(path) require.NoError(t, err) require.Len(t, attestations, 2) }) t.Run("with extra lines", func(t *testing.T) { // Create a temporary file with extra lines tempDir := t.TempDir() tempFile := filepath.Join(tempDir, "test_with_extra_lines.jsonl") originalContent, err := os.ReadFile("../test/data/sigstore-js-2.1.0_with_2_bundles.jsonl") require.NoError(t, err) extraLines := []byte("\n\n") newContent := append(originalContent, extraLines...) err = os.WriteFile(tempFile, newContent, 0644) require.NoError(t, err) // Test the function with the new file attestations, err := loadBundlesFromJSONLinesFile(tempFile) require.NoError(t, err) require.Len(t, attestations, 2, "Should still load 2 valid attestations") }) } func TestLoadBundlesFromJSONLinesFile_RejectEmptyJSONLFile(t *testing.T) { // Create a temporary file emptyJSONL, err := os.CreateTemp("", "empty.jsonl") require.NoError(t, err) err = emptyJSONL.Close() require.NoError(t, err) attestations, err := loadBundlesFromJSONLinesFile(emptyJSONL.Name()) require.ErrorIs(t, err, ErrEmptyBundleFile) require.Nil(t, attestations) } func TestLoadBundleFromJSONFile(t *testing.T) { path := "../test/data/sigstore-js-2.1.0-bundle.json" attestations, err := loadBundleFromJSONFile(path) require.NoError(t, err) require.Len(t, attestations, 1) } func TestGetLocalAttestations(t *testing.T) { t.Run("with JSON file containing one bundle", func(t *testing.T) { path := "../test/data/sigstore-js-2.1.0-bundle.json" attestations, err := GetLocalAttestations(path) require.NoError(t, err) require.Len(t, attestations, 1) }) t.Run("with JSON lines file containing multiple bundles", func(t *testing.T) { path := "../test/data/sigstore-js-2.1.0_with_2_bundles.jsonl" attestations, err := GetLocalAttestations(path) require.NoError(t, err) require.Len(t, attestations, 2) }) t.Run("with file with unrecognized extension", func(t *testing.T) { path := "../test/data/sigstore-js-2.1.0-bundles.tgz" attestations, err := GetLocalAttestations(path) require.ErrorIs(t, err, ErrUnrecognisedBundleExtension) require.Nil(t, attestations) }) t.Run("with non-existent bundle file and JSON file", func(t *testing.T) { path := "../test/data/not-found-bundle.json" attestations, err := GetLocalAttestations(path) require.ErrorContains(t, err, "could not load content from file path") require.Nil(t, attestations) }) t.Run("with non-existent bundle file and JSON lines file", func(t *testing.T) { path := "../test/data/not-found-bundle.jsonl" attestations, err := GetLocalAttestations(path) require.ErrorContains(t, err, "could not load content from file path") require.Nil(t, attestations) }) t.Run("with missing verification material", func(t *testing.T) { path := "../test/data/github_provenance_demo-0.0.12-py3-none-any-bundle-missing-verification-material.jsonl" _, err := GetLocalAttestations(path) require.ErrorIs(t, err, bundle.ErrMissingVerificationMaterial) }) t.Run("with missing verification certificate", func(t *testing.T) { path := "../test/data/github_provenance_demo-0.0.12-py3-none-any-bundle-missing-cert.jsonl" _, err := GetLocalAttestations(path) require.ErrorIs(t, err, bundle.ErrMissingBundleContent) }) } func TestFilterAttestations(t *testing.T) { attestations := []*api.Attestation{ { Bundle: &bundle.Bundle{ Bundle: &protobundle.Bundle{ Content: &protobundle.Bundle_DsseEnvelope{ DsseEnvelope: &dsse.Envelope{ PayloadType: "application/vnd.in-toto+json", Payload: []byte("{\"predicateType\": \"https://slsa.dev/provenance/v1\"}"), }, }, }, }, }, { Bundle: &bundle.Bundle{ Bundle: &protobundle.Bundle{ Content: &protobundle.Bundle_DsseEnvelope{ DsseEnvelope: &dsse.Envelope{ PayloadType: "application/vnd.something-other-than-in-toto+json", Payload: []byte("{\"predicateType\": \"https://slsa.dev/provenance/v1\"}"), }, }, }, }, }, { Bundle: &bundle.Bundle{ Bundle: &protobundle.Bundle{ Content: &protobundle.Bundle_DsseEnvelope{ DsseEnvelope: &dsse.Envelope{ PayloadType: "application/vnd.in-toto+json", Payload: []byte("{\"predicateType\": \"https://spdx.dev/Document/v2.3\"}"), }, }, }, }, }, } filtered, err := api.FilterAttestations("https://slsa.dev/provenance/v1", attestations) require.Len(t, filtered, 1) require.NoError(t, err) filtered, err = api.FilterAttestations("NonExistentPredicate", attestations) require.Nil(t, filtered) require.Error(t, err) }