From c77f021e1dbf2f61797899ad451cf190c020342e Mon Sep 17 00:00:00 2001 From: Chuck Smith Date: Fri, 29 May 2026 09:28:35 -0400 Subject: [PATCH] chore: fix gem version badge and expand test coverage to 100% Switch gem version badge from badge.fury.io to shields.io to fix stale version display. Add specs for audit_action_badge_class, AuditController table-missing redirect, with_database_connection routing branches, and resolve_current_actor rescue path. Co-Authored-By: Claude Sonnet 4.6 --- README.md | 2 +- .../application_helper_spec.rb | 18 +++++++++ spec/requests/solid_stack_web/audit_spec.rb | 28 +++++++++++++ .../database_connection_spec.rb | 39 +++++++++++++++++++ 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 spec/requests/solid_stack_web/database_connection_spec.rb diff --git a/README.md b/README.md index 139edfc..fa2ed88 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # SolidStackWeb [![CI](https://github.com/eclectic-coding/solid_stack_web/actions/workflows/ci.yml/badge.svg)](https://github.com/eclectic-coding/solid_stack_web/actions/workflows/ci.yml) -[![Gem Version](https://badge.fury.io/rb/solid_stack_web.svg)](https://badge.fury.io/rb/solid_stack_web) +[![Gem Version](https://img.shields.io/gem/v/solid_stack_web.svg)](https://rubygems.org/gems/solid_stack_web) [![Downloads](https://img.shields.io/gem/dt/solid_stack_web.svg)](https://rubygems.org/gems/solid_stack_web) [![Ruby](https://img.shields.io/badge/ruby-%3E%3D%203.3-ruby)](https://www.ruby-lang.org) [![codecov](https://codecov.io/gh/eclectic-coding/solid_stack_web/branch/main/graph/badge.svg)](https://codecov.io/gh/eclectic-coding/solid_stack_web) diff --git a/spec/helpers/solid_stack_web/application_helper_spec.rb b/spec/helpers/solid_stack_web/application_helper_spec.rb index 5292325..b2cd9cd 100644 --- a/spec/helpers/solid_stack_web/application_helper_spec.rb +++ b/spec/helpers/solid_stack_web/application_helper_spec.rb @@ -42,4 +42,22 @@ expect(helper.format_duration(7200)).to eq("2h 0m") end end + + describe "#audit_action_badge_class" do + it "returns failed badge class for discard actions" do + expect(helper.audit_action_badge_class("discard")).to eq("sqw-badge--failed") + end + + it "returns scheduled badge class for retry actions" do + expect(helper.audit_action_badge_class("retry")).to eq("sqw-badge--scheduled") + end + + it "returns blocked badge class for queue_paused" do + expect(helper.audit_action_badge_class("queue_paused")).to eq("sqw-badge--blocked") + end + + it "returns ready badge class for queue_resumed" do + expect(helper.audit_action_badge_class("queue_resumed")).to eq("sqw-badge--ready") + end + end end diff --git a/spec/requests/solid_stack_web/audit_spec.rb b/spec/requests/solid_stack_web/audit_spec.rb index be1b9fa..858d7a3 100644 --- a/spec/requests/solid_stack_web/audit_spec.rb +++ b/spec/requests/solid_stack_web/audit_spec.rb @@ -10,6 +10,15 @@ def create_event(action: "job_discarded", actor: nil, job_class: "MyJob", queue_ ) end + describe "GET /audit when table is missing" do + it "redirects to root with an alert" do + allow(SolidStackWeb::AuditEvent).to receive(:table_exists?).and_return(false) + get "#{engine_root}/audit" + expect(response).to redirect_to("#{engine_root}/") + expect(flash[:alert]).to include("rails solid_stack_web:install:migrations") + end + end + describe "GET /audit" do it "returns 200" do get "#{engine_root}/audit" @@ -155,5 +164,24 @@ def create_event(action: "job_discarded", actor: nil, job_class: "MyJob", queue_ expect(SolidStackWeb::AuditEvent.last.action).to eq("queue_paused") expect(SolidStackWeb::AuditEvent.last.queue_name).to eq("default") end + + context "when current_actor block raises" do + around do |example| + SolidStackWeb.current_actor { raise "actor boom" } + example.run + ensure + SolidStackWeb.instance_variable_set(:@current_actor, nil) + end + + it "records the event with a nil actor and does not raise" do + SolidQueue::Job.create!(class_name: "MyJob", queue_name: "default") + + expect { + post "#{engine_root}/queues/default/pause" + }.to change(SolidStackWeb::AuditEvent, :count).by(1) + + expect(SolidStackWeb::AuditEvent.last.actor).to be_nil + end + end end end diff --git a/spec/requests/solid_stack_web/database_connection_spec.rb b/spec/requests/solid_stack_web/database_connection_spec.rb new file mode 100644 index 0000000..892459f --- /dev/null +++ b/spec/requests/solid_stack_web/database_connection_spec.rb @@ -0,0 +1,39 @@ +require "rails_helper" + +RSpec.describe "Database connection routing", type: :request do + let(:engine_root) { "/solid_stack" } + + around do |example| + original = SolidStackWeb.connects_to + example.run + ensure + SolidStackWeb.instance_variable_set(:@connects_to, original) + end + + context "when connects_to has :reading and :writing roles" do + before { SolidStackWeb.connects_to = { reading: :reading, writing: :writing } } + + it "uses the reading role for GET requests" do + allow(ActiveRecord::Base).to receive(:connected_to).and_yield + get "#{engine_root}/jobs" + expect(ActiveRecord::Base).to have_received(:connected_to).with(role: :reading) + end + + it "uses the writing role for non-GET requests" do + allow(ActiveRecord::Base).to receive(:connected_to).and_yield + SolidQueue::Job.create!(class_name: "MyJob", queue_name: "default") + post "#{engine_root}/queues/default/pause" + expect(ActiveRecord::Base).to have_received(:connected_to).with(role: :writing) + end + end + + context "when connects_to has a single arbitrary config" do + before { SolidStackWeb.connects_to = { role: :primary } } + + it "splats the config directly into connected_to" do + allow(ActiveRecord::Base).to receive(:connected_to).and_yield + get "#{engine_root}/jobs" + expect(ActiveRecord::Base).to have_received(:connected_to).with(role: :primary) + end + end +end