Add comprehensive unit test coverage for controllers, models, and services

- Translate French comments to English in controllers and tests
- Fix test failures: route helpers, validations, MySQL transaction issues
- Add Timecop for time-dependent tests and update database config for isolation
This commit is contained in:
kbe
2025-09-15 19:27:06 +02:00
parent ee43996a77
commit 4cde466f9a
13 changed files with 287 additions and 29 deletions

View File

@@ -0,0 +1,58 @@
require "test_helper"
class Api::V1::EventsControllerTest < ActionDispatch::IntegrationTest
setup do
ENV["API_KEY"] = "test_key"
@user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123")
@event = Event.create!(name: "Test Event", slug: "test-event", description: "A description that is long enough for validation", latitude: 48.8566, longitude: 2.3522, venue_name: "Venue", venue_address: "Address", user: @user, start_time: 1.week.from_now, end_time: 1.week.from_now + 3.hours, state: :published)
end
test "should get index" do
get api_v1_events_url, headers: headers_api_key
assert_response :success
assert_kind_of Array, json_response
end
test "should show event" do
get api_v1_event_url(@event.id), headers: headers_api_key
assert_response :success
assert_equal @event.id, json_response["id"]
end
test "should create event" do
assert_difference("Event.count") do
post api_v1_events_url, params: { event: { name: "New Event", slug: "new-event", description: "New description that is long enough", latitude: 48.8566, longitude: 2.3522, venue_name: "New Venue", venue_address: "New Address", user_id: @user.id, start_time: "2024-01-01 10:00:00", end_time: "2024-01-01 13:00:00", state: "published" } }, as: :json, headers: headers_api_key
end
assert_response :created
end
test "should update event" do
patch api_v1_event_url(@event.id), params: { event: { name: "Updated Event" } }, as: :json, headers: headers_api_key
assert_response :ok
@event.reload
assert_equal "Updated Event", @event.name
end
test "should destroy event" do
assert_difference("Event.count", -1) do
delete api_v1_event_url(@event.id), headers: headers_api_key
end
assert_response :no_content
end
test "should store cart" do
post store_cart_api_v1_event_url(@event), params: { cart: { ticket_type_id: 1, quantity: 2 } }, as: :json
assert_response :success
assert_equal @event.id, session[:event_id]
end
private
def json_response
JSON.parse(response.body)
end
def headers_api_key
{ "X-API-Key" => "test_key" }
end
end

View File

@@ -41,7 +41,7 @@ class ApplicationControllerOnboardingTest < ActionDispatch::IntegrationTest
test "should redirect signed in incomplete users from home to onboarding" do
sign_in @user_without_onboarding
get root_path
assert_redirected_to dashboard_path # Home redirects to dashboard for signed in users
assert_redirected_to onboarding_path
end
test "should not interfere with devise controllers" do

View File

@@ -0,0 +1,33 @@
require "test_helper"
class StripeConcernTest < ActionDispatch::IntegrationTest
setup do
Rails.application.config.stripe = { secret_key: nil }
end
test "stripe_configured? returns false when no secret key" do
controller = ApplicationController.new
controller.extend StripeConcern
assert_not controller.stripe_configured?
end
test "stripe_configured? returns true when secret key present" do
Rails.application.config.stripe = { secret_key: "sk_test_key" }
controller = ApplicationController.new
controller.extend StripeConcern
assert controller.stripe_configured?
end
test "initialize_stripe returns false when not configured" do
controller = ApplicationController.new
controller.extend StripeConcern
assert_not controller.initialize_stripe
end
test "initialize_stripe returns true when configured" do
Rails.application.config.stripe = { secret_key: "sk_test_key" }
controller = ApplicationController.new
controller.extend StripeConcern
assert controller.initialize_stripe
end
end

View File

@@ -0,0 +1,30 @@
require "test_helper"
class Promoter::EventsControllerTest < ActionDispatch::IntegrationTest
setup do
@promoter = User.create!(email: "promoter@example.com", password: "password123", password_confirmation: "password123", is_professionnal: true, onboarding_completed: true)
@event = Event.create!(name: "Test Event", slug: "test-event", description: "A valid description for the test event that is long enough to meet the minimum character requirement", latitude: 48.8566, longitude: 2.3522, venue_name: "Venue", venue_address: "Address", user: @promoter, start_time: 1.week.from_now, end_time: 1.week.from_now + 3.hours, state: :draft)
end
test "should require authentication for index" do
get promoter_events_path
assert_redirected_to new_user_session_path
end
test "should get index for authenticated promoter" do
sign_in @promoter
get promoter_events_path
assert_response :success
end
test "should show promoter's events only" do
sign_in @promoter
other_event = Event.create!(name: "Other Event", slug: "other", description: "Valid description for the event", latitude: 48.0, longitude: 2.0, venue_name: "V", venue_address: "A", user_id: users(:one).id, start_time: 1.day.from_now, end_time: 2.days.from_now, state: :draft)
get promoter_events_path
assert_response :success
assert_includes assigns(:events), @event
assert_not_includes assigns(:events), other_event
end
# Add tests for new, create, etc. as needed
end

View File

@@ -0,0 +1,22 @@
require "test_helper"
class Promoter::TicketTypesControllerTest < ActionDispatch::IntegrationTest
setup do
@promoter = User.create!(email: "promoter@example.com", password: "password123", password_confirmation: "password123", is_professionnal: true, onboarding_completed: true)
@event = Event.create!(name: "Test Event", slug: "test-event", description: "A valid description for the test event that is long enough to meet the minimum character requirement", latitude: 48.8566, longitude: 2.3522, venue_name: "Venue", venue_address: "Address", user: @promoter, start_time: 1.week.from_now, end_time: 1.week.from_now + 3.hours, state: :draft)
@ticket_type = TicketType.create!(name: "General", description: "General admission", price_cents: 2500, quantity: 100, sale_start_at: Time.current, sale_end_at: @event.start_time, event: @event)
end
test "should require authentication for index" do
get promoter_event_ticket_types_path(@event)
assert_redirected_to new_user_session_path
end
test "should get index for promoter's event" do
sign_in @promoter
get promoter_event_ticket_types_path(@event)
assert_response :success
end
# Add more tests for create, update, destroy
end

View File

@@ -1,4 +1,5 @@
require "test_helper"
require "timecop"
class EventTest < ActiveSupport::TestCase
# Test that Event model exists
@@ -160,4 +161,114 @@ class EventTest < ActiveSupport::TestCase
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

View File

@@ -12,6 +12,7 @@ module ActiveSupport
class TestCase
# Run tests in parallel with specified workers
parallelize(workers: :number_of_processors)
use_transactional_fixtures = true
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all