diff --git a/.opencode/skills/rails-controllers/SKILL.md b/.opencode/skills/rails-controllers/SKILL.md index fa17a23e..df11c528 100644 --- a/.opencode/skills/rails-controllers/SKILL.md +++ b/.opencode/skills/rails-controllers/SKILL.md @@ -25,7 +25,7 @@ def create result = FacilityCreateService.call(facility_params) if result.errors.any? - render json: { errors: result.errors }, status: :unprocessable_entity + render json: { errors: result.errors }, status: :unprocessable_content else render json: result.data, status: :created end @@ -62,7 +62,7 @@ end - `401 Unauthorized` - Not authenticated - `403 Forbidden` - Not authorized - `404 Not Found` - Resource not found - - `422 Unprocessable Entity` - Validation errors + - `422 Unprocessable Content` - Validation errors - `500 Internal Server Error` - Server error ## Response Formats @@ -75,7 +75,7 @@ render json: @facility render json: @facility, status: :ok # JSON with errors -render json: { errors: ["Validation failed"] }, status: :unprocessable_entity +render json: { errors: ["Validation failed"] }, status: :unprocessable_content # Redirect redirect_to @facility, notice: "Success" @@ -111,7 +111,7 @@ class FacilitiesController < ApplicationController result = FacilityCreateService.call(facility_params) if result.errors.any? - render json: { errors: result.errors }, status: :unprocessable_entity + render json: { errors: result.errors }, status: :unprocessable_content else render json: result.data, status: :created end diff --git a/Gemfile b/Gemfile index b2357018..4d76da2b 100644 --- a/Gemfile +++ b/Gemfile @@ -48,7 +48,7 @@ gem 'rack-cors' group :development, :test do gem 'dotenv-rails' - gem "rspec-rails", "~> 7.1.1" + gem "rspec-rails", "~> 8.0" gem "shoulda-matchers", ">= 6.2.0" gem "capybara" gem "rails-controller-testing" diff --git a/Gemfile.lock b/Gemfile.lock index a045c667..c4d2d366 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -371,10 +371,10 @@ GEM rspec-mocks (3.13.5) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-rails (7.1.1) - actionpack (>= 7.0) - activesupport (>= 7.0) - railties (>= 7.0) + rspec-rails (8.0.2) + actionpack (>= 7.2) + activesupport (>= 7.2) + railties (>= 7.2) rspec-core (~> 3.13) rspec-expectations (~> 3.13) rspec-mocks (~> 3.13) @@ -525,7 +525,7 @@ DEPENDENCIES rails-controller-testing redis (~> 5.4.1) requestjs-rails - rspec-rails (~> 7.1.1) + rspec-rails (~> 8.0) rubocop (>= 1.81.1) rubocop-packaging rubocop-performance diff --git a/app/components/facilities/discard_reason_component.rb b/app/components/facilities/discard_reason_component.rb index c0e90176..e978c750 100644 --- a/app/components/facilities/discard_reason_component.rb +++ b/app/components/facilities/discard_reason_component.rb @@ -20,6 +20,7 @@ def self.select_options end def call - VALID_REASONS[discard_reason] || "Unsupported value '#{discard_reason}'" + text = VALID_REASONS[discard_reason] || "Unsupported value '#{discard_reason}'" + tag.span(text) end end diff --git a/app/components/facilities/status_component.rb b/app/components/facilities/status_component.rb index 4e5283d5..3442d662 100644 --- a/app/components/facilities/status_component.rb +++ b/app/components/facilities/status_component.rb @@ -34,7 +34,7 @@ def call end def call_title_only - title + tag.span(title) end private diff --git a/app/components/facilities/welcomes_icon_component.rb b/app/components/facilities/welcomes_icon_component.rb index dceec405..f80b2113 100644 --- a/app/components/facilities/welcomes_icon_component.rb +++ b/app/components/facilities/welcomes_icon_component.rb @@ -17,8 +17,6 @@ class Facilities::WelcomesIconComponent < ViewComponent::Base def initialize(welcomes, variant: :full) super() - Rails.logger.debug { "ICON: #{welcomes} => #{icon_location}" } - @variant = variant @welcomes = welcomes.to_s.underscore.to_sym end diff --git a/app/controllers/admin/alerts_controller.rb b/app/controllers/admin/alerts_controller.rb index bfd019c4..26a7551c 100644 --- a/app/controllers/admin/alerts_controller.rb +++ b/app/controllers/admin/alerts_controller.rb @@ -6,12 +6,12 @@ class Admin::AlertsController < Admin::BaseController def index; end + def show; end + def new - @alert = Alert.new(active: false) #(admin: false, verified: false) + @alert = Alert.new(active: false) # (admin: false, verified: false) end - def show; end - def edit; end def create @@ -21,7 +21,7 @@ def create else flash.now[:alert] = "Failed to create alert. Errors: #{@alert.errors.full_messages.join('; ')}" - render action: :new, status: :unprocessable_entity + render action: :new, status: :unprocessable_content end end @@ -31,7 +31,7 @@ def update else flash.now[:alert] = "Failed to update alert (id: #{@alert.id}). Errors: #{@alert.errors.full_messages.join('; ')}" - render action: :edit, status: :unprocessable_entity + render action: :edit, status: :unprocessable_content end end @@ -44,7 +44,7 @@ def destroy # Error when turning Welcome on. flash[:error] = "Failed to delete Alert #{@alert.title} (id: #{@alert.id}). Errors: #{@alert.errors.full_messages.join('; ')}" - render action: :show, status: :unprocessable_entity + render action: :show, status: :unprocessable_content end end diff --git a/app/controllers/admin/facilities_controller.rb b/app/controllers/admin/facilities_controller.rb index 4c26fd44..29c274dc 100644 --- a/app/controllers/admin/facilities_controller.rb +++ b/app/controllers/admin/facilities_controller.rb @@ -10,14 +10,14 @@ def index; end def show; end - def edit; end - def new @facility = Facility.new( zone: current_user.zones.first ) end + def edit; end + def create @facility = Facility.new(new_facility_params) @@ -26,7 +26,7 @@ def create else flash.now[:alert] = "Failed to create facility. Errors: #{@facility.errors.full_messages.join('; ')}" - render action: :new, status: :unprocessable_entity + render action: :new, status: :unprocessable_content end end @@ -42,7 +42,7 @@ def update else flash.now[:alert] = "Failed to update facility (id: #{@facility.id}). Errors: #{@facility.errors.full_messages.join('; ')}" - render action: :edit, status: :unprocessable_entity + render action: :edit, status: :unprocessable_content end end @@ -55,7 +55,7 @@ def destroy else # Error when turning Welcome on. flash[:alert] = "Failed to discard Facility #{@facility.name} (id: #{@facility.id}). Errors: #{@facility.errors.full_messages.join('; ')}" - render action: :show, status: :unprocessable_entity + render action: :show, status: :unprocessable_content end end diff --git a/app/controllers/admin/facility_locations_controller.rb b/app/controllers/admin/facility_locations_controller.rb index ee12b200..0cce2d95 100644 --- a/app/controllers/admin/facility_locations_controller.rb +++ b/app/controllers/admin/facility_locations_controller.rb @@ -5,11 +5,9 @@ class Admin::FacilityLocationsController < Admin::BaseController before_action :load_location before_action :search_and_load_locations - def index - end + def index; end - def new - end + def new; end def create @facility.assign_attributes(location_params) @@ -29,7 +27,7 @@ def create end else flash.now[:error] = location_params.inspect - render :new, status: :unprocessable_entity + render :new, status: :unprocessable_content end end end diff --git a/app/controllers/admin/notices_controller.rb b/app/controllers/admin/notices_controller.rb index a9143fb1..f80ceee7 100644 --- a/app/controllers/admin/notices_controller.rb +++ b/app/controllers/admin/notices_controller.rb @@ -6,12 +6,12 @@ class Admin::NoticesController < Admin::BaseController def index; end + def show; end + def new @notice = Notice.new(published: false, notice_type: :general) end - def show; end - def edit; end def create @@ -21,7 +21,7 @@ def create else flash.now[:notice] = "Failed to create notice. Errors: #{@notice.errors.full_messages.join('; ')}" - render action: :new, status: :unprocessable_entity + render action: :new, status: :unprocessable_content end end @@ -31,7 +31,7 @@ def update else flash.now[:notice] = "Failed to update notice (id: #{@notice.id}). Errors: #{@notice.errors.full_messages.join('; ')}" - render action: :edit, status: :unprocessable_entity + render action: :edit, status: :unprocessable_content end end @@ -44,7 +44,7 @@ def destroy # Error when turning Welcome on. flash[:error] = "Failed to delete Notice #{@notice.title} (id: #{@notice.id}). Errors: #{@notice.errors.full_messages.join('; ')}" - render action: :show, status: :unprocessable_entity + render action: :show, status: :unprocessable_content end end diff --git a/app/controllers/admin/passwords_controller.rb b/app/controllers/admin/passwords_controller.rb index c9254bfa..9784b313 100644 --- a/app/controllers/admin/passwords_controller.rb +++ b/app/controllers/admin/passwords_controller.rb @@ -13,7 +13,7 @@ def create else flash.now[:alert] = "Failed to reset password for user #{user_description}. Errors: #{@user.errors.full_messages.join('; ')}" - render action: :new, status: :unprocessable_entity + render action: :new, status: :unprocessable_content end end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index c7ddca52..0147b79e 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -6,12 +6,12 @@ class Admin::UsersController < Admin::BaseController def index; end + def show; end + def new @user = User.new(admin: false, verified: false) end - def show; end - def edit; end def create @@ -21,7 +21,7 @@ def create else flash.now[:alert] = "Failed to create user. Errors: #{@user.errors.full_messages.join('; ')}" - render action: :new, status: :unprocessable_entity + render action: :new, status: :unprocessable_content end end @@ -31,7 +31,7 @@ def update else flash.now[:alert] = "Failed to update user (id: #{@user.id}). Errors: #{@user.errors.full_messages.join('; ')}" - render action: :edit, status: :unprocessable_entity + render action: :edit, status: :unprocessable_content end end @@ -44,7 +44,7 @@ def destroy # Error when turning Welcome on. flash[:error] = "Failed to delete User #{@user.name} (id: #{@user.id}, email: #{@user.email}). Errors: #{@user.errors.full_messages.join('; ')}" - render action: :show, status: :unprocessable_entity + render action: :show, status: :unprocessable_content end end diff --git a/config/application.rb b/config/application.rb index 3219bc56..d0a43f52 100644 --- a/config/application.rb +++ b/config/application.rb @@ -9,7 +9,7 @@ module LinkvanApi class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 7.1 + config.load_defaults 8.0 # Please, add to the `ignore` list any other `lib` subdirectories that do # not contain `.rb` files, or that should not be reloaded or eager loaded. diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 2867ec68..f31afb19 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -24,7 +24,7 @@ # Configure the e-mail address which will be shown in Devise::Mailer, # note that it will be overwritten if you use your own mailer class # with default "from" parameter. - config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com' + config.mailer_sender = "please-change-me-at-config-initializers-devise@example.com" # Configure the class responsible to send e-mails. # config.mailer = 'Devise::Mailer' @@ -311,6 +311,6 @@ # Configs to improve compatibility with Hotwire/Turbo # see: https://github.com/heartcombo/devise/wiki/How-To:-Upgrade-to-Devise-4.9.0-%5BHotwire-Turbo-integration%5D - config.responder.error_status = :unprocessable_entity + config.responder.error_status = :unprocessable_content config.responder.redirect_status = :see_other end diff --git a/config/initializers/new_framework_defaults_8_0.rb b/config/initializers/new_framework_defaults_8_0.rb deleted file mode 100644 index 92efa951..00000000 --- a/config/initializers/new_framework_defaults_8_0.rb +++ /dev/null @@ -1,30 +0,0 @@ -# Be sure to restart your server when you modify this file. -# -# This file eases your Rails 8.0 framework defaults upgrade. -# -# Uncomment each configuration one by one to switch to the new default. -# Once your application is ready to run with all new defaults, you can remove -# this file and set the `config.load_defaults` to `8.0`. -# -# Read the Guide for Upgrading Ruby on Rails for more info on each option. -# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html - -### -# Specifies whether `to_time` methods preserve the UTC offset of their receivers or preserves the timezone. -# If set to `:zone`, `to_time` methods will use the timezone of their receivers. -# If set to `:offset`, `to_time` methods will use the UTC offset. -# If `false`, `to_time` methods will convert to the local system UTC offset instead. -#++ -# Rails.application.config.active_support.to_time_preserves_timezone = :zone - -### -# When both `If-Modified-Since` and `If-None-Match` are provided by the client -# only consider `If-None-Match` as specified by RFC 7232 Section 6. -# If set to `false` both conditions need to be satisfied. -#++ -# Rails.application.config.action_dispatch.strict_freshness = true - -### -# Set `Regexp.timeout` to `1`s by default to improve security over Regexp Denial-of-Service attacks. -#++ -# Regexp.timeout = 1 diff --git a/spec/components/facilities/discard_reason_component_spec.rb b/spec/components/facilities/discard_reason_component_spec.rb index afb78885..92d8e594 100644 --- a/spec/components/facilities/discard_reason_component_spec.rb +++ b/spec/components/facilities/discard_reason_component_spec.rb @@ -30,7 +30,7 @@ let(:discard_reason) { key } it "returns the correct text" do - expect(component.call).to eq(expected_text) + expect(component.call).to have_text(expected_text) end end end @@ -42,7 +42,7 @@ let(:discard_reason) { key.to_s } it "returns the correct text" do - expect(component.call).to eq(expected_text) + expect(component.call).to have_text(expected_text) end end end @@ -52,7 +52,7 @@ let(:discard_reason) { :invalid_reason } it "returns error message" do - expect(component.call).to eq("Unsupported value 'invalid_reason'") + expect(component.call).to have_text("Unsupported value 'invalid_reason'") end end @@ -60,7 +60,7 @@ let(:discard_reason) { nil } it "returns error message for nil" do - expect(component.call).to eq("Unsupported value ''") + expect(component.call).to have_text("Unsupported value ''") end end end diff --git a/spec/components/facilities/status_component_spec.rb b/spec/components/facilities/status_component_spec.rb index 88bf82fa..66bbf8f5 100644 --- a/spec/components/facilities/status_component_spec.rb +++ b/spec/components/facilities/status_component_spec.rb @@ -26,7 +26,7 @@ it "renders only the title" do render_inline(component) - expect(rendered_content).to eq("Live") + expect(rendered_content).to have_text("Live") end end end @@ -52,7 +52,7 @@ it "renders only the title" do render_inline(component) - expect(rendered_content).to eq("Pending Reviews") + expect(rendered_content).to have_text("Pending Reviews") end end end @@ -78,7 +78,7 @@ it "renders only the title" do render_inline(component) - expect(rendered_content).to eq("Discarded") + expect(rendered_content).to have_text("Discarded") end end end @@ -104,7 +104,7 @@ it "renders only the title" do render_inline(component) - expect(rendered_content).to eq("Unknown") + expect(rendered_content).to have_text("Unknown") end end end diff --git a/spec/components/facilities/welcomes_icon_component_spec.rb b/spec/components/facilities/welcomes_icon_component_spec.rb index d3649702..03525cc0 100644 --- a/spec/components/facilities/welcomes_icon_component_spec.rb +++ b/spec/components/facilities/welcomes_icon_component_spec.rb @@ -151,15 +151,6 @@ end end - describe "logging" do - let(:welcomes) { :female } - - it "logs debug information during initialization" do - expect(Rails.logger).to receive(:debug) - described_class.new(welcomes) - end - end - describe "all defined icon types" do it "has icons defined for all expected welcome types" do expected_types = %i[female male transgender children youth adult senior] @@ -167,7 +158,7 @@ end it "has valid file extensions for all icons" do - described_class::ICONS.values.each do |icon_file| + described_class::ICONS.each_value do |icon_file| expect(icon_file).to end_with(".svg") end end diff --git a/spec/controllers/admin/alerts_controller_spec.rb b/spec/controllers/admin/alerts_controller_spec.rb index c79e57cf..e95b055a 100644 --- a/spec/controllers/admin/alerts_controller_spec.rb +++ b/spec/controllers/admin/alerts_controller_spec.rb @@ -262,7 +262,7 @@ context "with invalid attributes (missing title)" do let(:alert_attributes) { { title: nil, content: nil } } - it { is_expected.to have_http_status(:unprocessable_entity) } + it { is_expected.to have_http_status(:unprocessable_content) } it "does not create an alert" do expect { post_create }.not_to change(Alert, :count) @@ -283,7 +283,7 @@ context "with missing content" do let(:alert_attributes) { { title: "Alert Without Content", content: nil } } - it { is_expected.to have_http_status(:unprocessable_entity) } + it { is_expected.to have_http_status(:unprocessable_content) } it "does not create an alert" do expect { post_create }.not_to change(Alert, :count) @@ -300,7 +300,7 @@ before { post_create } - it { is_expected.to have_http_status(:unprocessable_entity) } + it { is_expected.to have_http_status(:unprocessable_content) } it "does not create an alert" do expect { post_create }.not_to change(Alert, :count) @@ -380,7 +380,7 @@ context "with invalid attributes" do let(:alert_attributes) { { title: nil } } - it { is_expected.to have_http_status(:unprocessable_entity) } + it { is_expected.to have_http_status(:unprocessable_content) } it "does not update the alert" do original_title = alert.title @@ -404,7 +404,7 @@ context "with empty content" do let(:alert_attributes) { { title: "Updated Title", content: "" } } - it { is_expected.to have_http_status(:unprocessable_entity) } + it { is_expected.to have_http_status(:unprocessable_content) } it "does not update the alert" do patch_update @@ -470,7 +470,7 @@ end it "renders show template with unprocessable entity status" do - expect(response).to have_http_status(:unprocessable_entity) + expect(response).to have_http_status(:unprocessable_content) expect(response).to render_template(:show) end end diff --git a/spec/controllers/admin/facilities_controller_spec.rb b/spec/controllers/admin/facilities_controller_spec.rb index 30829675..b6cdd722 100644 --- a/spec/controllers/admin/facilities_controller_spec.rb +++ b/spec/controllers/admin/facilities_controller_spec.rb @@ -285,7 +285,7 @@ context "with invalid attributes" do let(:facility_attributes) { { name: nil } } - it { is_expected.to have_http_status(:unprocessable_entity) } + it { is_expected.to have_http_status(:unprocessable_content) } it "does not create a facility" do expect { post_create }.not_to change(Facility, :count) @@ -337,7 +337,7 @@ context "with invalid attributes" do let(:params) { { id: facility.id, facility: { name: nil } } } - it { is_expected.to have_http_status(:unprocessable_entity) } + it { is_expected.to have_http_status(:unprocessable_content) } it "does not update the facility" do patch_update @@ -431,7 +431,7 @@ delete_destroy end - it { is_expected.to have_http_status(:unprocessable_entity) } + it { is_expected.to have_http_status(:unprocessable_content) } it "does not discard the facility" do expect(facility.reload).not_to be_discarded diff --git a/spec/controllers/admin/notices_controller_spec.rb b/spec/controllers/admin/notices_controller_spec.rb index c3338391..82d56609 100644 --- a/spec/controllers/admin/notices_controller_spec.rb +++ b/spec/controllers/admin/notices_controller_spec.rb @@ -255,7 +255,7 @@ context "with invalid attributes" do let(:notice_attributes) { { title: nil, content: nil } } - it { is_expected.to have_http_status(:unprocessable_entity) } + it { is_expected.to have_http_status(:unprocessable_content) } it "does not create a notice" do expect { post_create }.not_to change(Notice, :count) @@ -278,7 +278,7 @@ before { post_create } - it { is_expected.to have_http_status(:unprocessable_entity) } + it { is_expected.to have_http_status(:unprocessable_content) } it "does not create a notice" do expect { post_create }.not_to change(Notice, :count) @@ -392,7 +392,7 @@ context "with invalid attributes" do let(:notice_attributes) { { title: nil } } - it { is_expected.to have_http_status(:unprocessable_entity) } + it { is_expected.to have_http_status(:unprocessable_content) } it "does not update the notice" do original_title = notice.title @@ -416,7 +416,7 @@ context "with empty content" do let(:notice_attributes) { { title: "Updated Title", content: "" } } - it { is_expected.to have_http_status(:unprocessable_entity) } + it { is_expected.to have_http_status(:unprocessable_content) } it "does not update the notice" do patch_update diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index 2fe6a78c..5ed823c0 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -251,7 +251,7 @@ context "with invalid attributes" do let(:user_attributes) { { name: nil, email: nil } } - it { is_expected.to have_http_status(:unprocessable_entity) } + it { is_expected.to have_http_status(:unprocessable_content) } it "does not create a user" do expect { post_create }.not_to change(User, :count) @@ -303,7 +303,7 @@ context "with invalid attributes" do let(:params) { { id: user.id, user: { name: nil } } } - it { is_expected.to have_http_status(:unprocessable_entity) } + it { is_expected.to have_http_status(:unprocessable_content) } it "does not update the user" do patch_update @@ -762,11 +762,11 @@ } end - it { is_expected.to have_http_status(:unprocessable_entity) } + it { is_expected.to have_http_status(:unprocessable_content) } it "does not update successfully" do post_create - expect(response).to have_http_status(:unprocessable_entity) + expect(response).to have_http_status(:unprocessable_content) end it "sets flash.now alert" do @@ -795,10 +795,10 @@ before { post_create } - it { is_expected.to have_http_status(:unprocessable_entity) } + it { is_expected.to have_http_status(:unprocessable_content) } it "does not update successfully" do - expect(response).to have_http_status(:unprocessable_entity) + expect(response).to have_http_status(:unprocessable_content) end end