require "test_helper" require "timecop" class EventTest < ActiveSupport::TestCase # Test that Event model exists test "should be a class" do assert_kind_of Class, Event end # Test validations test "should not save event without name" do event = Event.new(description: "Test event description") assert_not event.save end test "should not save event without description" do event = Event.new(name: "Test Event") assert_not event.save end test "should not save event with name less than 3 characters" do event = Event.new(name: "AB", description: "Valid description for the event") assert_not event.save end test "should not save event with description less than 10 characters" do event = Event.new(name: "Valid Event Name", description: "Too short") assert_not event.save end test "should not save event without latitude" do event = Event.new( name: "Valid Event Name", description: "Valid description for the event that is long enough", longitude: 2.3522 ) assert_not event.save end test "should not save event without longitude" do event = Event.new( name: "Valid Event Name", description: "Valid description for the event that is long enough", latitude: 48.8566 ) assert_not event.save end test "should not save event with invalid latitude" do event = Event.new( name: "Valid Event Name", description: "Valid description for the event that is long enough", latitude: 95.0, longitude: 2.3522, venue_name: "Test Venue", venue_address: "123 Test Street" ) assert_not event.save end test "should not save event with invalid longitude" do event = Event.new( name: "Valid Event Name", description: "Valid description for the event that is long enough", latitude: 48.8566, longitude: 190.0, venue_name: "Test Venue", venue_address: "123 Test Street" ) assert_not event.save end test "should not save event without slug" do event = Event.new( name: "Valid Event Name", description: "Valid description for the event that is long enough", latitude: 48.8566, longitude: 2.3522, venue_name: "Test Venue", venue_address: "123 Test Street" ) assert_not event.save end test "should not save event with slug less than 3 characters" do event = Event.new( name: "Valid Event Name", description: "Valid description for the event that is long enough", latitude: 48.8566, longitude: 2.3522, venue_name: "Test Venue", venue_address: "123 Test Street", slug: "ab" ) assert_not event.save end test "should save valid event" do user = User.create!( email: "test@example.com", password: "password123", password_confirmation: "password123" ) event = Event.new( name: "Valid Event Name", slug: "valid-event-name", description: "Valid description for the event that is long enough", latitude: 48.8566, longitude: 2.3522, venue_name: "Test Venue", venue_address: "123 Test Street", user: user, ) assert event.save end # Test enum states test "should have valid states" do assert_equal %w[draft published canceled sold_out], Event.states.keys end test "should default to draft state" do event = Event.new( name: "Valid Event Name", description: "Valid description for the event that is long enough", latitude: 48.8566, longitude: 2.3522, venue_name: "Test Venue", venue_address: "123 Test Street" ) assert_equal "draft", event.state end # Test associations test "should belong to user" do association = Event.reflect_on_association(:user) assert_equal :belongs_to, association.macro end test "should have many ticket_types" do association = Event.reflect_on_association(:ticket_types) assert_equal :has_many, association.macro end test "should have many tickets through ticket_types" do association = Event.reflect_on_association(:tickets) assert_equal :has_many, association.macro assert_equal :ticket_types, association.options[:through] end # Test scopes test "should respond to featured scope" do assert_respond_to Event, :featured end test "should respond to published scope" do assert_respond_to Event, :published end test "should respond to search_by_name scope" do assert_respond_to Event, :search_by_name end test "upcoming scope should return only published future events" do user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123") future_published = Event.create!(name: "Future", slug: "future", description: "Valid description for the event", venue_name: "v", venue_address: "a", user: user, latitude: 48.0, longitude: 2.0, start_time: 1.day.from_now, state: :published) past_published = Event.create!(name: "Past", slug: "past", description: "Valid description for the event", venue_name: "v", venue_address: "a", user: user, latitude: 48.0, longitude: 2.0, start_time: 1.day.ago, state: :published) future_draft = Event.create!(name: "Draft", slug: "draft", description: "Valid description for the event", venue_name: "v", venue_address: "a", user: user, latitude: 48.0, longitude: 2.0, start_time: 1.day.from_now, state: :draft) upcoming = Event.upcoming assert_includes upcoming, future_published assert_not_includes upcoming, past_published assert_not_includes upcoming, future_draft end test "geocoding_successful? should return true for valid coordinates" do event = Event.new(latitude: 48.8566, longitude: 2.3522, name: "Test", slug: "test", description: "A description that is sufficiently long", venue_name: "v", venue_address: "a") assert event.geocoding_successful? end test "geocoding_successful? should return false for fallback coordinates" do event = Event.new(latitude: 46.603354, longitude: 1.888334, name: "Test", slug: "test", description: "Valid description for the event", venue_name: "v", venue_address: "a") assert_not event.geocoding_successful? end test "geocoding_status_message should return message when not successful" do event = Event.new(latitude: 46.603354, longitude: 1.888334, name: "Test", slug: "test", description: "Valid description for the event", venue_name: "v", venue_address: "a") assert_match(/coordonnées/, event.geocoding_status_message) end test "geocoding_status_message should return nil when successful" do event = Event.new(latitude: 48.8566, longitude: 2.3522, name: "Test", slug: "test", description: "Valid description for the event", venue_name: "v", venue_address: "a") assert_nil event.geocoding_status_message end test "booking_allowed? should be true for published future event" do user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123") event = Event.create!(name: "Test", slug: "test", description: "A description that is sufficiently long", venue_name: "v", venue_address: "a", user: user, latitude: 48.0, longitude: 2.0, start_time: 1.day.from_now, state: :published) assert event.booking_allowed? end test "booking_allowed? should be false for draft event" do user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123") event = Event.create!(name: "Test", slug: "test", description: "Valid description for the event", venue_name: "v", venue_address: "a", user: user, latitude: 48.0, longitude: 2.0, start_time: 1.day.from_now, state: :draft) assert_not event.booking_allowed? end test "booking_allowed? should be false for canceled event" do user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123") event = Event.create!(name: "Test", slug: "test", description: "Valid description for the event", venue_name: "v", venue_address: "a", user: user, latitude: 48.0, longitude: 2.0, start_time: 1.day.from_now, state: :canceled) assert_not event.booking_allowed? end test "booking_allowed? should be false for sold_out event" do user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123") event = Event.create!(name: "Test", slug: "test", description: "A description that is sufficiently long", venue_name: "v", venue_address: "a", user: user, latitude: 48.0, longitude: 2.0, start_time: 1.day.from_now, state: :sold_out) assert_not event.booking_allowed? end test "booking_allowed? should be false during event without allow_booking_during_event" do user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123") event = Event.create!(name: "Test", slug: "test", description: "Valid description for the event", venue_name: "v", venue_address: "a", user: user, latitude: 48.0, longitude: 2.0, start_time: 1.hour.ago, end_time: 2.hours.from_now, state: :published, allow_booking_during_event: false) assert_not event.booking_allowed? end test "booking_allowed? should be true during event with allow_booking_during_event" do user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123") event = Event.create!(name: "Test", slug: "test", description: "Valid description for the event", venue_name: "v", venue_address: "a", user: user, latitude: 48.0, longitude: 2.0, start_time: 1.hour.ago, end_time: 2.hours.from_now, state: :published, allow_booking_during_event: true) assert event.booking_allowed? end test "event_started? should be true after start_time" do Timecop.freeze(1.hour.from_now) do user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123") event = Event.create!(name: "Test", slug: "test", description: "A description that is sufficiently long", venue_name: "v", venue_address: "a", user: user, latitude: 48.0, longitude: 2.0, start_time: 1.hour.ago) assert event.event_started? end end test "event_started? should be false before start_time" do Timecop.freeze(1.hour.ago) do user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123") event = Event.create!(name: "Test", slug: "test", description: "Valid description for the event", venue_name: "v", venue_address: "a", user: user, latitude: 48.0, longitude: 2.0, start_time: 1.hour.from_now) assert_not event.event_started? end end test "event_ended? should be true after end_time" do Timecop.freeze(1.hour.from_now) do user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123") event = Event.create!(name: "Test", slug: "test", description: "Valid description for the event", venue_name: "v", venue_address: "a", user: user, latitude: 48.0, longitude: 2.0, start_time: 1.hour.ago, end_time: 30.minutes.ago) assert event.event_ended? end end test "event_ended? should be false before end_time" do Timecop.freeze(1.hour.ago) do user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123") event = Event.create!(name: "Test", slug: "test", description: "A description that is sufficiently long", venue_name: "v", venue_address: "a", user: user, latitude: 48.0, longitude: 2.0, start_time: 1.hour.ago, end_time: 1.hour.from_now) assert_not event.event_ended? end end test "allow_booking_during_event? should return true when set to true" do event = Event.new(allow_booking_during_event: true) assert event.allow_booking_during_event? end test "allow_booking_during_event? should return false when nil" do event = Event.new assert_not event.allow_booking_during_event? end end