From 3c5b0dac81a03b294d39ef3fcad5195202264fd4 Mon Sep 17 00:00:00 2001 From: Duncan Date: Tue, 26 Nov 2024 11:14:38 +0200 Subject: [PATCH 01/14] added newcomer_reserved_spots competition field --- app/models/competition.rb | 1 + ...26084446_add_newcomer_reserved_spots_to_competitions.rb | 7 +++++++ db/schema.rb | 3 ++- lib/database_dumper.rb | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20241126084446_add_newcomer_reserved_spots_to_competitions.rb diff --git a/app/models/competition.rb b/app/models/competition.rb index aa82e6da80..a78c31b76a 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -188,6 +188,7 @@ class Competition < ApplicationRecord MAX_MARKDOWN_LENGTH = 255 MAX_COMPETITOR_LIMIT = 5000 MAX_GUEST_LIMIT = 100 + NEWCOMER_MONTH = validates_inclusion_of :competitor_limit_enabled, in: [true, false], if: :competitor_limit_required? validates_numericality_of :competitor_limit, greater_than_or_equal_to: 1, less_than_or_equal_to: MAX_COMPETITOR_LIMIT, if: :competitor_limit_enabled? validates :competitor_limit_reason, presence: true, if: :competitor_limit_enabled? diff --git a/db/migrate/20241126084446_add_newcomer_reserved_spots_to_competitions.rb b/db/migrate/20241126084446_add_newcomer_reserved_spots_to_competitions.rb new file mode 100644 index 0000000000..d9bf6c37fc --- /dev/null +++ b/db/migrate/20241126084446_add_newcomer_reserved_spots_to_competitions.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddNewcomerReservedSpotsToCompetitions < ActiveRecord::Migration[7.2] + def change + add_column :Competitions, :newcomer_reserved_spots, :integer, default: 0, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 4f5616229b..bd45f69519 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.2].define(version: 2024_11_18_145843) do +ActiveRecord::Schema[7.2].define(version: 2024_11_26_084446) do create_table "Competitions", id: { type: :string, limit: 32, default: "" }, charset: "utf8mb4", collation: "utf8mb4_unicode_ci", force: :cascade do |t| t.string "name", limit: 50, default: "", null: false t.string "cityName", limit: 50, default: "", null: false @@ -82,6 +82,7 @@ t.boolean "forbid_newcomers", default: false, null: false t.string "forbid_newcomers_reason" t.integer "registration_version", default: 0, null: false + t.integer "newcomer_reserved_spots", default: 0, null: false t.index ["cancelled_at"], name: "index_Competitions_on_cancelled_at" t.index ["countryId"], name: "index_Competitions_on_countryId" t.index ["end_date"], name: "index_Competitions_on_end_date" diff --git a/lib/database_dumper.rb b/lib/database_dumper.rb index e472a23a95..1c0703498e 100644 --- a/lib/database_dumper.rb +++ b/lib/database_dumper.rb @@ -110,6 +110,7 @@ def self.actions_to_column_sanitizers(columns_by_action) registration_version forbid_newcomers forbid_newcomers_reason + newcomer_reserved_spots ), db_default: %w( connected_stripe_account_id From 503ac9b97bad6067a603b60e22193a8230d10fde Mon Sep 17 00:00:00 2001 From: Duncan Date: Tue, 26 Nov 2024 11:43:42 +0200 Subject: [PATCH 02/14] added validation --- app/models/competition.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/models/competition.rb b/app/models/competition.rb index a78c31b76a..395c4dba3d 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -188,7 +188,7 @@ class Competition < ApplicationRecord MAX_MARKDOWN_LENGTH = 255 MAX_COMPETITOR_LIMIT = 5000 MAX_GUEST_LIMIT = 100 - NEWCOMER_MONTH = + NEWCOMER_MONTH_ENABLED = true validates_inclusion_of :competitor_limit_enabled, in: [true, false], if: :competitor_limit_required? validates_numericality_of :competitor_limit, greater_than_or_equal_to: 1, less_than_or_equal_to: MAX_COMPETITOR_LIMIT, if: :competitor_limit_enabled? validates :competitor_limit_reason, presence: true, if: :competitor_limit_enabled? @@ -243,6 +243,13 @@ class Competition < ApplicationRecord validates :external_website, :external_registration_page, length: { maximum: MAX_URL_LENGTH } validates :contact, length: { maximum: MAX_MARKDOWN_LENGTH } + validate :validate_newcomer_reserved_spots + private def validate_newcomer_reserved_spots + if newcomer_reserved_spots > 0 && !NEWCOMER_MONTH_ENABLED + errors.add(:newcomer_reserved_spots, 'newcomer competitions are not allowed at present') + end + end + # Dirty old trick to deal with competition id changes (see other methods using # 'with_old_id' for more details). def persisted_events_id From ea3d696a88a1af62a1ddcbaa6cb8f25ec85f0685 Mon Sep 17 00:00:00 2001 From: Duncan Date: Tue, 26 Nov 2024 13:34:03 +0200 Subject: [PATCH 03/14] added validation on number of newcomer spots that can be reserved --- app/models/competition.rb | 8 ++++++++ spec/models/competition_spec.rb | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/app/models/competition.rb b/app/models/competition.rb index 395c4dba3d..b70d432f01 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -189,6 +189,8 @@ class Competition < ApplicationRecord MAX_COMPETITOR_LIMIT = 5000 MAX_GUEST_LIMIT = 100 NEWCOMER_MONTH_ENABLED = true + MAX_NEWCOMER_SPOTS_RESERVED_FRACTION = 0.5 + validates_inclusion_of :competitor_limit_enabled, in: [true, false], if: :competitor_limit_required? validates_numericality_of :competitor_limit, greater_than_or_equal_to: 1, less_than_or_equal_to: MAX_COMPETITOR_LIMIT, if: :competitor_limit_enabled? validates :competitor_limit_reason, presence: true, if: :competitor_limit_enabled? @@ -248,8 +250,14 @@ class Competition < ApplicationRecord if newcomer_reserved_spots > 0 && !NEWCOMER_MONTH_ENABLED errors.add(:newcomer_reserved_spots, 'newcomer competitions are not allowed at present') end + + max_newcomer_spots = (competitor_limit * MAX_NEWCOMER_SPOTS_RESERVED_FRACTION).to_i + if newcomer_reserved_spots > max_newcomer_spots + errors.add(:newcomer_reserved_spots, 'cant reserve more than 50% of spots for newcomers') + end end + # Dirty old trick to deal with competition id changes (see other methods using # 'with_old_id' for more details). def persisted_events_id diff --git a/spec/models/competition_spec.rb b/spec/models/competition_spec.rb index 1efb07fcc2..7da6861901 100644 --- a/spec/models/competition_spec.rb +++ b/spec/models/competition_spec.rb @@ -11,6 +11,20 @@ expect(competition.cellName).to eq "Foo: Test - 2015" end + it 'can reserve newcomer spots up to 50% of registrations' do + expect(FactoryBot.build(:competition, newcomer_reserved_spots: 50, competitor_limit: 100 )).to be_valid + end + + it 'reserved newcomers spots cant exceed 50% of registrations' do + expect(FactoryBot.build(:competition, newcomer_reserved_spots: 51, competitor_limit: 100 )).to be_invalid_with_errors( + newcomer_reserved_spots: ['cant reserve more than 50% of spots for newcomers'] + ) + + expect(FactoryBot.build(:competition, newcomer_reserved_spots: 50, competitor_limit: 99 )).to be_invalid_with_errors( + newcomer_reserved_spots: ['cant reserve more than 50% of spots for newcomers'] + ) + end + it "rejects invalid names" do [ "foo (Test) - 2015", From 894f216d8ce5c8f387cc835c01925eb99e814f4c Mon Sep 17 00:00:00 2001 From: Duncan Date: Tue, 26 Nov 2024 14:24:53 +0200 Subject: [PATCH 04/14] rubocop --- app/models/competition.rb | 1 - spec/models/competition_spec.rb | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/models/competition.rb b/app/models/competition.rb index b70d432f01..dd4a908a84 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -257,7 +257,6 @@ class Competition < ApplicationRecord end end - # Dirty old trick to deal with competition id changes (see other methods using # 'with_old_id' for more details). def persisted_events_id diff --git a/spec/models/competition_spec.rb b/spec/models/competition_spec.rb index 7da6861901..a66063cf31 100644 --- a/spec/models/competition_spec.rb +++ b/spec/models/competition_spec.rb @@ -12,16 +12,16 @@ end it 'can reserve newcomer spots up to 50% of registrations' do - expect(FactoryBot.build(:competition, newcomer_reserved_spots: 50, competitor_limit: 100 )).to be_valid + expect(FactoryBot.build(:competition, newcomer_reserved_spots: 50, competitor_limit: 100)).to be_valid end it 'reserved newcomers spots cant exceed 50% of registrations' do - expect(FactoryBot.build(:competition, newcomer_reserved_spots: 51, competitor_limit: 100 )).to be_invalid_with_errors( - newcomer_reserved_spots: ['cant reserve more than 50% of spots for newcomers'] + expect(FactoryBot.build(:competition, newcomer_reserved_spots: 51, competitor_limit: 100)).to be_invalid_with_errors( + newcomer_reserved_spots: ['cant reserve more than 50% of spots for newcomers'], ) - expect(FactoryBot.build(:competition, newcomer_reserved_spots: 50, competitor_limit: 99 )).to be_invalid_with_errors( - newcomer_reserved_spots: ['cant reserve more than 50% of spots for newcomers'] + expect(FactoryBot.build(:competition, newcomer_reserved_spots: 50, competitor_limit: 99)).to be_invalid_with_errors( + newcomer_reserved_spots: ['cant reserve more than 50% of spots for newcomers'], ) end From 54da7d373b5d0fe9ca12fcdd1e2f833fc5d8e570 Mon Sep 17 00:00:00 2001 From: Duncan Date: Tue, 26 Nov 2024 14:54:21 +0200 Subject: [PATCH 05/14] added newcomer limit to competition form --- app/models/competition.rb | 6 ++++++ .../CompetitionForm/FormSections/CompetitorLimit.js | 1 + config/locales/en.yml | 2 ++ 3 files changed, 9 insertions(+) diff --git a/app/models/competition.rb b/app/models/competition.rb index dd4a908a84..7a5bf4a7b2 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -247,6 +247,8 @@ class Competition < ApplicationRecord validate :validate_newcomer_reserved_spots private def validate_newcomer_reserved_spots + return unless competitor_limit.present? + if newcomer_reserved_spots > 0 && !NEWCOMER_MONTH_ENABLED errors.add(:newcomer_reserved_spots, 'newcomer competitions are not allowed at present') end @@ -2366,6 +2368,7 @@ def to_form_data "enabled" => competitor_limit_enabled, "count" => competitor_limit, "reason" => competitor_limit_reason, + "newcomerReservedSpots" => newcomer_reserved_spots, }, "staff" => { "staffDelegateIds" => staff_delegates.to_a.pluck(:id), @@ -2467,6 +2470,7 @@ def form_errors "enabled" => errors[:competitor_limit_enabled], "count" => errors[:competitor_limit], "reason" => errors[:competitor_limit_reason], + "newcomer_reserved_spots" => errors[:newcomer_reserved_spots] }, "staff" => { "staffDelegateIds" => errors[:staff_delegate_ids], @@ -2604,6 +2608,7 @@ def self.form_data_to_attributes(form_data) competitor_limit_enabled: form_data.dig('competitorLimit', 'enabled'), competitor_limit: form_data.dig('competitorLimit', 'count'), competitor_limit_reason: form_data.dig('competitorLimit', 'reason'), + newcomer_reserved_spots: form_data.dig('competitorLimit', 'newcomerReservedSpots'), extra_registration_requirements: form_data.dig('registration', 'extraRequirements'), on_the_spot_registration: form_data.dig('registration', 'allowOnTheSpot'), on_the_spot_entry_fee_lowest_denomination: form_data.dig('entryFees', 'onTheSpotEntryFee'), @@ -2747,6 +2752,7 @@ def self.form_data_json_schema "enabled" => { "type" => ["boolean", "null"] }, "count" => { "type" => ["integer", "null"] }, "reason" => { "type" => ["string", "null"] }, + "newcomerReservedSpots" => { "type" => ["integer", "null"]} }, }, "staff" => { diff --git a/app/webpacker/components/CompetitionForm/FormSections/CompetitorLimit.js b/app/webpacker/components/CompetitionForm/FormSections/CompetitorLimit.js index c7399d80c7..89fc7bc82c 100644 --- a/app/webpacker/components/CompetitionForm/FormSections/CompetitorLimit.js +++ b/app/webpacker/components/CompetitionForm/FormSections/CompetitorLimit.js @@ -17,6 +17,7 @@ export default function CompetitorLimit() { + ); diff --git a/config/locales/en.yml b/config/locales/en.yml index 93cf206d0b..ca1fc390cb 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1662,6 +1662,7 @@ en: enabled: "Competitor limit" count: "Maximum number of competitors" reason: "The reason for the competitor limit" + newcomer_reserved_spots: "Number of spots to reserve for newcomers" staff: staff_delegate_ids: "WCA Delegate(s)" trainee_delegate_ids: "WCA Trainee Delegate(s)" @@ -1746,6 +1747,7 @@ en: enabled: "Although it is not required by the Regulations to provide a competitor limit, it's highly recommended to do so." count: "The number of competitors allowed in this competition. For now this number is informational only, and does not yet prevent more people from registering. We are working on adding explicit support for this to the registration flow, but it requires some other work first." reason: "What is the reason for the limit on competitors? Please fill this out in English!" + newcomer_reserved_spots: "Only allowed during Newcomer Month - reserved spots can't be more than half of the Competitor Limit." staff: staff_delegate_ids: "WCA Delegates for the competition." trainee_delegate_ids: "WCA Trainee Delegates for the competition." From 3c049706df99a7c43438a5e1b53129899fdfc301 Mon Sep 17 00:00:00 2001 From: Duncan Date: Tue, 26 Nov 2024 14:57:35 +0200 Subject: [PATCH 06/14] rubocop --- app/models/competition.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/competition.rb b/app/models/competition.rb index 7a5bf4a7b2..35cb2724d7 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -2470,7 +2470,7 @@ def form_errors "enabled" => errors[:competitor_limit_enabled], "count" => errors[:competitor_limit], "reason" => errors[:competitor_limit_reason], - "newcomer_reserved_spots" => errors[:newcomer_reserved_spots] + "newcomer_reserved_spots" => errors[:newcomer_reserved_spots], }, "staff" => { "staffDelegateIds" => errors[:staff_delegate_ids], @@ -2752,7 +2752,7 @@ def self.form_data_json_schema "enabled" => { "type" => ["boolean", "null"] }, "count" => { "type" => ["integer", "null"] }, "reason" => { "type" => ["string", "null"] }, - "newcomerReservedSpots" => { "type" => ["integer", "null"]} + "newcomerReservedSpots" => { "type" => ["integer", "null"] }, }, }, "staff" => { From a944b2d94fab2119292d9ea4c0d11881ec7c83f1 Mon Sep 17 00:00:00 2001 From: Duncan Date: Tue, 26 Nov 2024 15:20:14 +0200 Subject: [PATCH 07/14] defined reg checker tests and made reserved spots uncloneable --- app/models/competition.rb | 1 + .../registration_checker_spec.rb | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/app/models/competition.rb b/app/models/competition.rb index 35cb2724d7..625cf789b1 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -172,6 +172,7 @@ class Competition < ApplicationRecord event_change_deadline_date competition_series_id registration_version + newcomer_reserved_spots ).freeze VALID_NAME_RE = /\A([-&.:' [:alnum:]]+) (\d{4})\z/ VALID_ID_RE = /\A[a-zA-Z0-9]+\Z/ diff --git a/spec/lib/registrations/registration_checker_spec.rb b/spec/lib/registrations/registration_checker_spec.rb index f278e70792..b0039fcaea 100644 --- a/spec/lib/registrations/registration_checker_spec.rb +++ b/spec/lib/registrations/registration_checker_spec.rb @@ -2278,6 +2278,40 @@ }.not_to raise_error end end + + describe '#update_registration_allowed!.reserved newcomer spots' do + it 'organizer cant accept non-newcomer if only reserved newcomer spots remain' do + expect(true).to eq(false) + end + + it 'organizer can still accept newcomer if all reserved newcomer spots are full' do + expect(true).to eq(false) + end + + it 'organizer can accept non-newcomer if all reserved newcomer spots are full' do + expect(true).to eq(false) + end + + it 'organizer can accept newcomer if only reserved newcomer spots remain' do + expect(true).to eq(false) + end + + it 'organizer cant accept newcomer if competition if full' do + expect(true).to eq(false) + end + + it 'organizer can accept non-newcomer into a newcomer reserved spot if registration is closed' do + expect(true).to eq(false) + end + + it 'newcomer includes users with no WCA ID' do + expect(true).to eq(false) + end + + it 'newcomer includes users with a current-year WCA ID' do + expect(true).to eq(false) + end + end end describe '#bulk_update' do From 54613cfca4d493b9302a15022f676dd49070a2f4 Mon Sep 17 00:00:00 2001 From: Duncan Date: Tue, 26 Nov 2024 17:18:37 +0200 Subject: [PATCH 08/14] basic tests for registration_checker and competition model --- app/models/competition.rb | 5 ++ .../RegistrationsV2/api/helper/error_codes.js | 1 + lib/registrations/error_codes.rb | 1 + lib/registrations/registration_checker.rb | 13 +++- spec/factories/competitions.rb | 8 +++ .../registration_checker_spec.rb | 60 ++++++++++++------- spec/models/competition_spec.rb | 26 ++++++++ spec/spec_helper.rb | 2 +- 8 files changed, 92 insertions(+), 24 deletions(-) diff --git a/app/models/competition.rb b/app/models/competition.rb index 625cf789b1..aaaaa094b1 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -260,6 +260,11 @@ class Competition < ApplicationRecord end end + # TODO: Make sure this query is optimized + def non_newcomers_competing + registrations.accepted.where() + end + # Dirty old trick to deal with competition id changes (see other methods using # 'with_old_id' for more details). def persisted_events_id diff --git a/app/webpacker/components/RegistrationsV2/api/helper/error_codes.js b/app/webpacker/components/RegistrationsV2/api/helper/error_codes.js index a158b774a6..68fcf5cfa8 100644 --- a/app/webpacker/components/RegistrationsV2/api/helper/error_codes.js +++ b/app/webpacker/components/RegistrationsV2/api/helper/error_codes.js @@ -21,6 +21,7 @@ export const INVALID_REGISTRATION_STATUS = -4007; export const REGISTRATION_CLOSED = -4008; export const ORGANIZER_MUST_CANCEL_REGISTRATION = -4009; export const INVALID_WAITING_LIST_POSITION = -4010; +export const NO_UNRESERVED_SPOTS_REMAINING = -4011; export const QUALIFICATION_NOT_MET = -4012; export const PAYMENT_NOT_ENABLED = -6001; export const PAYMENT_NOT_READY = -6002; diff --git a/lib/registrations/error_codes.rb b/lib/registrations/error_codes.rb index f69d7c9ea0..feabbf19ca 100644 --- a/lib/registrations/error_codes.rb +++ b/lib/registrations/error_codes.rb @@ -34,6 +34,7 @@ module ErrorCodes REGISTRATION_CLOSED = -4008 ORGANIZER_MUST_CANCEL_REGISTRATION = -4009 INVALID_WAITING_LIST_POSITION = -4010 + NO_UNRESERVED_SPOTS_REMAINING = -4011 QUALIFICATION_NOT_MET = -4012 # Payment Errors diff --git a/lib/registrations/registration_checker.rb b/lib/registrations/registration_checker.rb index 9bdfe55f9d..13fc690ce2 100644 --- a/lib/registrations/registration_checker.rb +++ b/lib/registrations/registration_checker.rb @@ -171,12 +171,19 @@ def contains_organizer_fields?(request, organizer_fields) def validate_update_status!(new_status, competition, current_user, target_user, registration, events) raise WcaExceptions::RegistrationError.new(:unprocessable_entity, Registrations::ErrorCodes::INVALID_REQUEST_DATA) unless Registration.competing_statuses.include?(new_status) - raise WcaExceptions::RegistrationError.new(:forbidden, Registrations::ErrorCodes::COMPETITOR_LIMIT_REACHED) if - new_status == Registrations::Helper::STATUS_ACCEPTED && competition.competitor_limit_enabled? && - competition.registrations.competing_status_accepted.count >= competition.competitor_limit raise WcaExceptions::RegistrationError.new(:forbidden, Registrations::ErrorCodes::ALREADY_REGISTERED_IN_SERIES) if new_status == Registrations::Helper::STATUS_ACCEPTED && existing_registration_in_series?(competition, target_user) + if new_status == Registrations::Helper::STATUS_ACCEPTED && competition.competitor_limit_enabled? + raise WcaExceptions::RegistrationError.new(:forbidden, Registrations::ErrorCodes::COMPETITOR_LIMIT_REACHED) if + competition.registrations.competing_status_accepted.count >= competition.competitor_limit + + puts "checking this" + non_newcomer_spots_remaining = competition.competitor_limit - competition.newcomer_reserved_spots - competition.non_newcomers_competing + raise WcaExceptions::RegistrationError.new(:forbidden, Registrations::ErrorCodes::NO_UNRESERVED_SPOTS_REMAINING ) if + competition.non_newcomers_competing.count >= non_newcomer_spots_remaining + end + # Otherwise, organizers can make any status change they want to return if current_user.can_manage_competition?(competition) diff --git a/spec/factories/competitions.rb b/spec/factories/competitions.rb index 864db6f92a..742657d514 100644 --- a/spec/factories/competitions.rb +++ b/spec/factories/competitions.rb @@ -99,8 +99,16 @@ refund_policy_percent { 0 } guests_entry_fee_lowest_denomination { 0 } + # TODO: This should change to :v3 registration_version { :v1 } + trait :newcomer_month do + with_organizer + with_competitor_limit + competitor_limit { 4 } + newcomer_reserved_spots { 2 } + end + trait :enforces_qualifications do with_organizer qualification_results { true } diff --git a/spec/lib/registrations/registration_checker_spec.rb b/spec/lib/registrations/registration_checker_spec.rb index b0039fcaea..9fd7fed90b 100644 --- a/spec/lib/registrations/registration_checker_spec.rb +++ b/spec/lib/registrations/registration_checker_spec.rb @@ -2279,40 +2279,60 @@ end end - describe '#update_registration_allowed!.reserved newcomer spots' do - it 'organizer cant accept non-newcomer if only reserved newcomer spots remain' do - expect(true).to eq(false) - end + describe '#update_registration_allowed!.reserved newcomer spots', :tag do + let(:newcomer_month_comp) { FactoryBot.create(:competition, :newcomer_month) } + let(:non_newcomer_reg) { FactoryBot.create(:registration, competition: newcomer_month_comp) } + let(:newcomer_reg) { FactoryBot.create(:registration, :newcomer, competition: newcomer_month_comp) } - it 'organizer can still accept newcomer if all reserved newcomer spots are full' do - expect(true).to eq(false) - end + describe 'only newcomer spots remain', :only do + before do + FactoryBot.create_list(:registration, 2, :accepted, competition: newcomer_month_comp) + end - it 'organizer can accept non-newcomer if all reserved newcomer spots are full' do - expect(true).to eq(false) - end + it 'organizer cant accept non-newcomer if only reserved newcomer spots remain' do + update_request = FactoryBot.build( + :update_request, + user_id: non_newcomer_reg.user.id, + competition_id: non_newcomer_reg.competition.id, + submitted_by: newcomer_month_comp.organizers.first.id, + competing: { 'status' => 'accepted'}, + ) - it 'organizer can accept newcomer if only reserved newcomer spots remain' do - expect(true).to eq(false) - end + expect { + Registrations::RegistrationChecker.update_registration_allowed!(update_request, Competition.find(update_request['competition_id']), User.find(update_request['submitted_by'])) + }.to raise_error(WcaExceptions::RegistrationError) do |error| + expect(error.error).to eq(Registrations::ErrorCodes::NO_UNRESERVED_SPOTS_REMAINING ) + expect(error.status).to eq(:forbidden) + end + end - it 'organizer cant accept newcomer if competition if full' do - expect(true).to eq(false) + it 'organizer can accept first-timer' do + expect(true).to eq(false) + end + + it 'organizer can accept newcomer who started competing this year)' do + expect(true).to eq(false) + end end - it 'organizer can accept non-newcomer into a newcomer reserved spot if registration is closed' do - expect(true).to eq(false) + describe 'reserved newcomer spots are full' + it 'organizer can still accept newcomers if all reserved newcomer spots are full' do + expect(true).to eq(false) + end + + it 'organizer can accept non-newcomer if all reserved newcomer spots are full' do + expect(true).to eq(false) + end end - it 'newcomer includes users with no WCA ID' do + it 'organizer cant accept newcomer if competition is full' do expect(true).to eq(false) end - it 'newcomer includes users with a current-year WCA ID' do + it 'organizer can accept non-newcomer into a newcomer reserved spot if registration is closed' do expect(true).to eq(false) end end - end describe '#bulk_update' do describe '#bulk_update_allowed!' do diff --git a/spec/models/competition_spec.rb b/spec/models/competition_spec.rb index a66063cf31..acabdfdadf 100644 --- a/spec/models/competition_spec.rb +++ b/spec/models/competition_spec.rb @@ -1597,4 +1597,30 @@ def change_and_check_activities(new_start_date, new_end_date) expect(new_competition).not_to be_valid end end + + context 'newcomer month competition', :tag do + let(:newcomer_month_comp) { FactoryBot.create(:competition, :newcomer_month) } + let!(:newcomer_reg) { FactoryBot.create(:registration, :newcomer, competition: newcomer_month_comp) } + + context '#non_newcomers_competing' do + before do + FactoryBot.create_list(:registration, 2, :accepted, competition: newcomer_month_comp) + end + + it 'doesnt include newcomers in count' do + expect(newcomer_month_comp.registrations.count).to eq(3) + expect(newcomer_month_comp.non_newcomers_competing.count).to eq(2) + end + + it 'doesnt include non-newcomers in non-accepted states' do + non_newcomer_reg1 = FactoryBot.create(:registration, competition: newcomer_month_comp) + non_newcomer_reg1 = FactoryBot.create(:registration, :cancelled, competition: newcomer_month_comp) + non_newcomer_reg1 = FactoryBot.create(:registration, :rejected, competition: newcomer_month_comp) + non_newcomer_reg1 = FactoryBot.create(:registration, :waiting_list, competition: newcomer_month_comp) + + expect(newcomer_month_comp.registrations.count).to eq(7) + expect(newcomer_month_comp.non_newcomers_competing.count).to eq(2) + end + end + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2ef2dfcaf3..24fa09bf88 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -86,7 +86,7 @@ # order dependency and want to debug it, you can fix the order by providing # the seed, which is printed after each run. # --seed 1234 - config.order = :random + # config.order = :random # Seed global randomization in this process using the `--seed` CLI option. # Setting this allows you to use `--seed` to deterministically reproduce From e17259bb0aaad9083d1923f83ceda49d20983e2e Mon Sep 17 00:00:00 2001 From: Duncan Date: Fri, 6 Dec 2024 12:49:56 +0200 Subject: [PATCH 09/14] finished tests and features for newcomer reservations --- app/models/competition.rb | 9 +- app/models/user.rb | 4 + .../RegistrationsV2/api/helper/error_codes.js | 2 +- config/locales/en.yml | 1 + lib/registrations/error_codes.rb | 2 +- lib/registrations/registration_checker.rb | 10 +- spec/factories/competitions.rb | 1 + spec/factories/persons.rb | 6 +- spec/factories/registrations.rb | 6 +- spec/factories/users.rb | 10 ++ .../registration_checker_spec.rb | 101 +++++++++++++++--- spec/models/competition_spec.rb | 8 +- spec/models/user_spec.rb | 17 +++ spec/spec_helper.rb | 2 +- 14 files changed, 151 insertions(+), 28 deletions(-) diff --git a/app/models/competition.rb b/app/models/competition.rb index aaaaa094b1..4ff33aab27 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -261,8 +261,13 @@ class Competition < ApplicationRecord end # TODO: Make sure this query is optimized - def non_newcomers_competing - registrations.accepted.where() + def newcomers_competing + registrations.competing_status_accepted.includes(:user).select { |registration| registration.user.newcomer? } + end + + # TODO: What if there are no newcomer reserved spots? Is this represented as nil or 0 in the db? + def newcomer_reserved_spots_remaining + newcomer_reserved_spots - newcomers_competing.count end # Dirty old trick to deal with competition id changes (see other methods using diff --git a/app/models/user.rb b/app/models/user.rb index 7fbc80999f..7d9e2c1a14 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -387,6 +387,10 @@ def country Country.find_by_iso2(country_iso2) end + def newcomer? + person.nil? || wca_id.start_with?(Time.current.year.to_s) + end + def locale preferred_locale || I18n.default_locale end diff --git a/app/webpacker/components/RegistrationsV2/api/helper/error_codes.js b/app/webpacker/components/RegistrationsV2/api/helper/error_codes.js index 68fcf5cfa8..cf05130436 100644 --- a/app/webpacker/components/RegistrationsV2/api/helper/error_codes.js +++ b/app/webpacker/components/RegistrationsV2/api/helper/error_codes.js @@ -21,7 +21,7 @@ export const INVALID_REGISTRATION_STATUS = -4007; export const REGISTRATION_CLOSED = -4008; export const ORGANIZER_MUST_CANCEL_REGISTRATION = -4009; export const INVALID_WAITING_LIST_POSITION = -4010; -export const NO_UNRESERVED_SPOTS_REMAINING = -4011; export const QUALIFICATION_NOT_MET = -4012; +export const NO_UNRESERVED_SPOTS_REMAINING = -4013; export const PAYMENT_NOT_ENABLED = -6001; export const PAYMENT_NOT_READY = -6002; diff --git a/config/locales/en.yml b/config/locales/en.yml index ca1fc390cb..712e3eeeef 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1949,6 +1949,7 @@ en: -4010: "The Waiting List Position is not Valid" -4011: "You can only accept the first person on the waiting list" -4012: "You are not qualified to compete in the selected events" + -4013: "Cant accept non-newcomer when only reserved newcomer spots remain" -6001: "WCA Payment is not enabled for this competition" -6002: "You need to finish your registration before you can pay" #context: and when an error occured diff --git a/lib/registrations/error_codes.rb b/lib/registrations/error_codes.rb index feabbf19ca..274324ad99 100644 --- a/lib/registrations/error_codes.rb +++ b/lib/registrations/error_codes.rb @@ -34,8 +34,8 @@ module ErrorCodes REGISTRATION_CLOSED = -4008 ORGANIZER_MUST_CANCEL_REGISTRATION = -4009 INVALID_WAITING_LIST_POSITION = -4010 - NO_UNRESERVED_SPOTS_REMAINING = -4011 QUALIFICATION_NOT_MET = -4012 + NO_UNRESERVED_SPOTS_REMAINING = -4013 # Payment Errors PAYMENT_NOT_ENABLED = -6001 diff --git a/lib/registrations/registration_checker.rb b/lib/registrations/registration_checker.rb index 13fc690ce2..cf0ea09622 100644 --- a/lib/registrations/registration_checker.rb +++ b/lib/registrations/registration_checker.rb @@ -178,10 +178,12 @@ def validate_update_status!(new_status, competition, current_user, target_user, raise WcaExceptions::RegistrationError.new(:forbidden, Registrations::ErrorCodes::COMPETITOR_LIMIT_REACHED) if competition.registrations.competing_status_accepted.count >= competition.competitor_limit - puts "checking this" - non_newcomer_spots_remaining = competition.competitor_limit - competition.newcomer_reserved_spots - competition.non_newcomers_competing - raise WcaExceptions::RegistrationError.new(:forbidden, Registrations::ErrorCodes::NO_UNRESERVED_SPOTS_REMAINING ) if - competition.non_newcomers_competing.count >= non_newcomer_spots_remaining + if !target_user.newcomer? && competition.newcomer_reserved_spots > 0 + non_newcomers_competing = competition.registrations.competing_status_accepted.count - competition.newcomers_competing.count + non_newcomer_spots_remaining = competition.competitor_limit - competition.newcomer_reserved_spots_remaining - non_newcomers_competing + raise WcaExceptions::RegistrationError.new(:forbidden, Registrations::ErrorCodes::NO_UNRESERVED_SPOTS_REMAINING) if + (non_newcomers_competing >= non_newcomer_spots_remaining) && competition.registration_currently_open? + end end # Otherwise, organizers can make any status change they want to diff --git a/spec/factories/competitions.rb b/spec/factories/competitions.rb index 742657d514..7293e2d6c9 100644 --- a/spec/factories/competitions.rb +++ b/spec/factories/competitions.rb @@ -103,6 +103,7 @@ registration_version { :v1 } trait :newcomer_month do + registration_open with_organizer with_competitor_limit competitor_limit { 4 } diff --git a/spec/factories/persons.rb b/spec/factories/persons.rb index 8166f786a5..1aed8708e6 100644 --- a/spec/factories/persons.rb +++ b/spec/factories/persons.rb @@ -2,9 +2,13 @@ FactoryBot.define do factory :person do + transient do + wca_id_year { "2016" } + end + wca_id do mid = ('A'..'Z').to_a.sample(4).join - id = "2016#{mid}01" + id = "#{wca_id_year}#{mid}01" id = id.next while Person.exists?(wca_id: id) id end diff --git a/spec/factories/registrations.rb b/spec/factories/registrations.rb index 635d8e3023..ce0af058a6 100644 --- a/spec/factories/registrations.rb +++ b/spec/factories/registrations.rb @@ -41,10 +41,14 @@ competing_status { Registrations::Helper::STATUS_WAITING_LIST } end - trait :newcomer do + trait :first_timer do association :user, factory: [:user] end + trait :newcomer do + association :user, factory: [:user, :current_year_wca_id] + end + trait :paid do after(:create) do |registration| FactoryBot.create :registration_payment, registration: registration, user: registration.user, diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 4e2e76c0f7..d3e02e917c 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -220,6 +220,16 @@ end end + trait :current_year_wca_id do + transient do + person { + FactoryBot.create( + :person, name: name, countryId: Country.find_by_iso2(country_iso2).id, gender: gender, dob: dob.strftime("%F"), wca_id_year: Time.current.year.to_s + ) + } + end + end + trait :with_2fa do otp_required_for_login { true } otp_secret { User.generate_otp_secret } diff --git a/spec/lib/registrations/registration_checker_spec.rb b/spec/lib/registrations/registration_checker_spec.rb index 9fd7fed90b..f82adb79fe 100644 --- a/spec/lib/registrations/registration_checker_spec.rb +++ b/spec/lib/registrations/registration_checker_spec.rb @@ -2279,14 +2279,15 @@ end end - describe '#update_registration_allowed!.reserved newcomer spots', :tag do + describe '#update_registration_allowed!.reserved newcomer spots' do let(:newcomer_month_comp) { FactoryBot.create(:competition, :newcomer_month) } let(:non_newcomer_reg) { FactoryBot.create(:registration, competition: newcomer_month_comp) } let(:newcomer_reg) { FactoryBot.create(:registration, :newcomer, competition: newcomer_month_comp) } + let(:first_timer_reg) { FactoryBot.create(:registration, :first_timer, competition: newcomer_month_comp) } - describe 'only newcomer spots remain', :only do + describe 'only newcomer spots remain' do before do - FactoryBot.create_list(:registration, 2, :accepted, competition: newcomer_month_comp) + FactoryBot.create_list(:registration, 2, :accepted, competition: newcomer_month_comp) end it 'organizer cant accept non-newcomer if only reserved newcomer spots remain' do @@ -2295,44 +2296,118 @@ user_id: non_newcomer_reg.user.id, competition_id: non_newcomer_reg.competition.id, submitted_by: newcomer_month_comp.organizers.first.id, - competing: { 'status' => 'accepted'}, + competing: { 'status' => 'accepted' }, ) expect { Registrations::RegistrationChecker.update_registration_allowed!(update_request, Competition.find(update_request['competition_id']), User.find(update_request['submitted_by'])) }.to raise_error(WcaExceptions::RegistrationError) do |error| - expect(error.error).to eq(Registrations::ErrorCodes::NO_UNRESERVED_SPOTS_REMAINING ) + expect(error.error).to eq(Registrations::ErrorCodes::NO_UNRESERVED_SPOTS_REMAINING) expect(error.status).to eq(:forbidden) end end it 'organizer can accept first-timer' do - expect(true).to eq(false) + update_request = FactoryBot.build( + :update_request, + user_id: first_timer_reg.user.id, + competition_id: first_timer_reg.competition.id, + submitted_by: newcomer_month_comp.organizers.first.id, + competing: { 'status' => 'accepted' }, + ) + + expect { + Registrations::RegistrationChecker.update_registration_allowed!(update_request, Competition.find(update_request['competition_id']), User.find(update_request['submitted_by'])) + }.not_to raise_error end - it 'organizer can accept newcomer who started competing this year)' do - expect(true).to eq(false) + it 'organizer can accept newcomer who started competing this year' do + update_request = FactoryBot.build( + :update_request, + user_id: newcomer_reg.user.id, + competition_id: newcomer_reg.competition.id, + submitted_by: newcomer_month_comp.organizers.first.id, + competing: { 'status' => 'accepted' }, + ) + + expect { + Registrations::RegistrationChecker.update_registration_allowed!(update_request, Competition.find(update_request['competition_id']), User.find(update_request['submitted_by'])) + }.not_to raise_error end end - describe 'reserved newcomer spots are full' + describe 'reserved newcomer spots are full' do + before do + FactoryBot.create_list(:registration, 2, :newcomer, :accepted, competition: newcomer_month_comp) + end + it 'organizer can still accept newcomers if all reserved newcomer spots are full' do - expect(true).to eq(false) + update_request = FactoryBot.build( + :update_request, + user_id: newcomer_reg.user.id, + competition_id: newcomer_reg.competition.id, + submitted_by: newcomer_month_comp.organizers.first.id, + competing: { 'status' => 'accepted' }, + ) + + expect { + Registrations::RegistrationChecker.update_registration_allowed!(update_request, Competition.find(update_request['competition_id']), User.find(update_request['submitted_by'])) + }.not_to raise_error end it 'organizer can accept non-newcomer if all reserved newcomer spots are full' do - expect(true).to eq(false) + update_request = FactoryBot.build( + :update_request, + user_id: non_newcomer_reg.user.id, + competition_id: non_newcomer_reg.competition.id, + submitted_by: newcomer_month_comp.organizers.first.id, + competing: { 'status' => 'accepted' }, + ) + + expect { + Registrations::RegistrationChecker.update_registration_allowed!(update_request, Competition.find(update_request['competition_id']), User.find(update_request['submitted_by'])) + }.not_to raise_error end end it 'organizer cant accept newcomer if competition is full' do - expect(true).to eq(false) + FactoryBot.create_list(:registration, 4, :newcomer, :accepted, competition: newcomer_month_comp) + + update_request = FactoryBot.build( + :update_request, + user_id: newcomer_reg.user.id, + competition_id: newcomer_reg.competition.id, + submitted_by: newcomer_month_comp.organizers.first.id, + competing: { 'status' => 'accepted' }, + ) + + expect { + Registrations::RegistrationChecker.update_registration_allowed!(update_request, Competition.find(update_request['competition_id']), User.find(update_request['submitted_by'])) + }.to raise_error(WcaExceptions::RegistrationError) do |error| + expect(error.error).to eq(Registrations::ErrorCodes::COMPETITOR_LIMIT_REACHED) + expect(error.status).to eq(:forbidden) + end end it 'organizer can accept non-newcomer into a newcomer reserved spot if registration is closed' do - expect(true).to eq(false) + closed_newcomer_comp = FactoryBot.create(:competition, :newcomer_month, :registration_closed) + normal_reg = FactoryBot.create(:registration, competition: closed_newcomer_comp) + FactoryBot.create_list(:registration, 2, :accepted, competition: closed_newcomer_comp) + + update_request = FactoryBot.build( + :update_request, + user_id: normal_reg.user.id, + competition_id: normal_reg.competition.id, + submitted_by: closed_newcomer_comp.organizers.first.id, + competing: { 'status' => 'accepted' }, + ) + + expect { + Registrations::RegistrationChecker.update_registration_allowed!(update_request, Competition.find(update_request['competition_id']), User.find(update_request['submitted_by'])) + }.not_to raise_error end end + end describe '#bulk_update' do describe '#bulk_update_allowed!' do diff --git a/spec/models/competition_spec.rb b/spec/models/competition_spec.rb index acabdfdadf..7b0e9b2170 100644 --- a/spec/models/competition_spec.rb +++ b/spec/models/competition_spec.rb @@ -1613,10 +1613,10 @@ def change_and_check_activities(new_start_date, new_end_date) end it 'doesnt include non-newcomers in non-accepted states' do - non_newcomer_reg1 = FactoryBot.create(:registration, competition: newcomer_month_comp) - non_newcomer_reg1 = FactoryBot.create(:registration, :cancelled, competition: newcomer_month_comp) - non_newcomer_reg1 = FactoryBot.create(:registration, :rejected, competition: newcomer_month_comp) - non_newcomer_reg1 = FactoryBot.create(:registration, :waiting_list, competition: newcomer_month_comp) + FactoryBot.create(:registration, competition: newcomer_month_comp) + FactoryBot.create(:registration, :cancelled, competition: newcomer_month_comp) + FactoryBot.create(:registration, :rejected, competition: newcomer_month_comp) + FactoryBot.create(:registration, :waiting_list, competition: newcomer_month_comp) expect(newcomer_month_comp.registrations.count).to eq(7) expect(newcomer_month_comp.non_newcomers_competing.count).to eq(2) diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 332c26d8c2..d29b08f8cd 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -791,4 +791,21 @@ expect(user.teams_committees_at_least_senior_roles).not_to include(wrt_role) end end + + describe 'newcomer?' do + it 'true for user with no WCA ID' do + user = FactoryBot.create(:user) + expect(user.newcomer?).to eq(true) + end + + it 'true for user with current year WCA ID' do + user = FactoryBot.create(:user, :current_year_wca_id) + expect(user.newcomer?).to eq(true) + end + + it 'false for user with previous year WCA ID' do + user = FactoryBot.create(:user, :wca_id) + expect(user.newcomer?).to eq(false) + end + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 24fa09bf88..2ef2dfcaf3 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -86,7 +86,7 @@ # order dependency and want to debug it, you can fix the order by providing # the seed, which is printed after each run. # --seed 1234 - # config.order = :random + config.order = :random # Seed global randomization in this process using the `--seed` CLI option. # Setting this allows you to use `--seed` to deterministically reproduce From 6543cb771d18d6a2fab21c736cc169cf77afffbd Mon Sep 17 00:00:00 2001 From: Duncan Date: Fri, 6 Dec 2024 13:49:10 +0200 Subject: [PATCH 10/14] corrected mistake in comparison logic --- lib/registrations/registration_checker.rb | 7 +++--- .../registration_checker_spec.rb | 22 ++++++++++++++++++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/lib/registrations/registration_checker.rb b/lib/registrations/registration_checker.rb index cf0ea09622..cb2d33e4be 100644 --- a/lib/registrations/registration_checker.rb +++ b/lib/registrations/registration_checker.rb @@ -179,10 +179,11 @@ def validate_update_status!(new_status, competition, current_user, target_user, competition.registrations.competing_status_accepted.count >= competition.competitor_limit if !target_user.newcomer? && competition.newcomer_reserved_spots > 0 - non_newcomers_competing = competition.registrations.competing_status_accepted.count - competition.newcomers_competing.count - non_newcomer_spots_remaining = competition.competitor_limit - competition.newcomer_reserved_spots_remaining - non_newcomers_competing + available_spots = competition.competitor_limit - competition.registrations.competing_status_accepted.count + newcomer_reserved_spots_remaining = competition.newcomer_reserved_spots - competition.newcomers_competing.count + raise WcaExceptions::RegistrationError.new(:forbidden, Registrations::ErrorCodes::NO_UNRESERVED_SPOTS_REMAINING) if - (non_newcomers_competing >= non_newcomer_spots_remaining) && competition.registration_currently_open? + (available_spots <= newcomer_reserved_spots_remaining) && competition.registration_currently_open? end end diff --git a/spec/lib/registrations/registration_checker_spec.rb b/spec/lib/registrations/registration_checker_spec.rb index f82adb79fe..0a3db237e7 100644 --- a/spec/lib/registrations/registration_checker_spec.rb +++ b/spec/lib/registrations/registration_checker_spec.rb @@ -2279,7 +2279,7 @@ end end - describe '#update_registration_allowed!.reserved newcomer spots' do + describe '#update_registration_allowed!.reserved newcomer spots', :tag do let(:newcomer_month_comp) { FactoryBot.create(:competition, :newcomer_month) } let(:non_newcomer_reg) { FactoryBot.create(:registration, competition: newcomer_month_comp) } let(:newcomer_reg) { FactoryBot.create(:registration, :newcomer, competition: newcomer_month_comp) } @@ -2406,6 +2406,26 @@ Registrations::RegistrationChecker.update_registration_allowed!(update_request, Competition.find(update_request['competition_id']), User.find(update_request['submitted_by'])) }.not_to raise_error end + + it 'takes newcomer registrations into account when calculating spots remaining' do + FactoryBot.create_list(:registration, 2, :accepted, competition: newcomer_month_comp) + FactoryBot.create(:registration, :accepted, :newcomer, competition: newcomer_month_comp) + + update_request = FactoryBot.build( + :update_request, + user_id: non_newcomer_reg.user.id, + competition_id: non_newcomer_reg.competition.id, + submitted_by: newcomer_month_comp.organizers.first.id, + competing: { 'status' => 'accepted' }, + ) + + expect { + Registrations::RegistrationChecker.update_registration_allowed!(update_request, Competition.find(update_request['competition_id']), User.find(update_request['submitted_by'])) + }.to raise_error(WcaExceptions::RegistrationError) do |error| + expect(error.error).to eq(Registrations::ErrorCodes::NO_UNRESERVED_SPOTS_REMAINING) + expect(error.status).to eq(:forbidden) + end + end end end From a31016c399e85927400cb932886f7151abdb1f9c Mon Sep 17 00:00:00 2001 From: Duncan Date: Fri, 6 Dec 2024 13:49:40 +0200 Subject: [PATCH 11/14] removed test tag --- spec/lib/registrations/registration_checker_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/lib/registrations/registration_checker_spec.rb b/spec/lib/registrations/registration_checker_spec.rb index 0a3db237e7..982027f897 100644 --- a/spec/lib/registrations/registration_checker_spec.rb +++ b/spec/lib/registrations/registration_checker_spec.rb @@ -2279,7 +2279,7 @@ end end - describe '#update_registration_allowed!.reserved newcomer spots', :tag do + describe '#update_registration_allowed!.reserved newcomer spots' do let(:newcomer_month_comp) { FactoryBot.create(:competition, :newcomer_month) } let(:non_newcomer_reg) { FactoryBot.create(:registration, competition: newcomer_month_comp) } let(:newcomer_reg) { FactoryBot.create(:registration, :newcomer, competition: newcomer_month_comp) } From c76342c10f47d810b18b8ebca8d96fc722348fc7 Mon Sep 17 00:00:00 2001 From: Duncan <52967253+dunkOnIT@users.noreply.github.com> Date: Fri, 6 Dec 2024 13:52:37 +0200 Subject: [PATCH 12/14] reverted schema.rb changes --- db/schema.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index bd45f69519..d4f004c612 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.2].define(version: 2024_11_26_084446) do +ActiveRecord::Schema[7.2].define(version: 2024_11_18_145843) do create_table "Competitions", id: { type: :string, limit: 32, default: "" }, charset: "utf8mb4", collation: "utf8mb4_unicode_ci", force: :cascade do |t| t.string "name", limit: 50, default: "", null: false t.string "cityName", limit: 50, default: "", null: false From 5eab8976f424e05d375daa31e16c95ca7797e3d3 Mon Sep 17 00:00:00 2001 From: Duncan <52967253+dunkOnIT@users.noreply.github.com> Date: Fri, 6 Dec 2024 13:53:19 +0200 Subject: [PATCH 13/14] more schema.rb reversion --- db/schema.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index d4f004c612..4f5616229b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -82,7 +82,6 @@ t.boolean "forbid_newcomers", default: false, null: false t.string "forbid_newcomers_reason" t.integer "registration_version", default: 0, null: false - t.integer "newcomer_reserved_spots", default: 0, null: false t.index ["cancelled_at"], name: "index_Competitions_on_cancelled_at" t.index ["countryId"], name: "index_Competitions_on_countryId" t.index ["end_date"], name: "index_Competitions_on_end_date" From d5eadf2b4f24f6d9fbb6162e3b4376ab29e62d2f Mon Sep 17 00:00:00 2001 From: Duncan Date: Fri, 6 Dec 2024 13:54:59 +0200 Subject: [PATCH 14/14] removed test tags --- spec/models/competition_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/models/competition_spec.rb b/spec/models/competition_spec.rb index 7b0e9b2170..7fe769cb24 100644 --- a/spec/models/competition_spec.rb +++ b/spec/models/competition_spec.rb @@ -1598,7 +1598,7 @@ def change_and_check_activities(new_start_date, new_end_date) end end - context 'newcomer month competition', :tag do + context 'newcomer month competition' do let(:newcomer_month_comp) { FactoryBot.create(:competition, :newcomer_month) } let!(:newcomer_reg) { FactoryBot.create(:registration, :newcomer, competition: newcomer_month_comp) }