diff --git a/app/controllers/tournaments_controller.rb b/app/controllers/tournaments_controller.rb index a3acc19..f0ee6b3 100644 --- a/app/controllers/tournaments_controller.rb +++ b/app/controllers/tournaments_controller.rb @@ -221,12 +221,26 @@ class TournamentsController < ApplicationController end def index - if params[:search] - # @tournaments = Tournament.limit(200).search(params[:search]).order("date DESC") - @tournaments = Tournament.limit(200).search_date_name(params[:search]).order("date DESC") + # Simple manual pagination to avoid introducing a gem. + per_page = 20 + page = params[:page].to_i > 0 ? params[:page].to_i : 1 + offset = (page - 1) * per_page + + if params[:search].present? + tournaments = Tournament.search_date_name(params[:search]).to_a else - @tournaments = Tournament.all.sort_by{|t| t.days_until_start}.first(20) + tournaments = Tournament.all.to_a end + + # Sort by distance from today (closest first) + today = Date.today + tournaments.sort_by! { |t| (t.date - today).abs } + + @total_count = tournaments.size + @total_pages = (@total_count / per_page.to_f).ceil + @page = page + @per_page = per_page + @tournaments = tournaments.slice(offset, per_page) || [] end def show diff --git a/app/views/tournaments/index.html.erb b/app/views/tournaments/index.html.erb index d364662..7389526 100644 --- a/app/views/tournaments/index.html.erb +++ b/app/views/tournaments/index.html.erb @@ -1,28 +1,29 @@ -

Upcoming Tournaments

<%= form_tag(tournaments_path, :method => "get", id: "search-form") do %> - <%= text_field_tag :search, params[:search], placeholder: "Search Tournaments" %> - <%= submit_tag "Search" %> - <% end %> -

Search by name or date YYYY-MM-DD

- +

Upcoming Tournaments

+<%= form_tag(tournaments_path, :method => "get", id: "search-form") do %> + <%= text_field_tag :search, params[:search], placeholder: "Search Tournaments" %> + <%= submit_tag "Search" %> +<% end %> +

Search by name or date YYYY-MM-DD

+
+ - <% end %> + <% @tournaments.each do |tournament| %> - + <% end %>
Name Date<% if user_signed_in? %><%= link_to ' New Tournament', new_tournament_path, :class=>"fas fa-plus" %> + <% if user_signed_in? %> + <%= link_to ' New Tournament', new_tournament_path, :class=>"fas fa-plus" %> + <% end %> +
<%= link_to "#{tournament.name}", tournament %><%= link_to tournament.name, tournament %> <%= tournament.date %> <% if can? :manage, tournament %> @@ -30,13 +31,56 @@ <% if can? :destroy, tournament %> <%= link_to '', tournament, method: :delete, data: { confirm: "Are you sure you want to delete #{tournament.name}?" }, :class=>"fas fa-trash-alt" %> <% end %> - <% end %> + <% end %>
-
+<%# Pagination controls %> +<% if @total_pages.present? && @total_pages > 1 %> + + +

+ <% start_index = ((@page - 1) * @per_page) + 1 + end_index = [@page * @per_page, @total_count].min + %> + Showing <%= start_index %> - <%= end_index %> of <%= @total_count %> tournaments +

+<% end %> diff --git a/test/controllers/tournaments_controller_test.rb b/test/controllers/tournaments_controller_test.rb index 633dcb2..dd35a09 100644 --- a/test/controllers/tournaments_controller_test.rb +++ b/test/controllers/tournaments_controller_test.rb @@ -1084,4 +1084,55 @@ class TournamentsControllerTest < ActionController::TestCase assert_match(/#{match.bout_number}/, response.body, "Bout number #{match.bout_number} is missing from the bracket page") end end + test "index sorts tournaments by date closest to today" do + today = Date.today + t_today = Tournament.create!(name: "Closest Today", address: "123 Test St", director: "Director", director_email: "today@example.com", date: today, tournament_type: "Pool to bracket", is_public: true) + t_minus1 = Tournament.create!(name: "Minus 1", address: "123 Test St", director: "Director", director_email: "m1@example.com", date: today - 1, tournament_type: "Pool to bracket", is_public: true) + t_plus1 = Tournament.create!(name: "Plus 1", address: "123 Test St", director: "Director", director_email: "p1@example.com", date: today + 1, tournament_type: "Pool to bracket", is_public: true) + t_plus2 = Tournament.create!(name: "Plus 2", address: "123 Test St", director: "Director", director_email: "p2@example.com", date: today + 2, tournament_type: "Pool to bracket", is_public: true) + t_minus3 = Tournament.create!(name: "Minus 3", address: "123 Test St", director: "Director", director_email: "m3@example.com", date: today - 3, tournament_type: "Pool to bracket", is_public: true) + t_plus10 = Tournament.create!(name: "Plus 10", address: "123 Test St", director: "Director", director_email: "p10@example.com", date: today + 10, tournament_type: "Pool to bracket", is_public: true) + + created = [t_today, t_minus1, t_plus1, t_plus2, t_minus3, t_plus10] + # Hit index + get :index + assert_response :success + + # From the controller result, select only the tournaments we just created and verify their relative order + results = assigns(:tournaments).select { |t| created.map(&:id).include?(t.id) } + expected_order = created.sort_by { |t| (t.date - today).abs }.map(&:id) + + # Basic ordering assertions + assert_equal expected_order, results.map(&:id), "Created tournaments should be ordered by distance from today" + assert_equal t_today.id, results.first.id, "The tournament dated today should be first (closest)" + assert_equal t_plus10.id, results.last.id, "The farthest tournament should appear last" + + # Relative order checks (smaller distance should appear before larger distance) + assert results.index { |r| r.id == t_minus1.id } < results.index { |r| r.id == t_plus2.id }, "t_minus1 (distance 1) should appear before t_plus2 (distance 2)" + assert results.index { |r| r.id == t_plus2.id } < results.index { |r| r.id == t_minus3.id }, "t_plus2 (distance 2) should appear before t_minus3 (distance 3)" + end + + test "index paginates tournaments with page param and exposes total_count" do + initial_count = Tournament.count + # Create 25 tournaments to ensure we exceed the per_page (20) + 25.times do |i| + Tournament.create!(name: "Paginate Test #{i}", address: "1 Paginate Rd", director: "Dir", director_email: "paginate#{i}@example.com", date: Date.today + i, tournament_type: "Pool to bracket", is_public: true) + end + expected_total = initial_count + 25 + + # Page 1 + get :index, params: { page: 1 } + assert_response :success + assert_equal expected_total, assigns(:total_count), "total_count should reflect all tournaments" + assert_equal 20, assigns(:tournaments).size, "first page should contain 20 tournaments" + + # Page 2 + get :index, params: { page: 2 } + assert_response :success + assert_equal expected_total, assigns(:total_count), "total_count should remain the same on subsequent pages" + expected_page2_size = expected_total - 20 + # If there are more than 20 initial fixtures, expected_page2_size might be > 20; clamp to per_page logic: + expected_page2_display = [expected_page2_size, 20].min + assert_equal expected_page2_display, assigns(:tournaments).size, "second page should contain the remaining tournaments (or up to per_page)" + end end