package mountain_pass import ( "crypto/md5" "encoding/hex" "net/http" "net/http/httptest" "os" "path/filepath" "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // osmd5Hex mirrors the production helper in the test so the expected checksum // served by the fake geofabrik server is derived independently of pbfMD5. func osmd5Hex(data []byte) string { sum := md5.Sum(data) return hex.EncodeToString(sum[:]) } // fakeGeofabrik serves a PBF payload and an optional .md5 sibling. func fakeGeofabrik(t *testing.T, pbf []byte, md5Body string) *httptest.Server { t.Helper() mux := http.NewServeMux() mux.HandleFunc("/france-latest.osm.pbf", func(w http.ResponseWriter, r *http.Request) { w.Write(pbf) }) mux.HandleFunc("/france-latest.osm.pbf.md5", func(w http.ResponseWriter, r *http.Request) { if md5Body == "" { http.Error(w, "not found", http.StatusNotFound) return } w.Write([]byte(md5Body)) }) srv := httptest.NewServer(mux) t.Cleanup(srv.Close) return srv } func TestFetchFrancePBFDownloadsAndVerifies(t *testing.T) { pbf := []byte("some-valid-pbf-content-1") srv := fakeGeofabrik(t, pbf, osmd5Hex(pbf)+" france-latest.osm.pbf\n") dest := filepath.Join(t.TempDir(), "france-latest.osm.pbf") err := fetchFrancePBF(srv.Client(), srv.URL+"/france-latest.osm.pbf", dest) require.NoError(t, err) got, err := os.ReadFile(dest) require.NoError(t, err) assert.Equal(t, pbf, got) } func TestFetchFrancePBFMismatchRetainsFile(t *testing.T) { pbf := []byte("some-valid-pbf-content-2") srv := fakeGeofabrik(t, pbf, strings.Repeat("0", 32)+" france-latest.osm.pbf\n") dest := filepath.Join(t.TempDir(), "france-latest.osm.pbf") err := fetchFrancePBF(srv.Client(), srv.URL+"/france-latest.osm.pbf", dest) require.Error(t, err) assert.Contains(t, err.Error(), "checksum mismatch") // The corrupt file is kept for inspection, not deleted. got, readErr := os.ReadFile(dest) require.NoError(t, readErr) assert.Equal(t, pbf, got) } func TestFetchFrancePBFAlreadyCompleteVerified(t *testing.T) { pbf := []byte("some-valid-pbf-content-3") srv := fakeGeofabrik(t, pbf, osmd5Hex(pbf)+" france-latest.osm.pbf\n") dest := filepath.Join(t.TempDir(), "france-latest.osm.pbf") require.NoError(t, os.WriteFile(dest, pbf, 0o644)) err := fetchFrancePBF(srv.Client(), srv.URL+"/france-latest.osm.pbf", dest) require.NoError(t, err) got, _ := os.ReadFile(dest) assert.Equal(t, pbf, got) } func TestFetchFrancePBFAlreadyCompleteCorrupt(t *testing.T) { pbf := []byte("the-real-content") corrupt := []byte(strings.Repeat("x", len(pbf))) require.Equal(t, len(pbf), len(corrupt), "same length to prove size-only check is not enough") srv := fakeGeofabrik(t, pbf, osmd5Hex(pbf)+" france-latest.osm.pbf\n") dest := filepath.Join(t.TempDir(), "france-latest.osm.pbf") require.NoError(t, os.WriteFile(dest, corrupt, 0o644)) err := fetchFrancePBF(srv.Client(), srv.URL+"/france-latest.osm.pbf", dest) require.Error(t, err) assert.Contains(t, err.Error(), "checksum mismatch") got, _ := os.ReadFile(dest) assert.Equal(t, corrupt, got, "corrupt file retained for inspection") } func TestFetchFrancePBFSkipsVerificationWhenChecksumUnreachable(t *testing.T) { pbf := []byte("some-valid-pbf-content-4") srv := fakeGeofabrik(t, pbf, "") // md5 endpoint returns 404 dest := filepath.Join(t.TempDir(), "france-latest.osm.pbf") err := fetchFrancePBF(srv.Client(), srv.URL+"/france-latest.osm.pbf", dest) require.NoError(t, err) got, _ := os.ReadFile(dest) assert.Equal(t, pbf, got) } func TestPBFMD5(t *testing.T) { data := []byte("known-content-for-md5-test") expected := osmd5Hex(data) path := filepath.Join(t.TempDir(), "sample.bin") require.NoError(t, os.WriteFile(path, data, 0o644)) got, err := pbfMD5(path) require.NoError(t, err) assert.Equal(t, expected, got) }