From 9d5825071496ae3b4df5b5f4341ab7df45c279e6 Mon Sep 17 00:00:00 2001 From: Duncan <52967253+dunkOnIT@users.noreply.github.com> Date: Wed, 11 Oct 2023 09:59:20 +0200 Subject: [PATCH] Refactor registration_controller.rb (#250) Several refactors to simplify and consolidate logic in registration controller, as well as related tests and model --- .rubocop.yml | 6 +- app/controllers/application_controller.rb | 8 +- app/controllers/registration_controller.rb | 322 ++++++++++----------- app/helpers/error_codes.rb | 1 - app/models/registration.rb | 17 +- app/worker/registration_processor.rb | 5 +- config/application.rb | 4 +- config/routes.rb | 2 +- docker-compose.test.yml | 2 +- docs/example_payloads/registration.json | 3 - lib/registration_error.rb | 10 + spec/fixtures/patches.json | 130 ++++++--- spec/fixtures/registration.json | 3 - spec/fixtures/registrations.json | 98 +------ spec/rails_helper.rb | 4 +- spec/requests/cancel_registration_spec.rb | 107 +++---- spec/requests/get_registrations_spec.rb | 48 --- spec/requests/post_attendee_spec.rb | 39 ++- spec/requests/update_registration_spec.rb | 8 +- spec/support/dynamoid_reset.rb | 5 +- 20 files changed, 353 insertions(+), 469 deletions(-) create mode 100644 lib/registration_error.rb diff --git a/.rubocop.yml b/.rubocop.yml index 03b29316..5a6cc668 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -11,6 +11,10 @@ AllCops: Bundler/OrderedGems: Enabled: false +Lint/MissingSuper: + Exclude: + - 'lib/registration_error.rb' + Lint/EmptyWhen: Enabled: false @@ -224,4 +228,4 @@ Style/HashSyntax: Style/GlobalVars: AllowedVariables: - $sqs - - $dynamodb \ No newline at end of file + - $dynamodb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f7e7e630..636730b3 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -33,8 +33,12 @@ def performance_profile(&) end end - def render_error(status, error) + def render_error(http_status, error) Metrics.registration_validation_errors_counter.increment - render json: { error: error }, status: status + render json: { error: error }, status: http_status + end + + rescue_from ActionController::ParameterMissing do |e| + render json: { error: ErrorCodes::INVALID_REQUEST_DATA }, status: :bad_request end end diff --git a/app/controllers/registration_controller.rb b/app/controllers/registration_controller.rb index 3a962120..736f761f 100644 --- a/app/controllers/registration_controller.rb +++ b/app/controllers/registration_controller.rb @@ -13,60 +13,67 @@ class RegistrationController < ApplicationController # That's why we should always validate a request first, before taking any other before action # before_actions are triggered in the order they are defined before_action :validate_create_request, only: [:create] - before_action :validate_entry_request, only: [:entry] + before_action :validate_show_request, only: [:entry] before_action :ensure_lane_exists, only: [:create] before_action :validate_list_admin, only: [:list_admin] before_action :validate_update_request, only: [:update] before_action :validate_payment_ticket_request, only: [:payment_ticket] + def create + comment = params["competing"][:comment] || "" + guests = params[:guests] || 0 + + id = SecureRandom.uuid + + step_data = { + attendee_id: "#{@competition_id}-#{@user_id}", + user_id: @user_id, + competition_id: @competition_id, + lane_name: 'competing', + step: 'Event Registration', + step_details: { + registration_status: 'waiting', + event_ids: @event_ids, + comment: comment, + guests: guests, + }, + } + + $sqs.send_message({ + queue_url: @queue_url, + message_body: step_data.to_json, + message_group_id: id, + message_deduplication_id: id, + }) + + render json: { status: 'accepted', message: 'Started Registration Process' }, status: :accepted + end + # For a user to register they need to # 1) Need to actually be the user that they are trying to register # 2) Be Eligible to Compete (complete profile + not banned) # 3) Register for a competition that is open # 4) Register for events that are actually held at the competition # We need to do this in this order, so we don't leak user attributes - def validate_create_request @user_id = registration_params[:user_id] @competition_id = registration_params[:competition_id] @event_ids = registration_params[:competing]["event_ids"] - # This could be split out into a "validate competition exists" method - # Validations could also be restructured to be a bunch of private methods that validators call - @competition = CompetitionApi.get_competition_info(@competition_id) + @competition = get_competition_info! - unless CompetitionApi.competition_exists?(@competition_id) == true - return render_error(:not_found, ErrorCodes::COMPETITION_NOT_FOUND) - end - - unless @current_user == @user_id.to_s || UserApi.can_administer?(@current_user, @competition_id) - Metrics.registration_impersonation_attempt_counter.increment - return render json: { error: ErrorCodes::USER_IMPERSONATION }, status: :unauthorized - end + user_can_create_registration! can_compete, reasons = UserApi.can_compete?(@user_id) - unless can_compete - if reasons == ErrorCodes::USER_IS_BANNED - return render_error(:forbidden, ErrorCodes::USER_IS_BANNED) - else - return render_error(:unauthorized, ErrorCodes::USER_PROFILE_INCOMPLETE) - end - # status = :forbidden - # cannot_register_reason = reasons - end - - if !CompetitionApi.competition_open?(@competition_id) && !(UserApi.can_administer?(@current_user, @competition_id) && @current_user == @user_id.to_s) - # Admin can only pre-regiser for themselves, not for other users - return render_error(:forbidden, ErrorCodes::REGISTRATION_CLOSED) - end - - if @event_ids.empty? || !CompetitionApi.events_held?(@event_ids, @competition_id) - return render_error(:unprocessable_entity, ErrorCodes::INVALID_EVENT_SELECTION) - end - - if params.key?(:guests) && !guests_valid? - render_error(:unprocessable_entity, ErrorCodes::GUEST_LIMIT_EXCEEDED) - end + raise RegistrationError.new(:unauthorized, reasons) unless can_compete + + puts 0 + validate_events! + puts 1 + validate_guests! + puts 2 + rescue RegistrationError => e + render_error(e.http_status, e.error) end # We don't know which lane the user is going to complete first, this ensures that an entry in the DB exists @@ -96,97 +103,16 @@ def ensure_lane_exists end end - def create - comment = params[:comment] || "" - guests = params[:guests] || 0 - - id = SecureRandom.uuid - - step_data = { - attendee_id: "#{@competition_id}-#{@user_id}", - user_id: @user_id, - competition_id: @competition_id, - lane_name: 'competing', - step: 'Event Registration', - step_details: { - registration_status: 'waiting', - event_ids: @event_ids, - comment: comment, - guests: guests, - }, - } - - $sqs.send_message({ - queue_url: @queue_url, - message_body: step_data.to_json, - message_group_id: id, - message_deduplication_id: id, - }) - - render json: { status: 'accepted', message: 'Started Registration Process' }, status: :accepted - end - - # You can either update your own registration or one for a competition you administer - def validate_update_request - @user_id, @competition_id = update_params - @admin_comment = params[:admin_comment] - - # Check if competition exists - if CompetitionApi.competition_exists?(@competition_id) == true - @competition = CompetitionApi.get_competition_info(@competition_id) - else - return render_error(:not_found, ErrorCodes::COMPETITION_NOT_FOUND) - end - - # Check if competition exists - unless registration_exists?(@user_id, @competition_id) - return render_error(:not_found, ErrorCodes::REGISTRATION_NOT_FOUND) - end - - @registration = Registration.find("#{@competition_id}-#{@user_id}") - - # Only the user or an admin can update a user's registration - unless @current_user == @user_id || UserApi.can_administer?(@current_user, @competition_id) - return render_error(:unauthorized, ErrorCodes::USER_IMPERSONATION) - end - - # User must be an admin if they're changing admin properties - admin_fields = [@admin_comment] - if (admin_fields.any? { |field| !(field.nil?) }) && !(UserApi.can_administer?(@current_user, @competition_id)) - return render_error(:unauthorized, ErrorCodes::USER_INSUFFICIENT_PERMISSIONS) - end - - if params.key?(:status) - validate_status_or_render_error - end - - if params.key?(:event_ids) - validate_events_or_render_error - end - - params.key?(:guests) - if params.key?(:guests) && !guests_valid? - return render_error(:unprocessable_entity, ErrorCodes::GUEST_LIMIT_EXCEEDED) - end - - if params.key?(:comment) && !comment_valid? - return render_error(:unprocessable_entity, ErrorCodes::USER_COMMENT_TOO_LONG) - end - - if !params.key?(:comment) && @competition[:competition_info]["force_comment_in_registration"] - render_error(:unprocessable_entity, ErrorCodes::REQUIRED_COMMENT_MISSING) - end - end - def update - status = params[:status] - comment = params[:comment] guests = params[:guests] - event_ids = params[:event_ids] + status = params.dig("competing", "status") + comment = params.dig("competing", "comment") + event_ids = params.dig("competing", "event_ids") + admin_comment = params.dig("competing", "admin_comment") begin registration = Registration.find("#{@competition_id}-#{@user_id}") - updated_registration = registration.update_competing_lane!({ status: status, comment: comment, event_ids: event_ids, admin_comment: @admin_comment, guests: guests }) + updated_registration = registration.update_competing_lane!({ status: status, comment: comment, event_ids: event_ids, admin_comment: admin_comment, guests: guests }) render json: { status: 'ok', registration: { user_id: updated_registration["user_id"], registered_event_ids: updated_registration.registered_event_ids, @@ -204,33 +130,43 @@ def update end end - # You can either view your own registration or one for a competition you administer - def validate_entry_request - @user_id, @competition_id = entry_params + # You can either update your own registration or one for a competition you administer + def validate_update_request + @user_id = params[:user_id] + @competition_id = params[:competition_id] - unless @current_user == @user_id || UserApi.can_administer?(@current_user, @competition_id) - render_error(:unauthorized, ErrorCodes::USER_IMPERSONATION) + @competition = get_competition_info! + @registration = Registration.find("#{@competition_id}-#{@user_id}") + + raise RegistrationError.new(:unauthorized, ErrorCodes::USER_INSUFFICIENT_PERMISSIONS) unless is_admin_or_current_user? + raise RegistrationError.new(:unauthorized, ErrorCodes::USER_INSUFFICIENT_PERMISSIONS) if admin_fields_present? && !UserApi.can_administer?(@current_user, @competition_id) + raise RegistrationError.new(:unprocessable_entity, ErrorCodes::GUEST_LIMIT_EXCEEDED) if params.key?(:guests) && !guests_valid? + + if params.key?(:competing) + validate_status! if params["competing"].key?(:status) + validate_events! if params["competing"].key?(:event_ids) + raise RegistrationError.new(:unprocessable_entity, ErrorCodes::USER_COMMENT_TOO_LONG) if params["competing"].key?(:comment) && !comment_valid? + raise RegistrationError.new(:unprocessable_entity, ErrorCodes::REQUIRED_COMMENT_MISSING) if + !params["competing"].key?(:comment) && @competition[:competition_info]["force_comment_in_registration"] end + rescue Dynamoid::Errors::RecordNotFound + render_error(:not_found, ErrorCodes::REGISTRATION_NOT_FOUND) + rescue RegistrationError => e + render_error(e.http_status, e.error) end - def entry + def show registration = get_single_registration(@user_id, @competition_id) render json: { registration: registration, status: 'ok' } rescue Dynamoid::Errors::RecordNotFound render json: { registration: {}, status: 'ok' } end - def validate_payment_ticket_request - competition_id = params[:competition_id] - unless CompetitionApi.uses_wca_payment?(competition_id) - Metrics.registration_validation_errors_counter.increment - render json: { error: ErrorCodes::PAYMENT_NOT_ENABLED }, status: :forbidden - end - @registration = Registration.find("#{competition_id}-#{@current_user}") - if @registration.competing_state.nil? - Metrics.registration_validation_errors_counter.increment - render json: { error: ErrorCodes::PAYMENT_NOT_READY }, status: :forbidden - end + # You can either view your own registration or one for a competition you administer + def validate_show_registration + @user_id, @competition_id = entry_params + raise RegistrationError.new(:unauthorized, ErrorCodes::USER_INSUFFICIENT_PERMISSIONS) unless + @current_user == @user_id || UserApi.can_administer?(@current_user, @competition_id) end def payment_ticket @@ -245,19 +181,17 @@ def payment_ticket render json: { client_secret_id: ticket, connected_account_id: account_id } end - def list - competition_id = list_params - competition_info = CompetitionApi.get_competition_info(competition_id) + def validate_payment_ticket_request + competition_id = params[:competition_id] + render_error(:forbidden, ErrorCodes::PAYMENT_NOT_ENABLED) unless CompetitionApi.uses_wca_payment?(competition_id) - if competition_info[:competition_exists?] == false - return render json: { error: competition_info[:error] }, status: competition_info[:status] - end + @registration = Registration.find("#{competition_id}-#{@current_user}") + render_error(:forbidden, ErrorCodes::PAYMENT_NOT_READY) if @registration.competing_state.nil? + end + def list + competition_id = list_params registrations = get_registrations(competition_id, only_attending: true) - - if registrations.count == 0 && competition_info[:error] == ErrorCodes::COMPETITION_API_5XX - return render json: { error: competition_info[:error] }, status: competition_info[:status] - end render json: registrations rescue StandardError => e # Render an error response @@ -272,19 +206,16 @@ def validate_list_admin @competition_id = list_params unless UserApi.can_administer?(@current_user, @competition_id) - Metrics.registration_validation_errors_counter.increment - render json: { error: ErrorCodes::USER_INSUFFICIENT_PERMISSIONS }, status: 401 + render_error(:unauthorized, ErrorCodes::USER_INSUFFICIENT_PERMISSIONS) end end def list_admin registrations = get_registrations(@competition_id) - - # Render a success response render json: registrations rescue StandardError => e - # Render an error response puts e + # Is there a reason we aren't using an error code here? Metrics.registration_dynamodb_errors_counter.increment render json: { error: "Error getting registrations #{e}" }, status: :internal_server_error @@ -298,12 +229,13 @@ def registration_params params end - def entry_params - params.require([:user_id, :competition_id]) + def show_params + params.require([:user_id, :competition_id, :competing]) end def update_params params.require([:user_id, :competition_id]) + params.permit(:guests, competing: [:status, :comment, { event_ids: [] }, :admin_comment]) end def list_params @@ -349,43 +281,83 @@ def registration_exists?(user_id, competition_id) false end + def validate_guests! + raise RegistrationError.new(:unprocessable_entity, ErrorCodes::GUEST_LIMIT_EXCEEDED) if params.key?(:guests) && !guests_valid? + end + def guests_valid? @competition[:competition_info]["guest_entry_status"] != "restricted" || @competition[:competition_info]["guests_per_registration_limit"] >= params[:guests] end def comment_valid? - params[:comment].length <= 240 + params["competing"][:comment].length <= 240 end - def validate_events_or_render_error - event_ids = params[:event_ids] - status = params.key?(:status) ? params[:status] : @registration.competing_status + def validate_events! + event_ids = params["competing"][:event_ids] - # Events list can only be empty if the status is deleted - if event_ids == [] && status != "deleted" - return render_error(:unprocessable_entity, ErrorCodes::INVALID_EVENT_SELECTION) + if defined?(@registration) + status = params["competing"].key?(:status) ? params["competing"][:status] : @registration.competing_status + else + status = "pending" # Assign it a placeholder status so that we don't throw errors when querying status end - if !CompetitionApi.events_held?(event_ids, @competition_id) && status != "deleted" - return render_error(:unprocessable_entity, ErrorCodes::INVALID_EVENT_SELECTION) - end + # Events list can only be empty if the status is cancelled - this allows for edge cases where an API user might send an empty event list, + # or admin might want to remove events + raise RegistrationError.new(:unprocessable_entity, ErrorCodes::INVALID_EVENT_SELECTION) if event_ids == [] && status != "cancelled" + + # Event submitted must be held at the competition (unless the status is cancelled) + # TODO: Do we have an edge case where someone can submit events not held at the competition if their status is cancelled? Shouldn't we say the events be a subset or empty? + # like this: if !CompetitionApi.events_held?(event_ids, @competition_id) && event_ids != [] + raise RegistrationError.new(:unprocessable_entity, ErrorCodes::INVALID_EVENT_SELECTION) if !CompetitionApi.events_held?(event_ids, @competition_id) + # Events can't be changed outside the edit_events deadline + # TODO: Should an admin be able to override this? events_edit_deadline = Time.parse(@competition[:competition_info]["event_change_deadline_date"]) - render_error(:forbidden, ErrorCodes::EVENT_EDIT_DEADLINE_PASSED) if events_edit_deadline < Time.now + raise RegistrationError.new(:forbidden, ErrorCodes::EVENT_EDIT_DEADLINE_PASSED) if events_edit_deadline < Time.now end - def validate_status_or_render_error - unless Registration::REGISTRATION_STATES.include?(params[:status]) - return render_error(:unprocessable_entity, ErrorCodes::INVALID_REQUEST_DATA) - end + def admin_fields_present? + # There could be different admin fields in different lanes - define the admin fields per lane and check each + competing_admin_fields = ["admin_comment"] - if Registration::ADMIN_ONLY_STATES.include?(params[:status]) && !UserApi.can_administer?(@current_user, @competition_id) - return render_error(:unauthorized, ErrorCodes::USER_INSUFFICIENT_PERMISSIONS) - end + params.key?("competing") && params["competing"].keys.any? { |key| competing_admin_fields.include?(key) } + end + + def user_can_create_registration! + # Only an admin or the user themselves can create a registration for the user + raise RegistrationError.new(:unauthorized, ErrorCodes::USER_INSUFFICIENT_PERMISSIONS) unless is_admin_or_current_user? + + # Only admins can register when registration is closed, and they can only register for themselves - not for other users + raise RegistrationError.new(:forbidden, ErrorCodes::REGISTRATION_CLOSED) unless CompetitionApi.competition_open?(@competition_id) || admin_modifying_own_registration? + end + + def admin_modifying_own_registration? + UserApi.can_administer?(@current_user, @competition_id) && (@current_user == @user_id.to_s) + end + + def is_admin_or_current_user? + # Only an admin or the user themselves can create a registration for the user + # One case where admins need to create registrations for users is if a 3rd-party registration system is being used, and registration data is being + # passed to the Registration Service from it + (@current_user == @user_id.to_s) || UserApi.can_administer?(@current_user, @competition_id) + end + + def validate_status! + raise RegistrationError.new(:unprocessable_entity, ErrorCodes::INVALID_REQUEST_DATA) unless Registration::REGISTRATION_STATES.include?(params["competing"][:status]) + + raise RegistrationError.new(:unauthorized, ErrorCodes::USER_INSUFFICIENT_PERMISSIONS) if + Registration::ADMIN_ONLY_STATES.include?(params["competing"][:status]) && !UserApi.can_administer?(@current_user, @competition_id) competitor_limit = @competition[:competition_info]["competitor_limit"] - if params[:status] == 'accepted' && Registration.count > competitor_limit - render_error(:forbidden, ErrorCodes::COMPETITOR_LIMIT_REACHED) + raise RegistrationError.new(:forbidden, ErrorCodes::COMPETITOR_LIMIT_REACHED) if params["competing"][:status] == 'accepted' && Registration.count > competitor_limit + end + + def get_competition_info! + if CompetitionApi.competition_exists?(@competition_id) + CompetitionApi.get_competition_info(@competition_id) + else + raise RegistrationError.new(:not_found, ErrorCodes::COMPETITION_NOT_FOUND) end end end diff --git a/app/helpers/error_codes.rb b/app/helpers/error_codes.rb index c1991944..d9c76850 100644 --- a/app/helpers/error_codes.rb +++ b/app/helpers/error_codes.rb @@ -11,7 +11,6 @@ module ErrorCodes COMPETITION_API_5XX = -1001 # User Errors - USER_IMPERSONATION = -2000 USER_IS_BANNED = -2001 USER_PROFILE_INCOMPLETE = -2002 USER_INSUFFICIENT_PERMISSIONS = -2003 diff --git a/app/models/registration.rb b/app/models/registration.rb index 6b90ae39..0ed24b3a 100644 --- a/app/models/registration.rb +++ b/app/models/registration.rb @@ -11,22 +11,22 @@ class Registration table name: "registrations", capacity_mode: nil, key: :attendee_id end - REGISTRATION_STATES = %w[pending waiting_list accepted deleted].freeze - ADMIN_ONLY_STATES = %w[pending waiting_list accepted].freeze + REGISTRATION_STATES = %w[pending waiting_list accepted cancelled].freeze + ADMIN_ONLY_STATES = %w[pending waiting_list accepted].freeze # Only admins are allowed to change registration state to one of these states # Returns all event ids irrespective of registration status def event_ids lanes.filter_map { |x| x.lane_details["event_details"].pluck("event_id") if x.lane_name == "competing" }[0] end - # Returns id's of the events with a non-deleted state + # Returns id's of the events with a non-cancelled state def registered_event_ids event_ids = [] competing_lane = lanes.find { |x| x.lane_name == "competing" } competing_lane.lane_details["event_details"].each do |event| - if event["event_registration_state"] != "deleted" + if event["event_registration_state"] != "cancelled" event_ids << event["event_id"] end end @@ -63,13 +63,7 @@ def payment_ticket lanes.filter_map { |x| x.lane_details["payment_intent_client_secret"] if x.lane_name == "payment" }[0] end - def competing_state - lane_states[:competing] - end - def update_competing_lane!(update_params) - lane_states[:competing] = update_params[:status] if update_params[:status].present? - updated_lanes = lanes.map do |lane| if lane.lane_name == "competing" @@ -87,7 +81,7 @@ def update_competing_lane!(update_params) lane.lane_details["comment"] = update_params[:comment] if update_params[:comment].present? lane.lane_details["guests"] = update_params[:guests] if update_params[:guests].present? lane.lane_details["admin_comment"] = update_params[:admin_comment] if update_params[:admin_comment].present? - if update_params[:event_ids].present? && update_params[:status] != "deleted" + if update_params[:event_ids].present? && update_params[:status] != "cancelled" lane.update_events(update_params[:event_ids]) end end @@ -112,7 +106,6 @@ def init_payment_lane(amount, currency_code, client_secret) field :competition_id, :string field :is_attending, :boolean field :hide_name_publicly, :boolean - field :lane_states, :map field :lanes, :array, of: Lane global_secondary_index hash_key: :user_id, projected_attributes: :all diff --git a/app/worker/registration_processor.rb b/app/worker/registration_processor.rb index 2dd57bd6..e1e77fa8 100644 --- a/app/worker/registration_processor.rb +++ b/app/worker/registration_processor.rb @@ -45,11 +45,10 @@ def lane_init(competition_id, user_id) def event_registration(competition_id, user_id, event_ids, comment, guests) registration = Registration.find("#{competition_id}-#{user_id}") competing_lane = LaneFactory.competing_lane(event_ids, comment, guests) - competing_lane_state = { "competing" => "incoming" } if registration.lanes.nil? - registration.update_attributes(lanes: [competing_lane], lane_states: competing_lane_state) + registration.update_attributes(lanes: [competing_lane]) else - registration.update_attributes(lanes: registration.lanes.append(competing_lane), lane_states: competing_lane_state) + registration.update_attributes(lanes: registration.lanes.append(competing_lane)) end end end diff --git a/config/application.rb b/config/application.rb index 3dd2a2cd..17695ce0 100644 --- a/config/application.rb +++ b/config/application.rb @@ -12,7 +12,9 @@ module WcaRegistration class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. config.load_defaults 7.0 - config.autoload_paths << "#{root}/lib/**" + + config.autoload_paths += Dir["#{config.root}/lib"] + # Only loads a smaller set of middleware suitable for API only apps. # Middleware like session, flash, cookies can be added back manually. # Skip views, helpers and assets when generating a new resource. diff --git a/config/routes.rb b/config/routes.rb index 599c474a..0c53f0f6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -7,7 +7,7 @@ end get '/healthcheck', to: 'healthcheck#index' - get '/api/v1/register', to: 'registration#entry' + get '/api/v1/register', to: 'registration#show' post '/api/v1/register', to: 'registration#create' patch '/api/v1/register', to: 'registration#update' get '/api/v1/registrations/:competition_id/admin', to: 'registration#list_admin' diff --git a/docker-compose.test.yml b/docker-compose.test.yml index c8929814..e7166622 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -20,7 +20,7 @@ services: tty: true command: > bash -c 'bundle install && yarn install && bin/rake db:seed && - bundle exec rspec -e PASSING' + RAILS_ENV=test bundle exec rspec -e PASSING' networks: - wca-registration depends_on: diff --git a/docs/example_payloads/registration.json b/docs/example_payloads/registration.json index 5b8e0a24..9bc24c36 100644 --- a/docs/example_payloads/registration.json +++ b/docs/example_payloads/registration.json @@ -3,9 +3,6 @@ "competition_id":"CubingZANationalChampionship2023", "user_id":"158816", "is_attending":"True", - "lane_states":{ - "competitor":"accepted", - }, "lanes":[{ "lane_name":"competitor", "lane_state":"Accepted", diff --git a/lib/registration_error.rb b/lib/registration_error.rb new file mode 100644 index 00000000..eaa93673 --- /dev/null +++ b/lib/registration_error.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class RegistrationError < StandardError + attr_reader :http_status, :error + + def initialize(http_status, error) + @http_status = http_status + @error = error + end +end diff --git a/spec/fixtures/patches.json b/spec/fixtures/patches.json index cd306474..e6ce9859 100644 --- a/spec/fixtures/patches.json +++ b/spec/fixtures/patches.json @@ -2,27 +2,37 @@ "800-cancel-no-reg": { "user_id":"800", "competition_id":"CubingZANationalChampionship2023", - "status":"deleted" + "competing": { + "status":"cancelled" + } }, "816-cancel-bad-comp": { "user_id":"158816", "competition_id":"InvalidCompID", - "status":"deleted" + "competing": { + "status":"cancelled" + } }, "820-missing-comment": { "user_id":"158820", "competition_id":"LazarilloOpen2024", - "event_ids":["333", "333bf", "444"] + "competing": { + "event_ids":["333", "333bf", "444"] + } }, "820-delayed-update": { "user_id":"158820", "competition_id":"LazarilloOpen2023", - "event_ids":["333", "333bf", "444"] + "competing": { + "event_ids":["333", "333bf", "444"] + } }, "816-comment-update": { "user_id":"158816", "competition_id":"CubingZANationalChampionship2023", - "comment":"updated registration comment" + "competing": { + "comment":"updated registration comment" + } }, "816-guest-update": { "user_id":"158816", @@ -32,43 +42,59 @@ "816-cancel-full-registration": { "user_id":"158816", "competition_id":"CubingZANationalChampionship2023", - "status":"deleted" + "competing": { + "status":"cancelled" + } }, "816-cancel-and-change-events": { "user_id":"158816", "competition_id":"CubingZANationalChampionship2023", - "status":"deleted", - "event_ids":["555","666","777"] + "competing": { + "status":"cancelled", + "event_ids":["555","666","777"] + } }, "816-events-update": { "user_id":"158816", "competition_id":"CubingZANationalChampionship2023", - "event_ids":["333", "333mbf", "555","666","777"] + "competing": { + "event_ids":["333", "333mbf", "555","666","777"] + } }, "816-status-update-1": { "user_id":"158816", "competition_id":"CubingZANationalChampionship2023", - "status":"pending" + "competing": { + "status":"pending" + } }, "816-status-update-2": { "user_id":"158816", "competition_id":"CubingZANationalChampionship2023", - "status":"waiting_list" + "competing": { + "status":"waiting_list" + } }, "816-status-update-3": { "user_id":"158816", "competition_id":"CubingZANationalChampionship2023", - "status":"bad_status_name" + "competing": { + "status":"bad_status_name" + } }, "817-comment-update": { "user_id":"158817", "competition_id":"CubingZANationalChampionship2023", - "comment":"updated registration comment - had no comment before" + "competing": { + "comment":"updated registration comment - had no comment before" + } }, "817-comment-update-2": { "user_id":"158817", "competition_id":"CubingZANationalChampionship2023", - "comment":"comment longer than 240 characterscomment longer than 240 characterscomment longer than 240 characterscomment longer than 240 characterscomment longer than 240 characterscomment longer than 240 characterscomment longer than 240 characterscomment longer than 240 characters" + "competing": { + "comment":"comment longer than 240 characterscomment longer than 240 characterscomment longer than 240 characterscomment longer than 240 characterscomment longer than 240 characterscomment longer than 240 characterscomment longer than 240 characterscomment longer than 240 characters" + } }, "817-guest-update": { "user_id":"158817", @@ -83,94 +109,128 @@ "817-events-update": { "user_id":"158817", "competition_id":"CubingZANationalChampionship2023", - "event_ids":["333"] + "competing": { + "event_ids":["333"] + } }, "817-events-update-2": { "user_id":"158817", "competition_id":"CubingZANationalChampionship2023", - "event_ids":[] + "competing": { + "event_ids":[] + } }, "817-events-update-4": { "user_id":"158817", "competition_id":"CubingZANationalChampionship2023", - "status":"deleted", - "event_ids":[] + "competing": { + "status":"cancelled", + "event_ids":[] + } }, "817-events-update-5": { "user_id":"158817", "competition_id":"CubingZANationalChampionship2023", - "event_ids":["333", "333mbf", "333fm"] + "competing": { + "event_ids":["333", "333mbf", "333fm"] + } }, "817-events-update-6": { "user_id":"158817", "competition_id":"CubingZANationalChampionship2023", - "event_ids":["333", "333mbf", "888"] + "competing": { + "event_ids":["333", "333mbf", "888"] + } }, "817-cancel-full-registration": { "user_id":"158817", "competition_id":"CubingZANationalChampionship2023", - "status":"deleted" + "competing": { + "status":"cancelled" + } }, "817-status-update-1": { "user_id":"158817", "competition_id":"CubingZANationalChampionship2023", - "status":"accepted" + "competing": { + "status":"accepted" + } }, "817-status-update-2": { "user_id":"158817", "competition_id":"CubingZANationalChampionship2023", - "status":"waiting_list" + "competing": { + "status":"waiting_list" + } }, "818-cancel-full-registration": { "user_id":"158818", "competition_id":"CubingZANationalChampionship2023", - "status":"deleted" + "competing": { + "status":"cancelled" + } }, "819-cancel-full-registration": { "user_id":"158819", "competition_id":"CubingZANationalChampionship2023", - "status":"deleted" + "competing": { + "status":"cancelled" + } }, "819-status-update-1": { "user_id":"158819", "competition_id":"CubingZANationalChampionship2023", - "status":"accepted" + "competing": { + "status":"accepted" + } }, "819-status-update-2": { "user_id":"158819", "competition_id":"CubingZANationalChampionship2023", - "status":"pending" + "competing": { + "status":"pending" + } }, "819-status-update-3": { "user_id":"158819", "competition_id":"CubingZANationalChampionship2024", - "status":"accepted" + "competing": { + "status":"accepted" + } }, "823-cancel-full-registration": { "user_id":"158823", "competition_id":"CubingZANationalChampionship2023", - "status":"deleted" + "competing": { + "status":"cancelled" + } }, "823-cancel-wrong-lane": { "attendee_id":"CubingZANationalChampionship2023-158823", - "lane_states":{ - "staffing":"cancelled" + "staffing":{ + "status":"cancelled" } }, "816-cancel-full-registration_2": { "user_id":"158816", "competition_id":"CubingZANationalChampionship2023", - "status":"deleted", - "admin_comment":"registration delete comment" + "competing": { + "status":"cancelled", + "admin_comment":"registration delete comment" + } }, "073-cancel-full-registration": { "user_id":"15073", "competition_id":"BrizZonSylwesterOpen2023", - "status":"deleted" + "competing": { + "status":"cancelled" + } }, "1-cancel-full-registration": { "user_id":"1", "competition_id":"CubingZANationalChampionship2023", - "status":"deleted" + "competing": { + "status":"cancelled" + } } } diff --git a/spec/fixtures/registration.json b/spec/fixtures/registration.json index 5b8e0a24..9bc24c36 100644 --- a/spec/fixtures/registration.json +++ b/spec/fixtures/registration.json @@ -3,9 +3,6 @@ "competition_id":"CubingZANationalChampionship2023", "user_id":"158816", "is_attending":"True", - "lane_states":{ - "competitor":"accepted", - }, "lanes":[{ "lane_name":"competitor", "lane_state":"Accepted", diff --git a/spec/fixtures/registrations.json b/spec/fixtures/registrations.json index c9235ba4..eca8bf93 100644 --- a/spec/fixtures/registrations.json +++ b/spec/fixtures/registrations.json @@ -4,9 +4,6 @@ "competition_id":"CubingZANationalChampionship2023", "user_id":"158816", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -46,9 +43,6 @@ "competition_id":"CubingZANationalChampionship2023", "user_id":"1", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -86,9 +80,6 @@ "attendee_id":"CubingZANationalChampionship2023-158817", "competition_id":"CubingZANationalChampionship2023", "user_id":"158817", - "lane_states":{ - "competing":"pending" - }, "lanes":[{ "lane_name":"competing", "lane_state":"pending", @@ -124,9 +115,6 @@ { "attendee_id":"CubingZANationalChampionship2023-158818", "competition_id":"CubingZANationalChampionship2023", - "lane_states":{ - "competitor":"update_pending" - }, "lanes":[{ "lane_name":"competing", "lane_state":"update_pending", @@ -164,9 +152,6 @@ "competition_id":"CubingZANationalChampionship2023", "is_attending":false, "user_id":"158819", - "lane_states":{ - "competing":"waiting_list" - }, "lanes":[{ "lane_name":"competing", "lane_state":"waiting_list", @@ -203,9 +188,6 @@ "competition_id":"CubingZANationalChampionship2023", "user_id":"158820", "hide_name_publicly": false, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -239,9 +221,6 @@ }, { "attendee_id":"CubingZANationalChampionship2023-158821", - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -276,18 +255,12 @@ { "attendee_id":"CubingZANationalChampionship2023-158822", "competition_id":"CubingZANationalChampionship2023", - "user_id":"158822", - "lane_states":{ - "competing":"accepted" - } + "user_id":"158822" }, { "attendee_id":"CubingZANationalChampionship2023-158823", "competition_id":"CubingZANationalChampionship2023", "user_id":"158823", - "lane_states":{ - "competing":"cancelled" - }, "lanes":[{ "lane_name":"competing", "lane_state":"cancelled", @@ -323,9 +296,6 @@ "attendee_id":"CubingZANationalChampionship2023-158824", "competition_id":"CubingZANationalChampionship2023", "user_id":"158824", - "lane_states":{ - "competing":"pending" - }, "lanes":[{ "lane_name":"competing", "lane_state":"pending", @@ -360,9 +330,6 @@ "competition_id":"WinchesterWeeknightsIV2023", "user_id":"158816", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -401,9 +368,6 @@ "competition_id":"WinchesterWeeknightsIV2023", "user_id":"158817", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -442,9 +406,6 @@ "competition_id":"WinchesterWeeknightsIV2023", "user_id":"158818", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -483,9 +444,6 @@ "competition_id":"BangaloreCubeOpenJuly2023", "user_id":"158818", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -524,9 +482,6 @@ "competition_id":"BangaloreCubeOpenJuly2023", "user_id":"158819", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -565,9 +520,6 @@ "competition_id":"LazarilloOpen2023", "user_id":"158820", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -606,9 +558,6 @@ "competition_id":"LazarilloOpen2023", "user_id":"158821", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -647,9 +596,6 @@ "competition_id":"LazarilloOpen2023", "user_id":"158822", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -688,9 +634,6 @@ "competition_id":"LazarilloOpen2023", "user_id":"158823", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -729,9 +672,6 @@ "competition_id":"BrizZonSylwesterOpen2023", "user_id":"158817", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -769,9 +709,6 @@ "attendee_id":"InvalidCompID-158817", "competition_id":"InvalidCompID", "user_id":"158817", - "lane_states":{ - "competing":"pending" - }, "lanes":[{ "lane_name":"competing", "lane_state":"pending", @@ -808,9 +745,6 @@ "attendee_id":"CubingZANationalChampionship2023-209943", "competition_id":"CubingZANationalChampionship2023", "user_id":"209943", - "lane_states":{ - "competing":"pending" - }, "lanes":[{ "lane_name":"competing", "lane_state":"pending", @@ -847,9 +781,6 @@ "attendee_id":"CubingZANationalChampionship2023-999999", "competition_id":"CubingZANationalChampionship2023", "user_id":"999999", - "lane_states":{ - "competing":"pending" - }, "lanes":[{ "lane_name":"competing", "lane_state":"pending", @@ -886,9 +817,6 @@ "attendee_id":"CubingZANationalChampionship2023-158201", "competition_id":"CubingZANationalChampionship2023", "user_id":"158201", - "lane_states":{ - "competing":"pending" - }, "lanes":[{ "lane_name":"competing", "lane_state":"pending", @@ -925,9 +853,6 @@ "attendee_id":"CubingZANationalChampionship2023-158202", "competition_id":"CubingZANationalChampionship2023", "user_id":"158202", - "lane_states":{ - "competing":"pending" - }, "lanes":[{ "lane_name":"competing", "lane_state":"pending", @@ -965,9 +890,6 @@ "competition_id":"BrizZonSylwesterOpen2023", "user_id":"15073", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -1006,9 +928,6 @@ "competition_id":"BrizZonSylwesterOpen2023", "user_id":"15074", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -1047,9 +966,6 @@ "competition_id":"LazarilloOpen2024", "user_id":"158820", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -1088,9 +1004,6 @@ "competition_id":"CubingZANationalChampionship2024", "user_id":"158816", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -1130,9 +1043,6 @@ "competition_id":"CubingZANationalChampionship2024", "user_id":"158817", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -1172,9 +1082,6 @@ "competition_id":"CubingZANationalChampionship2024", "user_id":"158818", "is_attending":true, - "lane_states":{ - "competing":"accepted" - }, "lanes":[{ "lane_name":"competing", "lane_state":"accepted", @@ -1214,9 +1121,6 @@ "competition_id":"CubingZANationalChampionship2024", "user_id":"158819", "is_attending":true, - "lane_states":{ - "competing":"pending" - }, "lanes":[{ "lane_name":"competing", "lane_state":"pending", diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index b07fd5dc..33f411de 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -6,7 +6,7 @@ require 'spec_helper' require 'rspec/rails' -ENV['RAILS_ENV'] ||= 'test' # Not sure what this code is doing / if we need it +ENV['RAILS_ENV'] = 'test' # TODO: Figure out why this isn't working? (We have to manually say RAILS_ENV=test when running rspec) # Prevent database truncation if the environment is production abort("The Rails environment is running in production mode!") if Rails.env.production? @@ -69,7 +69,7 @@ # config.filter_gems_from_backtrace("gem name") # Reset dynamodb before each test - unless Rails.env.production? + if Rails.env.test? config.before(:each) do DynamoidReset.all end diff --git a/spec/requests/cancel_registration_spec.rb b/spec/requests/cancel_registration_spec.rb index 857ad915..f538ff2f 100644 --- a/spec/requests/cancel_registration_spec.rb +++ b/spec/requests/cancel_registration_spec.rb @@ -62,16 +62,15 @@ updated_registration = Registration.find("#{registration_update['competition_id']}-#{registration_update['user_id']}") puts updated_registration.inspect - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") end end - response '200', 'PASSING cancel accepted registration, event statuses change to "deleted"' do + response '200', 'PASSING cancel accepted registration, event statuses change to "cancelled"' do let(:registration_update) { @cancellation_816 } let(:Authorization) { @jwt_816 } @@ -83,7 +82,7 @@ updated_registration = Registration.find("#{registration_update['competition_id']}-#{registration_update['user_id']}") puts updated_registration.inspect updated_registration.event_details.each do |event| - expect(event["event_registration_state"]).to eq("deleted") + expect(event["event_registration_state"]).to eq("cancelled") end end end @@ -103,12 +102,11 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") end end @@ -127,12 +125,11 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") end end @@ -151,12 +148,11 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") end end @@ -175,12 +171,11 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") end end end @@ -206,12 +201,11 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") end end @@ -230,12 +224,11 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") end end @@ -254,14 +247,13 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") - expect(updated_registration.admin_comment).to eq(registration_update["admin_comment"]) + expect(updated_registration.admin_comment).to eq(registration_update["competing"]["admin_comment"]) end end @@ -280,12 +272,11 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") end end @@ -304,12 +295,11 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") end end @@ -328,12 +318,11 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") end end @@ -352,12 +341,11 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") end end @@ -376,12 +364,11 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") end end @@ -400,12 +387,11 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") end end @@ -424,14 +410,13 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") - expect(updated_registration.admin_comment).to eq(registration_update["admin_comment"]) + expect(updated_registration.admin_comment).to eq(registration_update["competing"]["admin_comment"]) end end @@ -450,12 +435,11 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") end end @@ -474,12 +458,11 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") end end @@ -498,12 +481,11 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") end end @@ -522,12 +504,11 @@ puts updated_registration.inspect expect(response_data["registered_event_ids"]).to eq([]) - expect(response_data["registration_status"]).to eq("deleted") + expect(response_data["registration_status"]).to eq("cancelled") # Make sure the registration stored in the dabatase contains teh values we expect expect(updated_registration.registered_event_ids).to eq([]) - expect(updated_registration.competing_status).to eq("deleted") - expect(updated_registration[:lane_states][:competing]).to eq("deleted") + expect(updated_registration.competing_status).to eq("cancelled") end end end @@ -553,7 +534,7 @@ response '401', 'PASSING admin submits cancellation for a comp they arent an admin for' do # This could return an insufficient permissions error instead if we want to somehow determine who should be an admin - error_response = { error: ErrorCodes::USER_IMPERSONATION }.to_json + error_response = { error: ErrorCodes::USER_INSUFFICIENT_PERMISSIONS }.to_json let(:registration_update) { @cancellation_073 } let(:Authorization) { @organizer_token } @@ -563,7 +544,7 @@ end response '401', 'PASSING user submits a cancellation for a different user' do - error_response = { error: ErrorCodes::USER_IMPERSONATION }.to_json + error_response = { error: ErrorCodes::USER_INSUFFICIENT_PERMISSIONS }.to_json let(:registration_update) { @cancellation_816 } let(:Authorization) { @jwt_817 } diff --git a/spec/requests/get_registrations_spec.rb b/spec/requests/get_registrations_spec.rb index 0a7a774f..6f36ed8a 100644 --- a/spec/requests/get_registrations_spec.rb +++ b/spec/requests/get_registrations_spec.rb @@ -45,7 +45,6 @@ let!(:competition_id) { @empty_comp } run_test! do |response| - assert_requested :get, "#{@base_comp_url}#{competition_id}", times: 1 body = JSON.parse(response.body) expect(body).to eq([]) end @@ -56,7 +55,6 @@ let!(:competition_id) { @registrations_exist_comp_500 } run_test! do |response| - assert_requested :get, "#{@base_comp_url}#{competition_id}", times: 1 body = JSON.parse(response.body) expect(body.length).to eq(3) end @@ -68,58 +66,12 @@ let!(:competition_id) { @registrations_exist_comp_502 } run_test! do |response| - assert_requested :get, "#{@base_comp_url}#{competition_id}", times: 1 body = JSON.parse(response.body) expect(body.length).to eq(2) end end end end - - context 'fail responses' do - include_context 'competition information' - include_context 'database seed' - - context 'competition_id not found by Competition Service' do - registration_error_json = { error: ErrorCodes::COMPETITION_NOT_FOUND }.to_json - - response '404', ' -> PASSING Competition ID doesnt exist' do - schema '$ref' => '#/components/schemas/error_response' - let(:competition_id) { @error_comp_404 } - - run_test! do |response| - assert_requested :get, "#{@base_comp_url}#{competition_id}", times: 1 - expect(response.body).to eq(registration_error_json) - end - end - end - - context '500 - competition service not available (500) and no registrations in our database for competition_id' do - registration_error_json = { error: ErrorCodes::COMPETITION_API_5XX }.to_json - response '500', ' -> PASSING Competition service unavailable - 500 error' do - schema '$ref' => '#/components/schemas/error_response' - let!(:competition_id) { @error_comp_500 } - - run_test! do |response| - assert_requested :get, "#{@base_comp_url}#{competition_id}", times: 1 - expect(response.body).to eq(registration_error_json) - end - end - end - - context '502 - competition service not available - 502, and no registration for competition ID' do - registration_error_json = { error: ErrorCodes::COMPETITION_API_5XX }.to_json - response '502', ' -> PASSING Competition service unavailable - 502 error' do - schema '$ref' => '#/components/schemas/error_response' - let!(:competition_id) { @error_comp_502 } - - run_test! do |response| - assert_requested :get, "#{@base_comp_url}#{competition_id}", times: 1 - expect(response.body).to eq(registration_error_json) - end - end - end - end end end diff --git a/spec/requests/post_attendee_spec.rb b/spec/requests/post_attendee_spec.rb index b01800aa..81712632 100644 --- a/spec/requests/post_attendee_spec.rb +++ b/spec/requests/post_attendee_spec.rb @@ -28,30 +28,31 @@ # include_context 'registration_data' include_context 'competition information' - # Failing: due to "Cannot do operations on a non-existent table" error - Finn input needed, I've done a basic check - response '202', '-> FAILING admin registers before registration opens' do - registration = FactoryBot.build(:admin, events: ["444", "333bf"], competition_id: "BrizZonSylwesterOpen2023") - let(:registration) { registration } + # Failing: see above + response '202', '-> PASSING competitor submits basic registration' do + registration = FactoryBot.build(:registration) + let!(:registration) { registration } let(:Authorization) { registration[:jwt_token] } run_test! do |response| - assert_requested :get, "#{@base_comp_url}#{@registrations_not_open}", times: 1 + assert_requested :get, "#{@base_comp_url}#{@includes_non_attending_registrations}", times: 1 end end - # Failing: see above - response '202', '-> FAILING competitor submits basic registration' do - registration = FactoryBot.build(:registration) - let!(:registration) { registration } + # Failing: due to "Cannot do operations on a non-existent table" error - Finn input needed, I've done a basic check + response '202', '-> PASSING admin registers before registration opens' do + registration = FactoryBot.build(:admin, events: ["444", "333bf"], competition_id: "BrizZonSylwesterOpen2023") + let(:registration) { registration } let(:Authorization) { registration[:jwt_token] } run_test! do |response| - assert_requested :get, "#{@base_comp_url}#{@includes_non_attending_registrations}", times: 1 + # TODO: Do a better assertion here + assert_requested :get, "#{@base_comp_url}#{@registrations_not_open}", times: 1 end end # Failing: see above - response '202', '-> FAILING admin submits registration for competitor' do + response '202', '-> PASSING admin submits registration for competitor' do registration = FactoryBot.build(:admin_submits) let(:registration) { registration } let(:Authorization) { registration[:jwt_token] } @@ -70,7 +71,7 @@ include_context 'competition information' response '401', ' -> PASSING user impersonation (no admin permission, JWT token user_id does not match registration user_id)' do - registration_error_json = { error: ErrorCodes::USER_IMPERSONATION }.to_json + registration_error_json = { error: ErrorCodes::USER_INSUFFICIENT_PERMISSIONS }.to_json let(:registration) { @required_fields_only } let(:Authorization) { @jwt_200 } run_test! do |response| @@ -97,7 +98,7 @@ end end - response '403', '-> PASSING attendee is banned' do + response '401', '-> PASSING attendee is banned' do registration_error_json = { error: ErrorCodes::USER_IS_BANNED }.to_json let(:registration) { @banned_user_reg } let(:Authorization) { @banned_user_jwt } @@ -138,10 +139,13 @@ end response '400', ' -> PASSING empty payload provided' do # getting a long error on this - not sure why it fails + registration_error_json = { error: ErrorCodes::INVALID_REQUEST_DATA }.to_json let(:registration) { @empty_payload } let(:Authorization) { @jwt_817 } - run_test! + run_test! do |response| + expect(response.body).to eq(registration_error_json) + end end response '404', ' -> PASSING competition does not exist' do @@ -182,7 +186,7 @@ end end - response '403', '-> PASSING admin adds banned user' do + response '401', '-> PASSING admin adds banned user' do registration_error_json = { error: ErrorCodes::USER_IS_BANNED }.to_json let(:registration) { @banned_user_reg } let(:Authorization) { @admin_token } @@ -223,10 +227,13 @@ end response '400', ' -> PASSING admin adds registration with empty payload provided' do # getting a long error on this - not sure why it fails + registration_error_json = { error: ErrorCodes::INVALID_REQUEST_DATA }.to_json let(:registration) { @empty_payload } let(:Authorization) { @admin_token } - run_test! + run_test! do |response| + expect(response.body).to eq(registration_error_json) + end end response '404', ' -> PASSING admin adds reg for competition which does not exist' do diff --git a/spec/requests/update_registration_spec.rb b/spec/requests/update_registration_spec.rb index 790405ec..2c7bdbf3 100644 --- a/spec/requests/update_registration_spec.rb +++ b/spec/requests/update_registration_spec.rb @@ -21,7 +21,7 @@ include_context 'database seed' include_context 'auth_tokens' - response '200', 'PASSING user passes empty event_ids - with deleted status' do + response '200', 'PASSING user passes empty event_ids - with cancelled status' do let(:registration_update) { @events_update_5 } let(:Authorization) { @jwt_817 } @@ -74,7 +74,7 @@ run_test! do |response| target_registration = Registration.find("#{registration_update['competition_id']}-#{registration_update['user_id']}") - expect(target_registration.event_ids).to eq(registration_update['event_ids']) + expect(target_registration.event_ids).to eq(registration_update['competing']['event_ids']) end end @@ -84,7 +84,7 @@ run_test! do |response| target_registration = Registration.find("#{registration_update['competition_id']}-#{registration_update['user_id']}") - expect(target_registration.event_ids).to eq(registration_update['event_ids']) + expect(target_registration.event_ids).to eq(registration_update['competing']['event_ids']) end end @@ -333,7 +333,7 @@ end response '401', 'PASSING user requests status change to someone elses reg' do - registration_error = { error: ErrorCodes::USER_IMPERSONATION }.to_json + registration_error = { error: ErrorCodes::USER_INSUFFICIENT_PERMISSIONS }.to_json let(:registration_update) { @pending_update_1 } let(:Authorization) { @jwt_816 } diff --git a/spec/support/dynamoid_reset.rb b/spec/support/dynamoid_reset.rb index e3e605b4..6b375931 100644 --- a/spec/support/dynamoid_reset.rb +++ b/spec/support/dynamoid_reset.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true -raise "Tests should be run in 'test' environment only" if Rails.env != 'test' && Rails.env != 'development' +raise "Tests should be run in 'test' environment only" if Rails.env != 'test' + +# This is required so that the first test that is run doesn't fail due to table not being created yet - https://github.com/Dynamoid/dynamoid/issues/277 +Dir[File.join(Dynamoid::Config.models_dir, '**/*.rb')].each { |file| require file } module DynamoidReset def self.all