admin_suite 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dbd2bda3cff05667e7f164b70d06c7f91e4ba7cde4dfe720291720fe589cfde6
4
- data.tar.gz: c2fea65bd3721677eee67904174664038c9e256d347770775bbfc3a3714bceb2
3
+ metadata.gz: f761dd4e5538b7fb655ce9a29c936bfa57d1cf56e06d3aa73e064e4721ec69a9
4
+ data.tar.gz: e4a584d9645f7f848ad48c6f94a47ce34d9a9820cbe1c6271c635b17f1176719
5
5
  SHA512:
6
- metadata.gz: 68580753a81e6e77b5a3cda22038f5d62919ab22e3bb00746504e18578847119528872f0bf94960c6d7d0df3ceb06a7df723ae872e8cce7d6d240fc0a5c08ab6
7
- data.tar.gz: b342407db536c0cd5f7264aff7ea6fa57f224b03b66d2675b1b928394490ee743424ea7608ff9845e71e391765ecac7da0823e101b1922cea9c8613dae44c48a
6
+ metadata.gz: 9e0c72f5c7494b4a5378cd0895781bbbb41c8ed372788bf9cbcbeaa2830866f87c0636fce56872ee6998dbb516552f8bd105a828864ee29d7f23cc2ec77949e5
7
+ data.tar.gz: 4f2fc0a2d4d6edcb75ab99d7e888e8cd7abef38a9790e5ff45b74f8a8e6e9b6d7d657186776e2fc4132b59b051b21769ff966b2a33f050007505648116a74652
data/.gitignore CHANGED
@@ -8,4 +8,5 @@
8
8
  !/test/dummy/log/.keep
9
9
  /test/dummy/tmp/
10
10
  /test/dummy/storage/
11
- admin_suite-*.gem
11
+ admin_suite-*.gem
12
+ /.bundle/
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,51 @@
1
+ # Contributing to AdminSuite
2
+
3
+ Thank you for your interest in contributing to AdminSuite!
4
+
5
+ ## Getting Started
6
+
7
+ 1. Fork the repository
8
+ 2. Clone your fork locally
9
+ 3. Install dependencies: `bundle install`
10
+ 4. Run the test suite: `bundle exec rake test`
11
+ 5. (Optional) Run tests with coverage: `COVERAGE=true bundle exec rake test`
12
+
13
+ ## Development
14
+
15
+ See `docs/development.md` for detailed information on:
16
+ - Setting up your development environment
17
+ - Running tests
18
+ - Code style guidelines
19
+
20
+ ## Pull Requests
21
+
22
+ 1. Create a feature branch from `main`
23
+ 2. Make your changes
24
+ 3. Add or update tests as needed
25
+ 4. Ensure all tests pass: `bundle exec rake test`
26
+ 5. Push your branch and create a pull request
27
+
28
+ ### CI Checks
29
+
30
+ All pull requests must pass the following checks before merging:
31
+ - **Tests**: Automated test suite runs on Ruby 3.2 and 3.3
32
+ - **Coverage**: Code coverage is automatically generated and uploaded to Codecov
33
+ - **Code Review**: At least one maintainer approval required
34
+
35
+ The CI workflow runs automatically on every pull request.
36
+
37
+ ## Releasing
38
+
39
+ See `docs/releasing.md` for information on how releases are managed.
40
+
41
+ Releases are automated via GitHub Actions when changes are merged to `main` with a version bump.
42
+
43
+ ### Required Secrets for Maintainers
44
+
45
+ The repository requires the following secrets to be configured:
46
+ - **`RUBYGEMS_API_KEY`**: Required for automated gem publishing to RubyGems
47
+ - **`CODECOV_TOKEN`**: Optional, for uploading code coverage reports to Codecov (workflow continues without it)
48
+
49
+ ## Questions?
50
+
51
+ Feel free to open an issue for questions or discussion.
@@ -36,6 +36,12 @@ These are the defaults in `AdminSuite::Configuration` / `AdminSuite::Engine`:
36
36
  - `Rails.root/config/admin_suite/portals/*.rb`
37
37
  - `Rails.root/app/admin/portals/*.rb`
38
38
  - `Rails.root/app/admin_suite/portals/*.rb`
39
+
40
+ Note: portal files are DSL side-effects (they don't define constants). If your host app
41
+ autoloads `app/admin` as `Admin::*` with Zeitwerk, AdminSuite will ignore
42
+ `app/admin/portals` for Zeitwerk to prevent eager-load `Zeitwerk::NameError`s.
43
+ We recommend placing portal DSL files under `config/admin_suite/portals` or
44
+ `app/admin_suite/portals` when possible.
39
45
  - `portals`: default portal metadata for `:ops`, `:email`, `:ai`, `:assistant`
40
46
  - `custom_renderers`: `{}`
41
47
  - `icon_renderer`: `nil` (uses lucide-rails by default when available)
data/docs/releasing.md CHANGED
@@ -2,15 +2,39 @@
2
2
 
3
3
  This page is intended for maintainers publishing `admin_suite` to RubyGems.
4
4
 
5
- ## Checklist
5
+ ## Automated Release Process (Recommended)
6
6
 
7
- 1. Bump the version
7
+ The gem is automatically published to RubyGems when changes are merged to `main`, provided the version has been bumped.
8
8
 
9
- - Update `lib/admin_suite/version.rb`
9
+ ### Steps
10
10
 
11
- 2. Update changelog
11
+ 1. **Bump the version**
12
+ - Update `lib/admin_suite/version.rb`
13
+
14
+ 2. **Update changelog**
15
+ - Add an entry to `CHANGELOG.md`
16
+
17
+ 3. **Create a PR and get it merged**
18
+ - The CI workflow will run tests automatically on the PR
19
+ - Once merged to `main`, after CI passes, the publish workflow will:
20
+ - Check if the version already exists on RubyGems
21
+ - Build and publish the gem (if it's a new version)
22
+ - Create a Git tag for the release (if it doesn't already exist)
23
+
24
+ ### Requirements
25
+
26
+ - The `RUBYGEMS_API_KEY` secret must be configured in the repository settings
27
+ - The version in `lib/admin_suite/version.rb` must be unique (not already published)
12
28
 
13
- - Add an entry to `CHANGELOG.md`
29
+ ## Manual Release Process
30
+
31
+ If you need to publish manually:
32
+
33
+ 1. Bump the version
34
+ - Update `lib/admin_suite/version.rb`
35
+
36
+ 2. Update changelog
37
+ - Add an entry to `CHANGELOG.md`
14
38
 
15
39
  3. Run tests and build the gem
16
40
 
@@ -19,7 +43,7 @@ bundle exec rake test
19
43
  gem build admin_suite.gemspec
20
44
  ```
21
45
 
22
- 4. (Recommended) Tag the release
46
+ 4. Tag the release
23
47
 
24
48
  ```bash
25
49
  git tag -a "vX.Y.Z" -m "AdminSuite vX.Y.Z"
@@ -32,7 +56,10 @@ git push --tags
32
56
  gem push "admin_suite-X.Y.Z.gem"
33
57
  ```
34
58
 
35
- Notes:
59
+ ## Notes
36
60
 
37
- - RubyGems commonly requires MFA/OTP for pushes (this gem is configured with `rubygems_mfa_required`).
61
+ - RubyGems commonly requires MFA/OTP for pushes (this gem is configured with `rubygems_mfa_required`)
62
+ - The automated workflow uses a GitHub Actions bot to push tags
63
+ - The publish workflow only runs after the CI workflow completes successfully
64
+ - You can manually trigger the publish workflow from the GitHub Actions tab if needed
38
65
 
@@ -14,14 +14,40 @@ module AdminSuite
14
14
  end
15
15
 
16
16
  initializer "admin_suite.host_dsl_ignore" do
17
- # Host apps sometimes store AdminSuite DSL files under `app/admin_suite/**`.
18
- # Those are not constant definitions, so we must prevent Zeitwerk from
19
- # expecting constants like `Portals::Ai` during eager load.
20
- host_dsl_dir = Rails.root.join("app/admin_suite")
21
- next unless host_dsl_dir.exist?
17
+ # Host apps sometimes store AdminSuite DSL files under `app/admin_suite/**`
18
+ # and/or `app/admin/portals/**`.
19
+ #
20
+ # These are *side-effect* DSL files (e.g. `AdminSuite.portal :ops do ... end`),
21
+ # not constant definitions. If a host app adds those dirs to Zeitwerk (common
22
+ # when autoloading `app/admin` as `Admin::*`), eager loading will crash with:
23
+ # expected file ... to define constant ...
24
+ #
25
+ # So we proactively ignore these directories for all Zeitwerk loaders.
26
+ host_dsl_dirs = [ Rails.root.join("app/admin_suite") ]
27
+
28
+ # `app/admin/portals` is a more common location in host apps and could also
29
+ # contain real constants. Only ignore it if it appears to contain AdminSuite
30
+ # portal DSL definitions.
31
+ host_admin_portals_dir = Rails.root.join("app/admin/portals")
32
+ if host_admin_portals_dir.exist?
33
+ portal_files = Dir[host_admin_portals_dir.join("**/*.rb").to_s]
34
+ contains_admin_suite_portals =
35
+ portal_files.any? do |file|
36
+ content = File.binread(file)
37
+ content = content.encode("UTF-8", invalid: :replace, undef: :replace, replace: "")
38
+ portal_dsl_pattern = /(::)?AdminSuite\s*\.\s*portal\b/
39
+ portal_dsl_pattern.match?(content)
40
+ rescue StandardError
41
+ false
42
+ end
43
+
44
+ host_dsl_dirs << host_admin_portals_dir if contains_admin_suite_portals
45
+ end
22
46
 
23
47
  Rails.autoloaders.each do |loader|
24
- loader.ignore(host_dsl_dir)
48
+ host_dsl_dirs.each do |dir|
49
+ loader.ignore(dir) if dir.exist?
50
+ end
25
51
  end
26
52
  end
27
53
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module AdminSuite
4
4
  module Version
5
- VERSION = "0.1.2"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
 
8
8
  # Backward-compatible constant.
data/lib/admin_suite.rb CHANGED
@@ -34,7 +34,10 @@ module AdminSuite
34
34
 
35
35
  # Defines (or updates) a portal using a Ruby DSL.
36
36
  #
37
- # Host apps typically place these in `app/admin/portals/*.rb`.
37
+ # Host apps typically place these in:
38
+ # - `config/admin_suite/portals/*.rb` (recommended; not a Zeitwerk autoload path)
39
+ # - `app/admin_suite/portals/*.rb` (supported; AdminSuite ignores for Zeitwerk)
40
+ # - `app/admin/portals/*.rb` (supported; AdminSuite will ignore for Zeitwerk if files contain `AdminSuite.portal`)
38
41
  #
39
42
  # @param key [Symbol, String]
40
43
  # @yield Portal definition DSL
@@ -24,6 +24,11 @@ AdminSuite.configure do |config|
24
24
  # Files typically call `AdminSuite.portal :ops do ... end`
25
25
  config.portal_globs = [
26
26
  Rails.root.join("config/admin_suite/portals/*.rb").to_s,
27
+ # Prefer `app/admin_suite/portals` for DSL files so Zeitwerk never expects
28
+ # application constants (e.g. `Admin::Portals::OpsPortal` for
29
+ # `app/admin/portals/ops_portal.rb`) during eager load.
30
+ Rails.root.join("app/admin_suite/portals/*.rb").to_s,
31
+ # Legacy/fallback: still support portals defined under app/admin/portals.
27
32
  Rails.root.join("app/admin/portals/*.rb").to_s
28
33
  ]
29
34
 
@@ -0,0 +1,175 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+ require "tmpdir"
5
+
6
+ module AdminSuite
7
+ class ZeitwerkIntegrationTest < ActiveSupport::TestCase
8
+ setup do
9
+ @temp_dir = Dir.mktmpdir("admin_suite_test")
10
+ end
11
+
12
+ teardown do
13
+ FileUtils.rm_rf(@temp_dir) if @temp_dir && File.exist?(@temp_dir)
14
+ end
15
+
16
+ # Helper method to create a loader that tracks ignored directories
17
+ def create_tracked_loader
18
+ loader = Zeitwerk::Loader.new
19
+ ignored_dirs = []
20
+
21
+ loader.define_singleton_method(:ignore) do |path|
22
+ ignored_dirs << path.to_s
23
+ end
24
+
25
+ [loader, ignored_dirs]
26
+ end
27
+
28
+ # Helper method that simulates the Zeitwerk integration logic from engine.rb
29
+ def simulate_zeitwerk_integration(app_root, loader)
30
+ host_dsl_dirs = [app_root.join("app/admin_suite")]
31
+ host_admin_portals_dir = app_root.join("app/admin/portals")
32
+
33
+ if host_admin_portals_dir.exist?
34
+ portal_files = Dir[host_admin_portals_dir.join("**/*.rb").to_s]
35
+ contains_admin_suite_portals =
36
+ portal_files.any? do |file|
37
+ content = File.binread(file).encode("UTF-8", invalid: :replace, undef: :replace, replace: "")
38
+ content.include?("AdminSuite.portal")
39
+ rescue StandardError
40
+ false
41
+ end
42
+
43
+ host_dsl_dirs << host_admin_portals_dir if contains_admin_suite_portals
44
+ end
45
+
46
+ host_dsl_dirs.each do |dir|
47
+ loader.ignore(dir) if dir.exist?
48
+ end
49
+ end
50
+
51
+ test "ignores app/admin/portals when it contains AdminSuite portal DSL" do
52
+ # Create app/admin/portals directory with portal DSL file
53
+ portals_dir = File.join(@temp_dir, "app", "admin", "portals")
54
+ FileUtils.mkdir_p(portals_dir)
55
+ File.write(
56
+ File.join(portals_dir, "ops_portal.rb"),
57
+ "AdminSuite.portal :ops do\n # portal config\nend"
58
+ )
59
+
60
+ # Create loader and simulate initializer logic
61
+ app_root = Pathname.new(@temp_dir)
62
+ loader, ignored_dirs = create_tracked_loader
63
+ simulate_zeitwerk_integration(app_root, loader)
64
+
65
+ # Verify that app/admin/portals was ignored
66
+ expected_path = app_root.join("app/admin/portals").to_s
67
+ assert_includes ignored_dirs, expected_path,
68
+ "Expected app/admin/portals to be ignored when it contains AdminSuite portal DSL"
69
+ end
70
+
71
+ test "does not ignore app/admin/portals when it contains only real constants" do
72
+ # Create app/admin/portals directory with a real constant definition
73
+ portals_dir = File.join(@temp_dir, "app", "admin", "portals")
74
+ FileUtils.mkdir_p(portals_dir)
75
+ File.write(
76
+ File.join(portals_dir, "admin_user.rb"),
77
+ "module Admin\n module Portals\n class AdminUser\n end\n end\nend"
78
+ )
79
+
80
+ # Create loader and simulate initializer logic
81
+ app_root = Pathname.new(@temp_dir)
82
+ loader, ignored_dirs = create_tracked_loader
83
+ simulate_zeitwerk_integration(app_root, loader)
84
+
85
+ # Verify that app/admin/portals was NOT ignored
86
+ unexpected_path = app_root.join("app/admin/portals").to_s
87
+ assert_not_includes ignored_dirs, unexpected_path,
88
+ "Expected app/admin/portals to NOT be ignored when it contains only real constants"
89
+ end
90
+
91
+ test "always ignores app/admin_suite directory when it exists" do
92
+ # Create app/admin_suite directory
93
+ admin_suite_dir = File.join(@temp_dir, "app", "admin_suite")
94
+ FileUtils.mkdir_p(admin_suite_dir)
95
+ File.write(
96
+ File.join(admin_suite_dir, "some_config.rb"),
97
+ "# Some DSL configuration"
98
+ )
99
+
100
+ # Create loader and simulate initializer logic
101
+ app_root = Pathname.new(@temp_dir)
102
+ loader, ignored_dirs = create_tracked_loader
103
+ simulate_zeitwerk_integration(app_root, loader)
104
+
105
+ # Verify that app/admin_suite was ignored
106
+ expected_path = app_root.join("app/admin_suite").to_s
107
+ assert_includes ignored_dirs, expected_path,
108
+ "Expected app/admin_suite to always be ignored"
109
+ end
110
+
111
+ test "handles mixed content - ignores app/admin/portals if any file contains portal DSL" do
112
+ # Create app/admin/portals directory with both real constants and portal DSL
113
+ portals_dir = File.join(@temp_dir, "app", "admin", "portals")
114
+ FileUtils.mkdir_p(portals_dir)
115
+
116
+ # File with real constant
117
+ File.write(
118
+ File.join(portals_dir, "admin_user.rb"),
119
+ "module Admin\n module Portals\n class AdminUser\n end\n end\nend"
120
+ )
121
+
122
+ # File with portal DSL
123
+ File.write(
124
+ File.join(portals_dir, "ops_portal.rb"),
125
+ "AdminSuite.portal :ops do\n # portal config\nend"
126
+ )
127
+
128
+ # Create loader and simulate initializer logic
129
+ app_root = Pathname.new(@temp_dir)
130
+ loader, ignored_dirs = create_tracked_loader
131
+ simulate_zeitwerk_integration(app_root, loader)
132
+
133
+ # Verify that app/admin/portals was ignored due to presence of portal DSL
134
+ expected_path = app_root.join("app/admin/portals").to_s
135
+ assert_includes ignored_dirs, expected_path,
136
+ "Expected app/admin/portals to be ignored when any file contains portal DSL"
137
+ end
138
+
139
+ test "handles file read errors gracefully" do
140
+ # Create app/admin/portals directory with a file
141
+ portals_dir = File.join(@temp_dir, "app", "admin", "portals")
142
+ FileUtils.mkdir_p(portals_dir)
143
+ test_file = File.join(portals_dir, "test.rb")
144
+ File.write(test_file, "AdminSuite.portal :ops do; end")
145
+
146
+ # Create loader
147
+ app_root = Pathname.new(@temp_dir)
148
+ loader, ignored_dirs = create_tracked_loader
149
+
150
+ # Temporarily override File.binread to simulate read errors
151
+ original_binread = File.singleton_class.instance_method(:binread)
152
+
153
+ File.singleton_class.define_method(:binread) do |path|
154
+ if path == test_file
155
+ raise StandardError, "Simulated read error"
156
+ else
157
+ original_binread.bind(File).call(path)
158
+ end
159
+ end
160
+
161
+ begin
162
+ # Simulate the initializer logic
163
+ simulate_zeitwerk_integration(app_root, loader)
164
+
165
+ # Verify that app/admin/portals was NOT ignored due to read error
166
+ unexpected_path = app_root.join("app/admin/portals").to_s
167
+ assert_not_includes ignored_dirs, unexpected_path,
168
+ "Expected app/admin/portals to NOT be ignored when file read fails"
169
+ ensure
170
+ # Restore original method
171
+ File.singleton_class.define_method(:binread, original_binread)
172
+ end
173
+ end
174
+ end
175
+ end
data/test/test_helper.rb CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  ENV["RAILS_ENV"] ||= "test"
4
4
 
5
+ # Configure SimpleCov for coverage reporting
6
+ if ENV["COVERAGE"]
7
+ require "simplecov"
8
+ SimpleCov.start "rails" do
9
+ add_filter "/test/"
10
+ add_filter "/config/"
11
+ add_group "Models", "app/models"
12
+ add_group "Controllers", "app/controllers"
13
+ add_group "Helpers", "app/helpers"
14
+ add_group "Libraries", "lib"
15
+ end
16
+ end
17
+
5
18
  require_relative "dummy/config/environment"
6
19
  require "minitest/autorun"
7
20
  require "active_support/test_case"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: admin_suite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - TechWright Labs
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-02-07 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rails
@@ -115,6 +115,7 @@ extra_rdoc_files: []
115
115
  files:
116
116
  - ".gitignore"
117
117
  - CHANGELOG.md
118
+ - CONTRIBUTING.md
118
119
  - Gemfile
119
120
  - LICENSE.txt
120
121
  - README.md
@@ -236,7 +237,6 @@ files:
236
237
  - test/dummy/config/puma.rb
237
238
  - test/dummy/config/routes.rb
238
239
  - test/dummy/db/seeds.rb
239
- - test/dummy/log/test.log
240
240
  - test/dummy/public/400.html
241
241
  - test/dummy/public/404.html
242
242
  - test/dummy/public/406-unsupported-browser.html
@@ -246,13 +246,13 @@ files:
246
246
  - test/dummy/public/icon.svg
247
247
  - test/dummy/public/robots.txt
248
248
  - test/dummy/test/test_helper.rb
249
- - test/dummy/tmp/local_secret.txt
250
249
  - test/fixtures/docs/progress/PROGRESS_REPORT.md
251
250
  - test/integration/dashboard_test.rb
252
251
  - test/integration/docs_test.rb
253
252
  - test/integration/theme_test.rb
254
253
  - test/lib/markdown_renderer_test.rb
255
254
  - test/lib/theme_palette_test.rb
255
+ - test/lib/zeitwerk_integration_test.rb
256
256
  - test/test_helper.rb
257
257
  homepage: https://github.com/techwright-lab/admin_suite
258
258
  licenses:
@@ -275,7 +275,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
275
275
  - !ruby/object:Gem::Version
276
276
  version: '0'
277
277
  requirements: []
278
- rubygems_version: 3.6.2
278
+ rubygems_version: 3.6.9
279
279
  specification_version: 4
280
280
  summary: Reusable admin suite engine
281
281
  test_files: []
@@ -1,147 +0,0 @@
1
- ------------------------------------------------------------------
2
- AdminSuite::ThemeTest: test_layout_includes_scoped_theme_variables
3
- ------------------------------------------------------------------
4
- Started GET "/internal/admin_suite" for 127.0.0.1 at 2026-02-05 00:05:41 +0100
5
- Processing by AdminSuite::DashboardController#index as HTML
6
- Rendering layout /Users/ravi/projects/techwright/admin_suite_repo/app/views/layouts/admin_suite/application.html.erb
7
- Rendering /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/dashboard/index.html.erb within layouts/admin_suite/application
8
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_health.html.erb (Duration: 0.2ms | GC: 0.0ms)
9
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_health.html.erb (Duration: 0.0ms | GC: 0.0ms)
10
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_health.html.erb (Duration: 0.0ms | GC: 0.0ms)
11
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_health.html.erb (Duration: 0.0ms | GC: 0.0ms)
12
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_cards.html.erb (Duration: 0.4ms | GC: 0.0ms)
13
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_stat.html.erb (Duration: 0.2ms | GC: 0.0ms)
14
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_stat.html.erb (Duration: 0.0ms | GC: 0.0ms)
15
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_stat.html.erb (Duration: 0.0ms | GC: 0.0ms)
16
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_stat.html.erb (Duration: 0.0ms | GC: 0.0ms)
17
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_stat.html.erb (Duration: 0.0ms | GC: 0.0ms)
18
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_recent.html.erb (Duration: 0.3ms | GC: 0.0ms)
19
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_recent.html.erb (Duration: 0.0ms | GC: 0.0ms)
20
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_recent.html.erb (Duration: 0.0ms | GC: 0.0ms)
21
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_recent.html.erb (Duration: 0.0ms | GC: 0.0ms)
22
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/dashboard/index.html.erb within layouts/admin_suite/application (Duration: 13.9ms | GC: 9.4ms)
23
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_sidebar.html.erb (Duration: 0.8ms | GC: 0.0ms)
24
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_sidebar.html.erb (Duration: 0.4ms | GC: 0.0ms)
25
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_topbar.html.erb (Duration: 0.1ms | GC: 0.0ms)
26
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_flash.html.erb (Duration: 1.1ms | GC: 0.0ms)
27
- Rendered layout /Users/ravi/projects/techwright/admin_suite_repo/app/views/layouts/admin_suite/application.html.erb (Duration: 18.4ms | GC: 9.5ms)
28
- Completed 200 OK in 28ms (Views: 19.8ms | GC: 9.7ms)
29
- -----------------------------------------------------------------
30
- AdminSuite::ThemeTest: test_body_is_scoped_with_admin-suite_class
31
- -----------------------------------------------------------------
32
- Started GET "/internal/admin_suite" for 127.0.0.1 at 2026-02-05 00:05:41 +0100
33
- Processing by AdminSuite::DashboardController#index as HTML
34
- Rendering layout /Users/ravi/projects/techwright/admin_suite_repo/app/views/layouts/admin_suite/application.html.erb
35
- Rendering /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/dashboard/index.html.erb within layouts/admin_suite/application
36
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_health.html.erb (Duration: 0.0ms | GC: 0.0ms)
37
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_health.html.erb (Duration: 0.0ms | GC: 0.0ms)
38
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_health.html.erb (Duration: 0.0ms | GC: 0.0ms)
39
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_health.html.erb (Duration: 0.0ms | GC: 0.0ms)
40
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_cards.html.erb (Duration: 0.1ms | GC: 0.0ms)
41
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_stat.html.erb (Duration: 0.0ms | GC: 0.0ms)
42
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_stat.html.erb (Duration: 0.0ms | GC: 0.0ms)
43
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_stat.html.erb (Duration: 0.0ms | GC: 0.0ms)
44
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_stat.html.erb (Duration: 0.0ms | GC: 0.0ms)
45
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_stat.html.erb (Duration: 0.0ms | GC: 0.0ms)
46
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_recent.html.erb (Duration: 0.0ms | GC: 0.0ms)
47
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_recent.html.erb (Duration: 0.0ms | GC: 0.0ms)
48
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_recent.html.erb (Duration: 0.0ms | GC: 0.0ms)
49
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_recent.html.erb (Duration: 0.0ms | GC: 0.0ms)
50
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/dashboard/index.html.erb within layouts/admin_suite/application (Duration: 0.7ms | GC: 0.0ms)
51
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_sidebar.html.erb (Duration: 0.6ms | GC: 0.1ms)
52
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_sidebar.html.erb (Duration: 0.4ms | GC: 0.0ms)
53
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_topbar.html.erb (Duration: 0.0ms | GC: 0.0ms)
54
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_flash.html.erb (Duration: 0.0ms | GC: 0.0ms)
55
- Rendered layout /Users/ravi/projects/techwright/admin_suite_repo/app/views/layouts/admin_suite/application.html.erb (Duration: 1.9ms | GC: 0.1ms)
56
- Completed 200 OK in 2ms (Views: 2.0ms | GC: 0.1ms)
57
- -----------------------------------------------------------------------------------
58
- AdminSuite::ThemePaletteTest: test_resolve_returns_fallback_for_unknown_color/shade
59
- -----------------------------------------------------------------------------------
60
- --------------------------------------------------------------------------------
61
- AdminSuite::ThemePaletteTest: test_resolve_returns_hex_for_known_palette_entries
62
- --------------------------------------------------------------------------------
63
- ------------------------------------------------------------
64
- AdminSuite::ThemePaletteTest: test_hex?_validates_hex_colors
65
- ------------------------------------------------------------
66
- ---------------------------------------------------------------------------
67
- AdminSuite::DashboardTest: test_GET_/internal/admin_suite_renders_dashboard
68
- ---------------------------------------------------------------------------
69
- Started GET "/internal/admin_suite" for 127.0.0.1 at 2026-02-05 00:05:41 +0100
70
- Processing by AdminSuite::DashboardController#index as HTML
71
- Rendering layout /Users/ravi/projects/techwright/admin_suite_repo/app/views/layouts/admin_suite/application.html.erb
72
- Rendering /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/dashboard/index.html.erb within layouts/admin_suite/application
73
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_health.html.erb (Duration: 0.0ms | GC: 0.0ms)
74
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_health.html.erb (Duration: 0.0ms | GC: 0.0ms)
75
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_health.html.erb (Duration: 0.0ms | GC: 0.0ms)
76
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_health.html.erb (Duration: 0.0ms | GC: 0.0ms)
77
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_cards.html.erb (Duration: 0.1ms | GC: 0.0ms)
78
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_stat.html.erb (Duration: 0.0ms | GC: 0.0ms)
79
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_stat.html.erb (Duration: 0.0ms | GC: 0.0ms)
80
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_stat.html.erb (Duration: 0.0ms | GC: 0.0ms)
81
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_stat.html.erb (Duration: 0.0ms | GC: 0.0ms)
82
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_stat.html.erb (Duration: 0.0ms | GC: 0.0ms)
83
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_recent.html.erb (Duration: 0.0ms | GC: 0.0ms)
84
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_recent.html.erb (Duration: 0.0ms | GC: 0.0ms)
85
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_recent.html.erb (Duration: 0.0ms | GC: 0.0ms)
86
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/panels/_recent.html.erb (Duration: 0.0ms | GC: 0.0ms)
87
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/dashboard/index.html.erb within layouts/admin_suite/application (Duration: 0.6ms | GC: 0.0ms)
88
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_sidebar.html.erb (Duration: 0.4ms | GC: 0.0ms)
89
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_sidebar.html.erb (Duration: 0.4ms | GC: 0.0ms)
90
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_topbar.html.erb (Duration: 0.0ms | GC: 0.0ms)
91
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_flash.html.erb (Duration: 0.0ms | GC: 0.0ms)
92
- Rendered layout /Users/ravi/projects/techwright/admin_suite_repo/app/views/layouts/admin_suite/application.html.erb (Duration: 1.7ms | GC: 0.0ms)
93
- Completed 200 OK in 2ms (Views: 1.8ms | GC: 0.0ms)
94
- ----------------------------------------------------------------------------------
95
- AdminSuite::MarkdownRendererTest: test_renders_html_and_extracts_toc_from_headings
96
- ----------------------------------------------------------------------------------
97
- -------------------------------------------------------------------------
98
- AdminSuite::DocsTest: test_docs_path_config_can_be_overridden_with_a_proc
99
- -------------------------------------------------------------------------
100
- Started GET "/internal/admin_suite/docs" for 127.0.0.1 at 2026-02-05 00:05:41 +0100
101
- Processing by AdminSuite::DocsController#index as HTML
102
- Rendering layout /Users/ravi/projects/techwright/admin_suite_repo/app/views/layouts/admin_suite/application.html.erb
103
- Rendering /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/docs/index.html.erb within layouts/admin_suite/application
104
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/docs/index.html.erb within layouts/admin_suite/application (Duration: 0.2ms | GC: 0.0ms)
105
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_sidebar.html.erb (Duration: 0.4ms | GC: 0.0ms)
106
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_sidebar.html.erb (Duration: 0.4ms | GC: 0.0ms)
107
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_topbar.html.erb (Duration: 0.0ms | GC: 0.0ms)
108
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_flash.html.erb (Duration: 0.0ms | GC: 0.0ms)
109
- Rendered layout /Users/ravi/projects/techwright/admin_suite_repo/app/views/layouts/admin_suite/application.html.erb (Duration: 1.3ms | GC: 0.0ms)
110
- Completed 200 OK in 2ms (Views: 1.4ms | GC: 0.0ms)
111
- ------------------------------------------------------------------------------
112
- AdminSuite::DocsTest: test_GET_/internal/admin_suite/docs_renders_successfully
113
- ------------------------------------------------------------------------------
114
- Started GET "/internal/admin_suite/docs" for 127.0.0.1 at 2026-02-05 00:05:41 +0100
115
- Processing by AdminSuite::DocsController#index as HTML
116
- Rendering layout /Users/ravi/projects/techwright/admin_suite_repo/app/views/layouts/admin_suite/application.html.erb
117
- Rendering /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/docs/index.html.erb within layouts/admin_suite/application
118
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/docs/index.html.erb within layouts/admin_suite/application (Duration: 0.1ms | GC: 0.0ms)
119
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_sidebar.html.erb (Duration: 0.4ms | GC: 0.0ms)
120
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_sidebar.html.erb (Duration: 0.4ms | GC: 0.0ms)
121
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_topbar.html.erb (Duration: 0.0ms | GC: 0.0ms)
122
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_flash.html.erb (Duration: 0.0ms | GC: 0.0ms)
123
- Rendered layout /Users/ravi/projects/techwright/admin_suite_repo/app/views/layouts/admin_suite/application.html.erb (Duration: 1.2ms | GC: 0.0ms)
124
- Completed 200 OK in 2ms (Views: 1.2ms | GC: 0.0ms)
125
- -----------------------------------------------------
126
- AdminSuite::DocsTest: test_docs_blocks_path_traversal
127
- -----------------------------------------------------
128
- Started GET "/internal/admin_suite/docs/../../secrets.md" for 127.0.0.1 at 2026-02-05 00:05:41 +0100
129
- Processing by AdminSuite::DocsController#show as MD
130
- Parameters: {"path" => "../../secrets.md"}
131
- Redirected to http://www.example.com/internal/admin_suite/docs/
132
- Completed 302 Found in 0ms (GC: 0.0ms)
133
- ---------------------------------------------------------------------------------------
134
- AdminSuite::DocsTest: test_GET_/internal/admin_suite/docs/<path>_renders_a_markdown_doc
135
- ---------------------------------------------------------------------------------------
136
- Started GET "/internal/admin_suite/docs/progress/PROGRESS_REPORT.md" for 127.0.0.1 at 2026-02-05 00:05:41 +0100
137
- Processing by AdminSuite::DocsController#show as MD
138
- Parameters: {"path" => "progress/PROGRESS_REPORT.md"}
139
- Rendering layout /Users/ravi/projects/techwright/admin_suite_repo/app/views/layouts/admin_suite/application.html.erb
140
- Rendering /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/docs/index.html.erb within layouts/admin_suite/application
141
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/docs/index.html.erb within layouts/admin_suite/application (Duration: 0.0ms | GC: 0.0ms)
142
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_sidebar.html.erb (Duration: 0.4ms | GC: 0.0ms)
143
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_sidebar.html.erb (Duration: 4.1ms | GC: 3.6ms)
144
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_topbar.html.erb (Duration: 0.0ms | GC: 0.0ms)
145
- Rendered /Users/ravi/projects/techwright/admin_suite_repo/app/views/admin_suite/shared/_flash.html.erb (Duration: 0.0ms | GC: 0.0ms)
146
- Rendered layout /Users/ravi/projects/techwright/admin_suite_repo/app/views/layouts/admin_suite/application.html.erb (Duration: 4.9ms | GC: 3.6ms)
147
- Completed 200 OK in 5ms (Views: 5.0ms | GC: 3.6ms)
@@ -1 +0,0 @@
1
- 779b8d659160590188c0642593c35a5df6e84bf258fa58b6e8d5e8ccfa620a8c36e911e98a2736ebfd699b1359e726ab30c27ab8a6ef25ed10d9fadacaff451f