feat: Complete hybrid image upload system with URL compatibility #8
@@ -167,25 +167,22 @@ class Event < ApplicationRecord
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check if event has any image (uploaded or URL)
|
# Check if event has any image (old field, attached, or URL)
|
||||||
def has_image?
|
def has_image?
|
||||||
image.attached? || image_url.present?
|
self[:image].present? || image.attached? || image_url.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get display image source (uploaded or URL)
|
# Get display image source (uploaded or URL)
|
||||||
def display_image
|
def display_image
|
||||||
if image.attached?
|
if image.attached?
|
||||||
image
|
image
|
||||||
else
|
elsif image_url.present?
|
||||||
image_url
|
image_url
|
||||||
|
else
|
||||||
|
self[:image]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check if event has any image (old field or attached)
|
|
||||||
def has_image?
|
|
||||||
self[:image].present? || image.attached?
|
|
||||||
end
|
|
||||||
|
|
||||||
# Check if coordinates were successfully geocoded or are fallback coordinates
|
# Check if coordinates were successfully geocoded or are fallback coordinates
|
||||||
def geocoding_successful?
|
def geocoding_successful?
|
||||||
coordinates_look_valid?
|
coordinates_look_valid?
|
||||||
|
|||||||
@@ -317,4 +317,157 @@ class EventTest < ActiveSupport::TestCase
|
|||||||
# Check that ticket types were NOT duplicated
|
# Check that ticket types were NOT duplicated
|
||||||
assert_equal 0, duplicated_event.ticket_types.count
|
assert_equal 0, duplicated_event.ticket_types.count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Test slug generation functionality
|
||||||
|
test "should generate slug from name and venue" do
|
||||||
|
user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123")
|
||||||
|
event = Event.new(
|
||||||
|
name: "Soirée d'ouverture",
|
||||||
|
description: "Valid description for the event that is long enough",
|
||||||
|
venue_name: "Test Venue",
|
||||||
|
venue_address: "123 Test Street",
|
||||||
|
user: user,
|
||||||
|
latitude: 48.0,
|
||||||
|
longitude: 2.0
|
||||||
|
)
|
||||||
|
event.save
|
||||||
|
assert_equal "soiree-d-ouverture-test-venue", event.slug
|
||||||
|
end
|
||||||
|
|
||||||
|
test "should generate slug from name, venue, and city" do
|
||||||
|
user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123")
|
||||||
|
event = Event.new(
|
||||||
|
name: "Fête de la Musique",
|
||||||
|
venue_name: "Théâtre Principal",
|
||||||
|
venue_address: "15 Rue de la Paix, 75002 Paris",
|
||||||
|
description: "Valid description for the event that is long enough",
|
||||||
|
user: user,
|
||||||
|
latitude: 48.0,
|
||||||
|
longitude: 2.0
|
||||||
|
)
|
||||||
|
event.save
|
||||||
|
assert_equal "fete-de-la-musique-theatre-principal-paris", event.slug
|
||||||
|
end
|
||||||
|
|
||||||
|
test "should generate fallback slug when no data available" do
|
||||||
|
user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123")
|
||||||
|
event = Event.new(
|
||||||
|
description: "Valid description for the event that is long enough",
|
||||||
|
venue_address: "123 Test Street",
|
||||||
|
user: user,
|
||||||
|
latitude: 48.0,
|
||||||
|
longitude: 2.0
|
||||||
|
)
|
||||||
|
event.save
|
||||||
|
assert_match /^event-\d+$/, event.slug
|
||||||
|
end
|
||||||
|
|
||||||
|
test "should ensure slug uniqueness" do
|
||||||
|
user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123")
|
||||||
|
|
||||||
|
# Create first event
|
||||||
|
event1 = Event.create!(
|
||||||
|
name: "Test Event",
|
||||||
|
venue_name: "Venue",
|
||||||
|
venue_address: "123 Test Street",
|
||||||
|
description: "Valid description for the event that is long enough",
|
||||||
|
user: user,
|
||||||
|
latitude: 48.0,
|
||||||
|
longitude: 2.0
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create second event with same details
|
||||||
|
event2 = Event.create!(
|
||||||
|
name: "Test Event",
|
||||||
|
venue_name: "Venue",
|
||||||
|
venue_address: "123 Test Street",
|
||||||
|
description: "Valid description for the event that is long enough",
|
||||||
|
user: user,
|
||||||
|
latitude: 48.0,
|
||||||
|
longitude: 2.0
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_not_equal event1.slug, event2.slug
|
||||||
|
assert_match /^test-event-venue-1$/, event2.slug
|
||||||
|
end
|
||||||
|
|
||||||
|
test "should extract city from French postal code" do
|
||||||
|
user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123")
|
||||||
|
event = Event.new(
|
||||||
|
name: "Concert",
|
||||||
|
venue_address: "5 Avenue des Champs-Élysées, 75008 Paris",
|
||||||
|
description: "Valid description for the event that is long enough",
|
||||||
|
user: user,
|
||||||
|
latitude: 48.0,
|
||||||
|
longitude: 2.0
|
||||||
|
)
|
||||||
|
event.save
|
||||||
|
assert event.slug.include?("paris")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Test image URL functionality
|
||||||
|
test "should accept valid image URL" do
|
||||||
|
user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123")
|
||||||
|
event = Event.new(
|
||||||
|
name: "Event with URL Image",
|
||||||
|
slug: "event-url-image",
|
||||||
|
description: "Valid description for the event that is long enough",
|
||||||
|
venue_name: "Venue",
|
||||||
|
venue_address: "123 Test Street",
|
||||||
|
user: user,
|
||||||
|
latitude: 48.0,
|
||||||
|
longitude: 2.0,
|
||||||
|
image_url: "https://example.com/image.jpg"
|
||||||
|
)
|
||||||
|
assert event.valid?
|
||||||
|
end
|
||||||
|
|
||||||
|
test "should reject invalid image URL" do
|
||||||
|
user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123")
|
||||||
|
event = Event.new(
|
||||||
|
name: "Event with Invalid URL",
|
||||||
|
slug: "event-invalid-url",
|
||||||
|
description: "Valid description for the event that is long enough",
|
||||||
|
venue_name: "Venue",
|
||||||
|
venue_address: "123 Test Street",
|
||||||
|
user: user,
|
||||||
|
latitude: 48.0,
|
||||||
|
longitude: 2.0,
|
||||||
|
image_url: "not-a-valid-url"
|
||||||
|
)
|
||||||
|
assert_not event.valid?
|
||||||
|
assert_includes event.errors[:image_url], "doit être une URL valide vers une image (JPG, PNG, GIF, WebP)"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "should reject URL with non-image extension" do
|
||||||
|
user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123")
|
||||||
|
event = Event.new(
|
||||||
|
name: "Event with Non-image URL",
|
||||||
|
slug: "event-non-image-url",
|
||||||
|
description: "Valid description for the event that is long enough",
|
||||||
|
venue_name: "Venue",
|
||||||
|
venue_address: "123 Test Street",
|
||||||
|
user: user,
|
||||||
|
latitude: 48.0,
|
||||||
|
longitude: 2.0,
|
||||||
|
image_url: "https://example.com/document.pdf"
|
||||||
|
)
|
||||||
|
assert_not event.valid?
|
||||||
|
assert_includes event.errors[:image_url], "doit être une URL valide vers une image (JPG, PNG, GIF, WebP)"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "has_image? should return true for URL image" do
|
||||||
|
event = Event.new(image_url: "https://example.com/image.jpg")
|
||||||
|
assert event.has_image?
|
||||||
|
end
|
||||||
|
|
||||||
|
test "has_image? should return false without image" do
|
||||||
|
event = Event.new
|
||||||
|
assert_not event.has_image?
|
||||||
|
end
|
||||||
|
|
||||||
|
test "display_image should return image URL when no attached image" do
|
||||||
|
event = Event.new(image_url: "https://example.com/image.jpg")
|
||||||
|
assert_equal "https://example.com/image.jpg", event.display_image
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user