From 35ace00e3c671c07f2a0f1f63ace3a555da9ef19 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Thu, 14 Dec 2023 19:23:07 -0500 Subject: [PATCH 1/7] Add with_temp_application test helper --- spec/requests/default_namespace_spec.rb | 17 ++++------------- .../active_admin_integration_spec_helper.rb | 9 +++++++++ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/spec/requests/default_namespace_spec.rb b/spec/requests/default_namespace_spec.rb index 527f2c12a99..a220a34eba5 100644 --- a/spec/requests/default_namespace_spec.rb +++ b/spec/requests/default_namespace_spec.rb @@ -66,18 +66,9 @@ def with_custom_default_namespace(namespace) application = ActiveAdmin::Application.new application.default_namespace = namespace - with_temp_application(application) { yield } - end - - def with_temp_application(application) - original_application = ActiveAdmin.application - ActiveAdmin.application = application - - load_resources { ActiveAdmin.register(Category) } - - yield - - ensure - ActiveAdmin.application = original_application + with_temp_application(application) do + load_resources { ActiveAdmin.register(Category) } + yield + end end end diff --git a/spec/support/active_admin_integration_spec_helper.rb b/spec/support/active_admin_integration_spec_helper.rb index b10c763c549..28a1f2181ab 100644 --- a/spec/support/active_admin_integration_spec_helper.rb +++ b/spec/support/active_admin_integration_spec_helper.rb @@ -1,5 +1,14 @@ # frozen_string_literal: true module ActiveAdminIntegrationSpecHelper + def with_temp_application(application) + original_application = ActiveAdmin.application + ActiveAdmin.application = application + reload_routes! + yield + ensure + ActiveAdmin.application = original_application + end + def with_resources_during(example) load_resources { yield } From 5d2b1b689fd74523b7a35ec10cccaa6d5e3fc646 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Thu, 14 Dec 2023 19:31:06 -0500 Subject: [PATCH 2/7] Add initial show request spec --- spec/requests/resource/show_spec.rb | 32 +++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 spec/requests/resource/show_spec.rb diff --git a/spec/requests/resource/show_spec.rb b/spec/requests/resource/show_spec.rb new file mode 100644 index 00000000000..6bca032b7f3 --- /dev/null +++ b/spec/requests/resource/show_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true +require "rails_helper" + +RSpec.describe "Resource show page", type: :request do + let!(:application) { ActiveAdmin::Application.new } + let!(:namespace) { application.namespace(:admin) } + let(:html_body) { Capybara.string(response.body) } + + context "with no display name" do + let!(:post) { Post.create! } + let(:resource) do + namespace.register Post do + show do |post| + attributes_table do + row :field + end + end + end + end + + it "renders default page title" do + with_temp_application(application) do + load_resources { resource } + + get admin_post_path(post) + + expect(response.body).to include("Post ##{post.id}") + expect(html_body).to have_css("[data-test-page-header]", text: "Post ##{post.id}") + end + end + end +end From 472e2b6ebf0d00fa3abe91421d943dc149f4c68d Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Fri, 15 Dec 2023 01:01:59 -0500 Subject: [PATCH 3/7] Run CI on push for this branch --- .github/workflows/ci.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5ca6bcb4184..6ab226ed818 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -3,8 +3,6 @@ name: ci on: pull_request: push: - branches: - - master concurrency: group: ${{ github.repository }}-${{ github.workflow }}-${{ github.ref }} From ce027d2e483e8b4834c8cd77442b8c4026b284d2 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Thu, 23 Apr 2026 16:45:43 -0400 Subject: [PATCH 4/7] Convert root_to feature to request spec --- features/root_to.feature | 18 ----------- features/step_definitions/root_steps.rb | 10 ------- spec/requests/root_to_spec.rb | 40 +++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 28 deletions(-) delete mode 100644 features/root_to.feature delete mode 100644 features/step_definitions/root_steps.rb create mode 100644 spec/requests/root_to_spec.rb diff --git a/features/root_to.feature b/features/root_to.feature deleted file mode 100644 index 89a374d24df..00000000000 --- a/features/root_to.feature +++ /dev/null @@ -1,18 +0,0 @@ -@root -Feature: Namespace root - - As a developer - In order to customize the welcome page - I want to set it in the configuration - - Scenario: Default root is the Dashboard - Given I am logged in with capybara - Then I should be on the dashboard - - Scenario: Set root to "stores#index" - Given a configuration of: - """ - ActiveAdmin.application.root_to = 'stores#index' - """ - And I am logged in with capybara - Then I should see the page title "Bookstores" diff --git a/features/step_definitions/root_steps.rb b/features/step_definitions/root_steps.rb deleted file mode 100644 index dc035569571..00000000000 --- a/features/step_definitions/root_steps.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true -Around "@root" do |scenario, block| - previous_root = ActiveAdmin.application.root_to - - begin - block.call - ensure - ActiveAdmin.application.root_to = previous_root - end -end diff --git a/spec/requests/root_to_spec.rb b/spec/requests/root_to_spec.rb new file mode 100644 index 00000000000..f0e984167d7 --- /dev/null +++ b/spec/requests/root_to_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true +require "rails_helper" + +RSpec.describe "Namespace root", type: :request do + # Fixes failure with: bin/rspec spec/requests --seed 34371 + around do |example| + with_resources_during(example) {} + end + + it "renders the dashboard by default" do + with_root_to("dashboard#index") do + get admin_root_path + end + + expect(response).to have_http_status(:ok) + expect(page_header_text).to eq("Dashboard") + end + + it "can route the namespace root to a resource index" do + with_root_to("stores#index") do + get admin_root_path + end + + expect(response).to have_http_status(:ok) + expect(page_header_text).to eq("Bookstores") + end + + def with_root_to(root_to) + previous_root_to = ActiveAdmin.application.root_to + ActiveAdmin.application.root_to = root_to + reload_routes! + yield + ensure + ActiveAdmin.application.root_to = previous_root_to + end + + def page_header_text + Nokogiri::HTML(response.body).at_css("[data-test-page-header] h2")&.text.to_s.squish + end +end From 13b3cec006e1fca442ccaec476f720d69f0c735d Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Thu, 23 Apr 2026 16:47:42 -0400 Subject: [PATCH 5/7] Convert index page title feature to request spec --- features/index/page_title.feature | 41 ------------ spec/requests/index/page_title_spec.rb | 92 ++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 41 deletions(-) delete mode 100644 features/index/page_title.feature create mode 100644 spec/requests/index/page_title_spec.rb diff --git a/features/index/page_title.feature b/features/index/page_title.feature deleted file mode 100644 index e43ee554ebf..00000000000 --- a/features/index/page_title.feature +++ /dev/null @@ -1,41 +0,0 @@ -Feature: Index - Page Title - - Modifying the page title on the index screen - - Scenario: Set a string as the title - Given an index configuration of: - """ - ActiveAdmin.register Post do - index title: "Awesome Title" - end - """ - Then I should see the page title "Awesome Title" - - Scenario: Set the title using a proc - Given an index configuration of: - """ - ActiveAdmin.register Post do - index title: proc{ 'Custom title from proc' } - end - """ - Then I should see the page title "Custom title from proc" - - Scenario: Set the title using a proc that uses the available resource class - Given an index configuration of: - """ - ActiveAdmin.register Post do - index title: proc{ "List of #{resource_class.model_name.plural}" } - end - """ - Then I should see the page title "List of posts" - - Scenario: Set the title in controller - Given an index configuration of: - """ - ActiveAdmin.register Post do - controller do - before_action { @page_title = "List of #{resource_class.model_name.plural}" } - end - end - """ - Then I should see the page title "List of posts" diff --git a/spec/requests/index/page_title_spec.rb b/spec/requests/index/page_title_spec.rb new file mode 100644 index 00000000000..541ae6afb1c --- /dev/null +++ b/spec/requests/index/page_title_spec.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true +require "rails_helper" + +RSpec.describe "Index page title", type: :request do + around do |example| + with_admin_batch_actions(false) { example.run } + end + + context "when the title is configured as a string" do + around do |example| + with_resources_during(example) do + ActiveAdmin.register(Post) do + index title: "Awesome Title" + end + end + end + + it "renders the configured title" do + get admin_posts_path + + expect(response).to have_http_status(:ok) + expect(page_header_text).to eq("Awesome Title") + end + end + + context "when the title is configured as a proc" do + around do |example| + with_resources_during(example) do + ActiveAdmin.register(Post) do + index title: proc { "Custom title from proc" } + end + end + end + + it "renders the title returned by the proc" do + get admin_posts_path + + expect(response).to have_http_status(:ok) + expect(page_header_text).to eq("Custom title from proc") + end + end + + context "when the title proc references the resource class" do + around do |example| + with_resources_during(example) do + ActiveAdmin.register(Post) do + index title: proc { "List of #{resource_class.model_name.plural}" } + end + end + end + + it "renders the title returned by the proc" do + get admin_posts_path + + expect(response).to have_http_status(:ok) + expect(page_header_text).to eq("List of posts") + end + end + + context "when the controller sets @page_title" do + around do |example| + with_resources_during(example) do + ActiveAdmin.register(Post) do + controller do + before_action { @page_title = "List of #{resource_class.model_name.plural}" } + end + end + end + end + + it "renders the controller-defined title" do + get admin_posts_path + + expect(response).to have_http_status(:ok) + expect(page_header_text).to eq("List of posts") + end + end + + def with_admin_batch_actions(value) + namespace = ActiveAdmin.application.namespace(:admin) + previous_value = namespace.batch_actions + namespace.batch_actions = value + + yield + ensure + namespace.batch_actions = previous_value + end + + def page_header_text + Nokogiri::HTML(response.body).at_css("[data-test-page-header] h2")&.text.to_s.squish + end +end From 64a03819a236c829b8bca5d56f1aa702c109d65a Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Thu, 23 Apr 2026 17:50:41 -0400 Subject: [PATCH 6/7] Convert register resources feature to request spec --- features/registering_resources.feature | 33 --------- spec/requests/resource/registration_spec.rb | 75 +++++++++++++++++++++ 2 files changed, 75 insertions(+), 33 deletions(-) delete mode 100644 features/registering_resources.feature create mode 100644 spec/requests/resource/registration_spec.rb diff --git a/features/registering_resources.feature b/features/registering_resources.feature deleted file mode 100644 index 094e612c897..00000000000 --- a/features/registering_resources.feature +++ /dev/null @@ -1,33 +0,0 @@ -Feature: Registering Resources - - Registering resources within Active Admin - - Background: - Given I am logged in - And a post with the title "Hello World" exists - - Scenario: Registering a resource with the defaults - Given a configuration of: - """ - ActiveAdmin.register Post - """ - When I go to the dashboard - Then I should see "Posts" - When I follow "Posts" - Then I should see "Hello World" - When I follow "View" - Then I should see "Hello World" - And I should be in the resource section for Post - - Scenario: Registering a resource with another name - Given a configuration of: - """ - ActiveAdmin.register Post, as: "My Post" - """ - When I go to the dashboard - Then I should see "My Posts" - When I follow "My Posts" - Then I should see "Hello World" - When I follow "View" - Then I should see "Hello World" - And I should be in the resource section for My Post diff --git a/spec/requests/resource/registration_spec.rb b/spec/requests/resource/registration_spec.rb new file mode 100644 index 00000000000..d1b22babf73 --- /dev/null +++ b/spec/requests/resource/registration_spec.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true +require "rails_helper" + +RSpec.describe "Resource registration", type: :request do + let!(:post_record) { Post.create!(title: "Hello World") } + + # Fixes failure with: bin/rspec spec/requests --seed 19664 + around do |example| + with_admin_batch_actions(false) { example.run } + end + + context "when registering a resource with the defaults" do + around do |example| + with_resources_during(example) { ActiveAdmin.register(Post) } + end + + it "renders the resource in the dashboard, index, and show pages" do + resource = ActiveAdmin.application.namespace(:admin).resource_for(Post) + + get admin_root_path + expect(response).to have_http_status(:ok) + expect(html_body).to have_link("Posts", href: resource.route_collection_path) + + get resource.route_collection_path + expect(response).to have_http_status(:ok) + expect(response.body).to include("Hello World") + expect(html_body).to have_link("View", href: resource.route_instance_path(post_record)) + + get resource.route_instance_path(post_record) + expect(response).to have_http_status(:ok) + expect(response.body).to include("Hello World") + expect(resource.route_instance_path(post_record)).to include("posts") + end + end + + context "when registering a resource with another name" do + around do |example| + with_resources_during(example) { ActiveAdmin.register(Post, as: "My Post") } + end + + it "uses the aliased resource name and routes" do + resource = ActiveAdmin.application.namespace(:admin).resource_for(Post) + + get admin_root_path + expect(response).to have_http_status(:ok) + expect(html_body).to have_link("My Posts", href: resource.route_collection_path) + + get resource.route_collection_path + expect(response).to have_http_status(:ok) + expect(response.body).to include("Hello World") + expect(html_body).to have_link("View", href: resource.route_instance_path(post_record)) + + get resource.route_instance_path(post_record) + expect(response).to have_http_status(:ok) + expect(response.body).to include("Hello World") + expect(resource.route_instance_path(post_record)).to include("my_posts") + end + end + + private + + def with_admin_batch_actions(value) + namespace = ActiveAdmin.application.namespace(:admin) + previous_value = namespace.batch_actions + namespace.batch_actions = value + + yield + ensure + namespace.batch_actions = previous_value + end + + def html_body + Capybara.string(response.body) + end +end From 5b4015447a41b84e54e12ca07398f4898df02a43 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Thu, 23 Apr 2026 17:06:37 -0400 Subject: [PATCH 7/7] TEMP --- spec/unit/batch_actions/resource_spec.rb | 2 +- spec/unit/collection_decorator_spec.rb | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/spec/unit/batch_actions/resource_spec.rb b/spec/unit/batch_actions/resource_spec.rb index 99b3c8488bb..e72989a236e 100644 --- a/spec/unit/batch_actions/resource_spec.rb +++ b/spec/unit/batch_actions/resource_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require "rails_helper" -RSpec.describe ActiveAdmin::BatchActions::ResourceExtension do +RSpec.describe "ActiveAdmin::BatchActions::ResourceExtension" do let(:resource) do namespace = ActiveAdmin::Namespace.new(ActiveAdmin::Application.new, :admin) namespace.batch_actions = true diff --git a/spec/unit/collection_decorator_spec.rb b/spec/unit/collection_decorator_spec.rb index 9aaf0c62d45..450919c08ab 100644 --- a/spec/unit/collection_decorator_spec.rb +++ b/spec/unit/collection_decorator_spec.rb @@ -1,28 +1,30 @@ # frozen_string_literal: true require "rails_helper" -class NumberDecorator - def initialize(number) - @number = number - end +RSpec.describe "ActiveAdmin::CollectionDecorator" do + let(:number_decorator) do + Class.new do + def initialize(number) + @number = number + end - def selectable? - @number.even? + def selectable? + @number.even? + end + end end -end -RSpec.describe ActiveAdmin::CollectionDecorator do describe "#decorated_collection" do subject { collection.decorated_collection } - let(:collection) { ActiveAdmin::CollectionDecorator.decorate((1..10).to_a, with: NumberDecorator) } + let(:collection) { ActiveAdmin::CollectionDecorator.decorate((1..10).to_a, with: number_decorator) } it "returns an array of decorated objects" do - expect(subject).to all(be_a(NumberDecorator)) + expect(subject).to all(be_a(number_decorator)) end end describe "array methods" do - subject { ActiveAdmin::CollectionDecorator.decorate((1..10).to_a, with: NumberDecorator) } + subject { ActiveAdmin::CollectionDecorator.decorate((1..10).to_a, with: number_decorator) } it "delegates them to the decorated collection" do expect(subject.count(&:selectable?)).to eq(5)