admin_suite 0.5.0 → 0.6.2

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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -0
  3. data/CHANGELOG.md +78 -11
  4. data/CONTRIBUTING.md +9 -4
  5. data/Gemfile +1 -0
  6. data/README.md +25 -5
  7. data/app/controllers/admin_suite/application_controller.rb +12 -11
  8. data/app/controllers/admin_suite/mcp_controller.rb +36 -0
  9. data/app/controllers/admin_suite/resources_controller.rb +7 -78
  10. data/app/views/admin_suite/resources/index.html.erb +1 -0
  11. data/config/routes.rb +5 -0
  12. data/lib/admin/base/resource.rb +7 -29
  13. data/lib/admin_suite/auth/host_user.rb +42 -0
  14. data/lib/admin_suite/auth/strategy.rb +1 -1
  15. data/lib/admin_suite/auth.rb +15 -0
  16. data/lib/admin_suite/authorization_context.rb +28 -0
  17. data/lib/admin_suite/configuration.rb +56 -2
  18. data/lib/admin_suite/mcp/authorization.rb +68 -0
  19. data/lib/admin_suite/mcp/serializer.rb +138 -0
  20. data/lib/admin_suite/mcp/tools/aggregate.rb +55 -0
  21. data/lib/admin_suite/mcp/tools/describe_resources.rb +63 -0
  22. data/lib/admin_suite/mcp/tools/get_record.rb +41 -0
  23. data/lib/admin_suite/mcp/tools/list_records.rb +67 -0
  24. data/lib/admin_suite/mcp.rb +53 -0
  25. data/lib/admin_suite/query.rb +71 -0
  26. data/lib/admin_suite/ui/show_value_formatter.rb +2 -2
  27. data/lib/admin_suite/version.rb +1 -1
  28. data/lib/admin_suite.rb +14 -9
  29. data/lib/generators/admin_suite/install/templates/admin_suite.rb +5 -2
  30. data/test/archspec/enforcement_test.rb +115 -0
  31. data/test/controllers/resources_controller_test.rb +19 -13
  32. data/test/dummy/config/environments/development.rb +9 -6
  33. data/test/dummy_boot_test.rb +21 -0
  34. data/test/integration/authentication_test.rb +10 -0
  35. data/test/integration/authorization_test.rb +20 -3
  36. data/test/integration/index_query_characterization_test.rb +229 -0
  37. data/test/integration/mcp_aggregate_test.rb +44 -0
  38. data/test/integration/mcp_authorization_test.rb +102 -0
  39. data/test/integration/mcp_endpoint_test.rb +89 -0
  40. data/test/integration/mcp_get_record_test.rb +62 -0
  41. data/test/integration/mcp_instrumentation_test.rb +107 -0
  42. data/test/integration/mcp_list_records_test.rb +75 -0
  43. data/test/integration/mcp_parity_test.rb +155 -0
  44. data/test/integration/mcp_release_test.rb +131 -0
  45. data/test/integration/read_only_resource_test.rb +128 -2
  46. data/test/integration/searchable_select_search_test.rb +5 -4
  47. data/test/lib/action_executor_test.rb +17 -9
  48. data/test/lib/auth_host_user_test.rb +52 -0
  49. data/test/lib/auth_http_basic_test.rb +10 -0
  50. data/test/lib/auth_test.rb +20 -3
  51. data/test/lib/authorization_context_test.rb +127 -0
  52. data/test/lib/engine_defaults_test.rb +1 -2
  53. data/test/lib/mcp_serializer_test.rb +107 -0
  54. data/test/lib/query_test.rb +91 -0
  55. data/test/lib/removed_deprecations_test.rb +16 -0
  56. data/test/publish_workflow_test.rb +63 -0
  57. data/test/test_helper.rb +26 -0
  58. metadata +44 -5
  59. data/lib/admin_suite/renderers/legacy_gleania.rb +0 -232
  60. data/test/lib/legacy_renderer_deprecation_test.rb +0 -42
  61. data/test/lib/resource_exportable_deprecation_test.rb +0 -47
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class McpSerializerTest < ActiveSupport::TestCase
6
+ Column = Data.define(:name)
7
+ Index = Data.define(:columns_list)
8
+ Config = Data.define(:index_config)
9
+
10
+ test "emits only the resource's declared columns" do
11
+ record = Struct.new(:id, :name, :secret_token).new(1, "Widget", "sh-hh")
12
+ config = Config.new(Index.new([Column.new(:id), Column.new(:name)]))
13
+
14
+ row = AdminSuite::Mcp::Serializer.index_row(record, config)
15
+
16
+ assert_equal %w[id name], row.keys.map(&:to_s).sort
17
+ refute_includes row.keys.map(&:to_s), "secret_token"
18
+ end
19
+
20
+ test "a raising accessor degrades that cell, not the row" do
21
+ record = Object.new
22
+ def record.id = 1
23
+ def record.name = raise("boom")
24
+ config = Config.new(Index.new([Column.new(:id), Column.new(:name)]))
25
+
26
+ row = AdminSuite::Mcp::Serializer.index_row(record, config)
27
+
28
+ assert_equal 1, row[:id]
29
+ assert_nil row[:name]
30
+ end
31
+
32
+ test "association panels return bounded rows containing only declared columns" do
33
+ show = Admin::Base::Resource::ShowConfig.new
34
+ show.panel :children, association: :children, columns: [:name], limit: 500
35
+ config = Struct.new(:show_config).new(show)
36
+ child = Struct.new(:name, :secret_token).new("Visible", "private")
37
+ record = Struct.new(:children).new(Array.new(150, child))
38
+
39
+ payload = AdminSuite::Mcp::Serializer.associations_payload(record, config, max_rows: 100)
40
+ assert_equal 100, payload.fetch(:children).fetch(:rows).size
41
+ assert_equal({ name: "Visible" }, payload.fetch(:children).fetch(:rows).first)
42
+ assert_equal 100, payload.fetch(:children).fetch(:applied_limit)
43
+ refute_includes JSON.generate(payload), "private"
44
+ end
45
+
46
+ test "association panels without declared columns do not serialize model attributes" do
47
+ show = Admin::Base::Resource::ShowConfig.new
48
+ show.panel :children, association: :children
49
+ config = Struct.new(:show_config).new(show)
50
+ record = Object.new
51
+ def record.children = raise("must not load an undeclared field set")
52
+
53
+ assert_empty AdminSuite::Mcp::Serializer.associations_payload(record, config, max_rows: 100)
54
+ end
55
+
56
+ test "a content lambda serializes the proc result, not a missing attribute" do
57
+ record = Struct.new(:id).new(1)
58
+ column = Admin::Base::Resource::ColumnDefinition.new(name: :listings_count, content: ->(_r) { 42 })
59
+ config = Config.new(Index.new([column]))
60
+
61
+ assert_equal 42, AdminSuite::Mcp::Serializer.index_row(record, config)[:listings_count]
62
+ end
63
+
64
+ test "a label lambda serializes the proc result" do
65
+ record = Struct.new(:id).new(1)
66
+ column = Admin::Base::Resource::ColumnDefinition.new(name: :status, content: ->(_r) { "active" }, type: :label)
67
+ config = Config.new(Index.new([column]))
68
+
69
+ assert_equal "active", AdminSuite::Mcp::Serializer.index_row(record, config)[:status]
70
+ end
71
+
72
+ test "declared times and associations serialize as parseable primitives, not heap dumps" do
73
+ created_at = Time.utc(2026, 9, 10, 12, 0, 0)
74
+ application = SerializerApplication.new(id: 7, name: "Acme")
75
+ record = Struct.new(:created_at, :application, :blob).new(created_at, application, SerializerOpaque.new)
76
+ config = Config.new(Index.new([Column.new(:created_at), Column.new(:application), Column.new(:blob)]))
77
+
78
+ row = AdminSuite::Mcp::Serializer.index_row(record, config)
79
+ text = AdminSuite::Mcp::Serializer.dump(row)
80
+
81
+ assert_equal "2026-09-10T12:00:00Z", row[:created_at]
82
+ assert_equal created_at, Time.iso8601(row[:created_at])
83
+ assert_equal "Acme", row[:application]
84
+ refute_match(/#<|0x[0-9a-f]+/i, text)
85
+ end
86
+
87
+ test "a missing association panel degrades that panel instead of raising" do
88
+ show = Admin::Base::Resource::ShowConfig.new
89
+ show.panel :children, association: :missing_kids, columns: [:name]
90
+ config = Struct.new(:show_config).new(show)
91
+
92
+ payload = AdminSuite::Mcp::Serializer.associations_payload(Object.new, config, max_rows: 100)
93
+
94
+ assert_equal [], payload.fetch(:children).fetch(:rows)
95
+ end
96
+
97
+ class SerializerApplication < ActiveRecord::Base
98
+ attr_reader :id, :name
99
+
100
+ def initialize(id:, name:)
101
+ @id = id
102
+ @name = name
103
+ end
104
+ end
105
+
106
+ class SerializerOpaque; end
107
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class QueryTest < ActiveSupport::TestCase
6
+ Config = Struct.new(:model_class, :index_config)
7
+ IndexConfig = Struct.new(
8
+ :per_page,
9
+ :includes_list,
10
+ :searchable_fields,
11
+ :filters_list,
12
+ :default_sort,
13
+ :sortable_fields,
14
+ :default_sort_direction
15
+ )
16
+
17
+ class RaisingIncludesRelation < ReadOnlyResourceFixtures::Relation
18
+ def includes(*)
19
+ raise ArgumentError, "bad association"
20
+ end
21
+ end
22
+
23
+ class Model
24
+ class << self
25
+ attr_accessor :relation
26
+
27
+ def all = relation
28
+ end
29
+ end
30
+
31
+ test "per_page falls back to the DSL value when no param is given" do
32
+ query = AdminSuite::Query.new(resource_config: config_with(per_page: 30), params: {})
33
+
34
+ assert_equal 30, query.per_page
35
+ end
36
+
37
+ test "per_page honours the param" do
38
+ query = AdminSuite::Query.new(resource_config: config_with(per_page: 30), params: { per_page: "50" })
39
+
40
+ assert_equal 50, query.per_page
41
+ end
42
+
43
+ test "per_page clamps to MAX_PAGE_SIZE" do
44
+ query = AdminSuite::Query.new(resource_config: config_with(per_page: 30), params: { per_page: "999999" })
45
+
46
+ assert_equal AdminSuite::Query::MAX_PAGE_SIZE, query.per_page
47
+ end
48
+
49
+ test "per_page falls back for junk and non-positive values" do
50
+ ["abc", "0", "-5", nil, "", [], true].each do |value|
51
+ query = AdminSuite::Query.new(resource_config: config_with(per_page: 30), params: { per_page: value })
52
+
53
+ assert_equal 30, query.per_page, "per_page: #{value.inspect} must fall back to the DSL value"
54
+ end
55
+ end
56
+
57
+ test "the cap applies to DSL defaults as well as explicit page sizes" do
58
+ [nil, "", "bad", 0, -1, [], true, 5000].each do |value|
59
+ query = AdminSuite::Query.new(resource_config: config_with(per_page: 500),
60
+ params: { per_page: value }, max_page_size: 40)
61
+ assert_equal 40, query.per_page, "per_page=#{value.inspect}"
62
+ end
63
+ end
64
+
65
+ test "per_page remains a positive integer when max_page_size is below 1" do
66
+ [0, -5, nil].each do |cap|
67
+ query = AdminSuite::Query.new(
68
+ resource_config: config_with(per_page: 30),
69
+ params: { per_page: "10" },
70
+ max_page_size: cap
71
+ )
72
+
73
+ assert_kind_of Integer, query.per_page, "max_page_size=#{cap.inspect}"
74
+ assert_operator query.per_page, :>, 0, "max_page_size=#{cap.inspect}"
75
+ end
76
+ end
77
+
78
+ test "a raising includes degrades to the unoptimized scope instead of raising" do
79
+ relation = RaisingIncludesRelation.new([])
80
+ Model.relation = relation
81
+ query = AdminSuite::Query.new(resource_config: config_with(per_page: 25, includes: [:nope]), params: {})
82
+
83
+ assert_same relation, query.scope
84
+ end
85
+
86
+ private
87
+
88
+ def config_with(per_page:, includes: [])
89
+ Config.new(Model, IndexConfig.new(per_page, includes, [], [], nil, [], :asc))
90
+ end
91
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class RemovedDeprecationsTest < ActiveSupport::TestCase
6
+ test "the gem has no legacy Gleania renderer implementations or defaults" do
7
+ refute defined?(AdminSuite::Renderers::LegacyGleania)
8
+ %i[prompt_template_preview messages_preview tool_args_preview turn_messages_preview].each do |key|
9
+ assert_nil AdminSuite::RendererRegistry.lookup_default(key)
10
+ end
11
+ end
12
+
13
+ test "exportable is no longer a resource DSL method" do
14
+ refute Admin::Base::Resource.respond_to?(:exportable)
15
+ end
16
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "minitest/autorun"
4
+ require "yaml"
5
+
6
+ class PublishWorkflowTest < Minitest::Test
7
+ WORKFLOW_PATH = File.expand_path("../.github/workflows/publish.yml", __dir__)
8
+
9
+ def setup
10
+ @source = File.read(WORKFLOW_PATH)
11
+ @workflow = YAML.load_file(WORKFLOW_PATH)
12
+ @job = @workflow.fetch("jobs").fetch("publish")
13
+ @steps = @job.fetch("steps")
14
+ end
15
+
16
+ def test_publishing_uses_the_release_environment_and_job_scoped_oidc
17
+ assert_equal "release", @job["environment"]
18
+ assert_equal "write", @job.fetch("permissions")["id-token"]
19
+ assert_equal "write", @job.fetch("permissions")["contents"]
20
+ refute @workflow.fetch("permissions", {}).key?("id-token")
21
+ end
22
+
23
+ def test_automatic_publishing_requires_successful_main_push_ci
24
+ condition = @job.fetch("if")
25
+ assert_includes condition, "github.repository == 'techwright-lab/admin_suite'"
26
+ assert_includes condition, "github.event_name == 'workflow_run'"
27
+ assert_includes condition, "github.event.workflow_run.conclusion == 'success'"
28
+ assert_includes condition, "github.event.workflow_run.event == 'push'"
29
+ assert_includes condition, "github.event.workflow_run.head_branch == 'main'"
30
+ assert_includes condition, "github.event.workflow_run.head_repository.full_name == github.repository"
31
+ assert_includes condition, "github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main'"
32
+ end
33
+
34
+ def test_credentials_are_pinned_conditional_and_before_the_push
35
+ credentials_index = @steps.index { |step| step["name"] == "Configure RubyGems trusted publishing" }
36
+ refute_nil credentials_index
37
+ credentials = @steps.fetch(credentials_index)
38
+ push_index = @steps.index { |step| step["name"] == "Publish to RubyGems" }
39
+ push = @steps.fetch(push_index)
40
+
41
+ assert_equal "rubygems/configure-rubygems-credentials@dc5a8d8553e6ee01fc26761a49e99e733d17954a", credentials["uses"]
42
+ assert_equal "steps.version_check.outputs.should_publish == 'true'", credentials["if"]
43
+ assert_equal credentials["if"], push["if"]
44
+ assert_operator credentials_index, :<, push_index
45
+ refute_includes @source, "secrets.RUBYGEMS_API_KEY"
46
+ refute_includes @source, "GEM_HOST_API_KEY:"
47
+ refute_includes @source, "~/.gem/credentials"
48
+ assert_includes push.fetch("run"), "gem push"
49
+ assert_includes push.fetch("run"), "--host https://rubygems.org"
50
+ end
51
+
52
+ def test_releases_preserve_tested_sha_and_serialization
53
+ checkout = @steps.find { |step| step.fetch("uses", "").start_with?("actions/checkout@") }
54
+ assert_equal "${{ github.event.workflow_run.head_sha || github.sha }}", checkout.fetch("with")["ref"]
55
+ assert_equal false, @workflow.fetch("concurrency")["cancel-in-progress"]
56
+ assert_includes @source, "different contents. Bump the gem version before publishing."
57
+ push_index = @steps.index { |step| step["name"] == "Publish to RubyGems" }
58
+ tag_index = @steps.index { |step| step["name"] == "Create Git tag" }
59
+ release_index = @steps.index { |step| step["name"] == "Create GitHub Release" }
60
+ assert_operator push_index, :<, tag_index
61
+ assert_operator tag_index, :<, release_index
62
+ end
63
+ end
data/test/test_helper.rb CHANGED
@@ -16,6 +16,15 @@ if ENV["COVERAGE"]
16
16
  end
17
17
 
18
18
  require_relative "dummy/config/environment"
19
+
20
+ # Auth strategies are process-global. Tests that register temporary strategies
21
+ # can restore a snapshot with this helper to avoid cross-file registry leakage.
22
+ def with_auth_registry_snapshot
23
+ registry = AdminSuite::Auth.instance_variable_get(:@registry).dup
24
+ yield
25
+ ensure
26
+ AdminSuite::Auth.instance_variable_set(:@registry, registry)
27
+ end
19
28
  require "minitest/autorun"
20
29
  require "active_support/test_case"
21
30
  require "action_dispatch/testing/integration"
@@ -23,6 +32,14 @@ require "action_dispatch/testing/integration"
23
32
  # Ensure the engine is loaded (and its initializers run).
24
33
  require "admin_suite"
25
34
 
35
+ def with_authorize(hook)
36
+ previous = AdminSuite.config.authorize
37
+ AdminSuite.config.authorize = hook
38
+ yield
39
+ ensure
40
+ AdminSuite.config.authorize = previous
41
+ end
42
+
26
43
  # The dummy app is intentionally database-free, while the generic controller
27
44
  # supports Active Record hosts. Supply only the exception type its lookup path
28
45
  # rescues so show-page behavior can be exercised with an in-memory fixture.
@@ -181,3 +198,12 @@ module Admin
181
198
  end
182
199
  end
183
200
  end
201
+
202
+ # MCP never permits anonymous callers, including in the development escape hatch.
203
+ class McpIntegrationTest < ActionDispatch::IntegrationTest
204
+ setup do
205
+ @previous_mcp_actor_resolver = AdminSuite.config.current_actor
206
+ AdminSuite.config.current_actor = ->(_) { "test-operator" }
207
+ end
208
+ teardown { AdminSuite.config.current_actor = @previous_mcp_actor_resolver }
209
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: admin_suite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - TechWright Labs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-08-01 00:00:00.000000000 Z
11
+ date: 2026-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -50,6 +50,20 @@ dependencies:
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
52
  version: '10'
53
+ - !ruby/object:Gem::Dependency
54
+ name: mcp
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '1.1'
60
+ type: :runtime
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '1.1'
53
67
  - !ruby/object:Gem::Dependency
54
68
  name: turbo-rails
55
69
  requirement: !ruby/object:Gem::Requirement
@@ -152,6 +166,7 @@ files:
152
166
  - app/controllers/admin_suite/application_controller.rb
153
167
  - app/controllers/admin_suite/dashboard_controller.rb
154
168
  - app/controllers/admin_suite/docs_controller.rb
169
+ - app/controllers/admin_suite/mcp_controller.rb
155
170
  - app/controllers/admin_suite/portals_controller.rb
156
171
  - app/controllers/admin_suite/resources_controller.rb
157
172
  - app/helpers/admin_suite/base_helper.rb
@@ -205,8 +220,10 @@ files:
205
220
  - lib/admin_suite.rb
206
221
  - lib/admin_suite/auth.rb
207
222
  - lib/admin_suite/auth/host_hook.rb
223
+ - lib/admin_suite/auth/host_user.rb
208
224
  - lib/admin_suite/auth/http_basic.rb
209
225
  - lib/admin_suite/auth/strategy.rb
226
+ - lib/admin_suite/authorization_context.rb
210
227
  - lib/admin_suite/configuration.rb
211
228
  - lib/admin_suite/definition_loader.rb
212
229
  - lib/admin_suite/deprecation.rb
@@ -214,14 +231,21 @@ files:
214
231
  - lib/admin_suite/host_autoload_policy.rb
215
232
  - lib/admin_suite/legacy_custom_renderer_procs.rb
216
233
  - lib/admin_suite/markdown_renderer.rb
234
+ - lib/admin_suite/mcp.rb
235
+ - lib/admin_suite/mcp/authorization.rb
236
+ - lib/admin_suite/mcp/serializer.rb
237
+ - lib/admin_suite/mcp/tools/aggregate.rb
238
+ - lib/admin_suite/mcp/tools/describe_resources.rb
239
+ - lib/admin_suite/mcp/tools/get_record.rb
240
+ - lib/admin_suite/mcp/tools/list_records.rb
217
241
  - lib/admin_suite/portal_definition.rb
218
242
  - lib/admin_suite/portal_registry.rb
243
+ - lib/admin_suite/query.rb
219
244
  - lib/admin_suite/renderer.rb
220
245
  - lib/admin_suite/renderer_registry.rb
221
246
  - lib/admin_suite/renderers/code_renderer.rb
222
247
  - lib/admin_suite/renderers/json_renderer.rb
223
248
  - lib/admin_suite/renderers/key_value_renderer.rb
224
- - lib/admin_suite/renderers/legacy_gleania.rb
225
249
  - lib/admin_suite/renderers/table_from_renderer.rb
226
250
  - lib/admin_suite/section_definition.rb
227
251
  - lib/admin_suite/theme_palette.rb
@@ -238,6 +262,7 @@ files:
238
262
  - lib/generators/admin_suite/scaffold/scaffold_generator.rb
239
263
  - lib/tasks/admin_suite_tailwind.rake
240
264
  - lib/tasks/admin_suite_test.rake
265
+ - test/archspec/enforcement_test.rb
241
266
  - test/controllers/resources_controller_test.rb
242
267
  - test/dummy/Gemfile
243
268
  - test/dummy/README.md
@@ -281,6 +306,7 @@ files:
281
306
  - test/dummy/public/icon.svg
282
307
  - test/dummy/public/robots.txt
283
308
  - test/dummy/test/test_helper.rb
309
+ - test/dummy_boot_test.rb
284
310
  - test/fixtures/docs/progress/PROGRESS_REPORT.md
285
311
  - test/integration/association_linking_test.rb
286
312
  - test/integration/authentication_test.rb
@@ -288,8 +314,17 @@ files:
288
314
  - test/integration/chart_panel_test.rb
289
315
  - test/integration/dashboard_test.rb
290
316
  - test/integration/docs_test.rb
317
+ - test/integration/index_query_characterization_test.rb
291
318
  - test/integration/index_table_test.rb
292
319
  - test/integration/layout_assets_test.rb
320
+ - test/integration/mcp_aggregate_test.rb
321
+ - test/integration/mcp_authorization_test.rb
322
+ - test/integration/mcp_endpoint_test.rb
323
+ - test/integration/mcp_get_record_test.rb
324
+ - test/integration/mcp_instrumentation_test.rb
325
+ - test/integration/mcp_list_records_test.rb
326
+ - test/integration/mcp_parity_test.rb
327
+ - test/integration/mcp_release_test.rb
293
328
  - test/integration/navigation_sections_test.rb
294
329
  - test/integration/pagination_and_stats_test.rb
295
330
  - test/integration/read_only_resource_test.rb
@@ -299,23 +334,27 @@ files:
299
334
  - test/integration/toggle_test.rb
300
335
  - test/lib/action_executor_redirect_test.rb
301
336
  - test/lib/action_executor_test.rb
337
+ - test/lib/auth_host_user_test.rb
302
338
  - test/lib/auth_http_basic_test.rb
303
339
  - test/lib/auth_resolution_test.rb
304
340
  - test/lib/auth_test.rb
341
+ - test/lib/authorization_context_test.rb
305
342
  - test/lib/builtin_renderers_test.rb
306
343
  - test/lib/definition_loader_test.rb
307
344
  - test/lib/engine_defaults_test.rb
308
345
  - test/lib/form_field_renderer_test.rb
309
346
  - test/lib/format_table_cell_test.rb
310
347
  - test/lib/index_includes_test.rb
311
- - test/lib/legacy_renderer_deprecation_test.rb
312
348
  - test/lib/markdown_renderer_test.rb
349
+ - test/lib/mcp_serializer_test.rb
350
+ - test/lib/query_test.rb
351
+ - test/lib/removed_deprecations_test.rb
313
352
  - test/lib/renderer_test.rb
314
- - test/lib/resource_exportable_deprecation_test.rb
315
353
  - test/lib/resource_observability_extensions_test.rb
316
354
  - test/lib/show_value_formatter_test.rb
317
355
  - test/lib/theme_palette_test.rb
318
356
  - test/lib/zeitwerk_integration_test.rb
357
+ - test/publish_workflow_test.rb
319
358
  - test/test_helper.rb
320
359
  homepage: https://github.com/techwright-lab/admin_suite
321
360
  licenses: