package pf import ( "strings" "testing" ) func strPtr(v string) *string { return &v } func int64Ptr(v int64) *int64 { return &v } func float64Ptr(v float64) *float64 { return &v } func validProjectPayload() ProjectPayload { return ProjectPayload{ Title: "Full Park View", DealType: "sale", OurPrice: float64Ptr(2500000), DLDPermit: strPtr("7140504127"), Building: strPtr("Harbour Gate Tower 2"), Bedrooms: int64Ptr(2), SizeSqft: float64Ptr(1081), OurURL: strPtr( "https://www.propertyfinder.ae/en/plp/buy/apartment-for-sale-dubai-dubai-creek-harbour-the-lagoons-harbour-gate-harbour-gate-tower-2-86176216.html", ), } } func TestValidateProjectRequiredAcceptsConcretePropertyFinderListingURL(t *testing.T) { payload := validProjectPayload() if err := validateProjectRequired(payload); err != nil { t.Fatalf("validateProjectRequired() returned unexpected error: %v", err) } } func TestValidateProjectRequiredRejectsSearchPageAsOurURL(t *testing.T) { payload := validProjectPayload() payload.OurURL = strPtr("https://www.propertyfinder.ae/en/search?c=1&l=12345") err := validateProjectRequired(payload) if err == nil { t.Fatal("validateProjectRequired() accepted a search page as our_url") } if !strings.Contains(err.Error(), "concrete PropertyFinder listing URL") { t.Fatalf("unexpected error: %v", err) } } func TestValidateProjectRequiredRejectsListingLikeURLWithoutID(t *testing.T) { payload := validProjectPayload() payload.OurURL = strPtr("https://www.propertyfinder.ae/en/plp/buy/apartment-for-sale-dubai-dubai-creek-harbour.html") err := validateProjectRequired(payload) if err == nil { t.Fatal("validateProjectRequired() accepted a listing-like URL without listing id") } if !strings.Contains(err.Error(), "concrete PropertyFinder listing URL") { t.Fatalf("unexpected error: %v", err) } } func TestApplyParsedOwnListingFillsProjectMetadata(t *testing.T) { payload := ProjectPayload{ Title: "Full Park View", DealType: "sale", OurURL: strPtr( "https://www.propertyfinder.ae/en/plp/buy/apartment-for-sale-dubai-dubai-creek-harbour-the-lagoons-harbour-gate-harbour-gate-tower-2-86176216.html", ), } parsed := &ParsedOwnListing{ OurPrice: float64Ptr(3500000), DLDPermit: strPtr("7140504127"), Building: strPtr("Harbour Gate Tower 2"), Bedrooms: int64Ptr(2), SizeSqft: float64Ptr(1081), } payload = applyParsedOwnListing(payload, parsed) if err := validateProjectRequired(payload); err != nil { t.Fatalf("validateProjectRequired() after parsed metadata returned error: %v", err) } if payload.OurPrice == nil || *payload.OurPrice != 3500000 { t.Fatalf("our_price was not applied: %#v", payload.OurPrice) } if payload.DLDPermit == nil || *payload.DLDPermit != "7140504127" { t.Fatalf("dld_permit was not applied: %#v", payload.DLDPermit) } if payload.Building == nil || *payload.Building != "Harbour Gate Tower 2" { t.Fatalf("building was not applied: %#v", payload.Building) } if payload.Bedrooms == nil || *payload.Bedrooms != 2 { t.Fatalf("bedrooms was not applied: %#v", payload.Bedrooms) } if payload.SizeSqft == nil || *payload.SizeSqft != 1081 { t.Fatalf("size_sqft was not applied: %#v", payload.SizeSqft) } }