package main import ( "fmt" "net/http" "net/http/httptest" "os" "path/filepath" "strings" "testing" "gitgud.io/mike/mpv-manager/pkg/releaseprovenance" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "lukechampine.com/blake3" ) func TestReviewedDownloadURLsPreserveDigestsAndManagerArtifacts(t *testing.T) { lock, err := releaseprovenance.Load("../../release/provenance-v1.3.0-rc.4.json", "1.3.0-rc.4") require.NoError(t, err) // Keep one reviewed source; other assets must remain untouched. lock.Artifacts = lock.Artifacts[:1] a := &lock.Artifacts[0] require.NotEmpty(t, a.DownloadURL) source := a.URL release := Release{Version: lock.ReleaseVersion} release.Windows.X8664.URL = source release.Windows.X8664.BLAKE3 = a.BLAKE3 release.Manager.WinX86_64.URL = "https://example.com/manager.exe" release.UOSC.URL = "https://example.com/uosc.zip" require.NoError(t, applyReviewedDownloadURLs(&release, lock)) assert.Equal(t, a.DownloadURL, release.Windows.X8664.URL) assert.Equal(t, a.BLAKE3, release.Windows.X8664.BLAKE3) assert.Equal(t, source, a.URL) assert.Equal(t, "https://example.com/manager.exe", release.Manager.WinX86_64.URL) assert.Equal(t, "https://example.com/uosc.zip", release.UOSC.URL) release.Windows.X8664.URL = source release.Windows.X8664.BLAKE3 = "different" require.ErrorContains(t, applyReviewedDownloadURLs(&release, lock), "digest differs") assert.Equal(t, source, release.Windows.X8664.URL) release.Windows.X8664.URL = "https://example.com/unreviewed.7z" require.ErrorContains(t, applyReviewedDownloadURLs(&release, lock), "unused reviewed") } func TestFreshProvenanceDownloadUsesReviewedMirrorAndRetainsOfflineCache(t *testing.T) { lock, err := releaseprovenance.Load("../../release/provenance-v1.3.0-rc.4.json", "1.3.0-rc.4") require.NoError(t, err) t.Chdir(t.TempDir()) originalLock, originalClient, originalAuto := activeProvenance, downloadClient, *autoMode originalUsed, originalFiles := usedProvenanceAssets, allUsedFiles t.Cleanup(func() { activeProvenance, downloadClient, *autoMode = originalLock, originalClient, originalAuto usedProvenanceAssets, allUsedFiles = originalUsed, originalFiles }) payload := []byte("reviewed upstream artifact") digest := fmt.Sprintf("blake3:%x", blake3.Sum256(payload)) var originRequests, mirrorRequests int server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/origin/app.zip" { originRequests++ _, _ = w.Write([]byte("upstream replaced these bytes")) return } mirrorRequests++ _, _ = w.Write(payload) })) defer server.Close() source := server.URL + "/origin/app.zip" lock.Artifacts = []releaseprovenance.Artifact{{ ID: "app.zip", URL: source, DownloadURL: server.URL + "/" + strings.TrimPrefix(digest, "blake3:") + "/app.zip", BLAKE3: digest, Verification: "TLS fixture bytes independently hashed", Evidence: "local TLS fixture", }} require.NoError(t, lock.Validate(lock.ReleaseVersion)) activeProvenance = lock downloadClient, *autoMode = server.Client(), true usedProvenanceAssets = make(map[string]bool) got, err := computeHashForURL("test", source, "") require.NoError(t, err) assert.Equal(t, digest, got) assert.Equal(t, 0, originRequests) assert.Equal(t, 1, mirrorRequests) assert.True(t, usedProvenanceAssets[source]) assert.Equal(t, source, getCachedURL(filepath.Join(releaseFilesDir, "app.zip"))) // The transport choice must not invalidate a reviewed offline cache. server.Close() got, err = computeHashForURL("test", source, "") require.NoError(t, err) assert.Equal(t, digest, got) // A correct URL/cache sidecar never substitutes for digest verification. require.NoError(t, os.WriteFile(filepath.Join(releaseFilesDir, "app.zip"), []byte("tampered"), 0644)) _, err = computeHashForURL("test", source, "") require.ErrorContains(t, err, "does not match reviewed digest") }