plutonium 0.46.0 → 0.48.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 +4 -4
- data/.claude/skills/plutonium/SKILL.md +4 -0
- data/.claude/skills/plutonium-interaction/SKILL.md +23 -0
- data/.claude/skills/plutonium-nested-resources/SKILL.md +10 -0
- data/.claude/skills/plutonium-testing/SKILL.md +268 -0
- data/.yarnrc.yml +1 -0
- data/CHANGELOG.md +23 -0
- data/Rakefile +10 -1
- data/app/assets/plutonium.css +1 -1
- data/docs/.vitepress/config.ts +6 -0
- data/docs/guides/nested-resources.md +10 -0
- data/docs/guides/testing.md +154 -0
- data/docs/reference/controller/index.md +9 -4
- data/docs/superpowers/plans/2026-04-14-plutonium-testing.md +2046 -0
- data/docs/superpowers/plans/2026-04-14-plutonium-testing.md.tasks.json +21 -0
- data/docs/superpowers/specs/2026-04-14-plutonium-testing-design.md +364 -0
- data/gemfiles/rails_8.1.gemfile.lock +27 -1
- data/lib/generators/pu/test/install/install_generator.rb +34 -0
- data/lib/generators/pu/test/install/templates/plutonium_testing.rb.tt +14 -0
- data/lib/generators/pu/test/scaffold/scaffold_generator.rb +55 -0
- data/lib/generators/pu/test/scaffold/templates/integration_test.rb.tt +65 -0
- data/lib/plutonium/action/interactive.rb +2 -1
- data/lib/plutonium/core/controller.rb +18 -1
- data/lib/plutonium/helpers/turbo_stream_actions_helper.rb +20 -1
- data/lib/plutonium/testing/auth_helpers.rb +62 -0
- data/lib/plutonium/testing/dsl.rb +73 -0
- data/lib/plutonium/testing/nested_resource.rb +58 -0
- data/lib/plutonium/testing/portal_access.rb +49 -0
- data/lib/plutonium/testing/resource_crud.rb +104 -0
- data/lib/plutonium/testing/resource_definition.rb +61 -0
- data/lib/plutonium/testing/resource_interaction.rb +51 -0
- data/lib/plutonium/testing/resource_model.rb +53 -0
- data/lib/plutonium/testing/resource_policy.rb +72 -0
- data/lib/plutonium/testing.rb +16 -0
- data/lib/plutonium/ui/action_button.rb +1 -1
- data/lib/plutonium/version.rb +1 -1
- data/lib/plutonium.rb +2 -0
- data/package.json +1 -1
- data/plutonium.gemspec +2 -0
- data/yarn.lock +6037 -3893
- metadata +50 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d07d40ddf359fb63528f92bae1e1c10c0ec19d4d8101a7202e1c7ae30a798e90
|
|
4
|
+
data.tar.gz: 30fe5b1d2c89bd08552b3d64eb84795bc12e5417805b7ffd6c18f84f5f05d8d1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f5652a759d23236d48265376846ed7269a34ab6a7796bb40c6cc2331a7be308a8de472cda0405e7453ce52ae6452bcb291aaf2c784d305a9dbec451d1be3efa8
|
|
7
|
+
data.tar.gz: 3aee38cfc32329df17558559fcda9f1cae1c0605dc8c5a70d3e8ccd74ec5a4de9a04082e95b7368a07e812fe9a1b7d59e89405077e1dfb8210241710f59b3397
|
|
@@ -61,6 +61,7 @@ Optional additions when relevant:
|
|
|
61
61
|
| Create a portal or feature package | `plutonium-portal` / `plutonium-package` |
|
|
62
62
|
| Mount a portal, configure entity strategies, route portal resources | `plutonium-portal` (+ `plutonium-entity-scoping` for tenancy) |
|
|
63
63
|
| Install Plutonium in a Rails app | `plutonium-installation` |
|
|
64
|
+
| Write tests for a resource, run `pu:test:scaffold`, or include `Plutonium::Testing::*` concerns | `plutonium-testing` |
|
|
64
65
|
|
|
65
66
|
## Generator catalog
|
|
66
67
|
|
|
@@ -87,6 +88,8 @@ Every Plutonium generator is discoverable via `rails g pu:<tab>`. Always pass `-
|
|
|
87
88
|
| `pu:field:renderer NAME` | Custom display renderer | `plutonium-definition` |
|
|
88
89
|
| `pu:eject:layout` | Eject the base layout for customization | `plutonium-views` |
|
|
89
90
|
| `pu:skills:sync` | Sync Plutonium Claude skills into the project | `plutonium` |
|
|
91
|
+
| `pu:test:install` | Install Plutonium::Testing scaffolding | `plutonium-testing` |
|
|
92
|
+
| `pu:test:scaffold NAME --portals=...` | Scaffold integration tests per (resource × portal) | `plutonium-testing` |
|
|
90
93
|
|
|
91
94
|
## Resource architecture at a glance
|
|
92
95
|
|
|
@@ -144,3 +147,4 @@ Meta-generators (`pu:saas:setup`) propagate these flags to the generators they c
|
|
|
144
147
|
- `plutonium-installation` · `plutonium-create-resource` · `plutonium-model` · `plutonium-policy` · `plutonium-entity-scoping` · `plutonium-portal` · `plutonium-definition`
|
|
145
148
|
- `plutonium-controller` · `plutonium-interaction` · `plutonium-views` · `plutonium-forms` · `plutonium-assets`
|
|
146
149
|
- `plutonium-auth` · `plutonium-invites` · `plutonium-package` · `plutonium-nested-resources`
|
|
150
|
+
- `plutonium-testing` — default test concerns and scaffolding
|
|
@@ -373,6 +373,29 @@ class Company::InviteUserInteraction < Plutonium::Resource::Interaction
|
|
|
373
373
|
end
|
|
374
374
|
```
|
|
375
375
|
|
|
376
|
+
## Generating Interaction URLs
|
|
377
|
+
|
|
378
|
+
Use the `interaction:` kwarg on `resource_url_for`. The action type (record/bulk/resource) is inferred from the element and presence of `ids:`:
|
|
379
|
+
|
|
380
|
+
```ruby
|
|
381
|
+
# Record action — instance argument
|
|
382
|
+
resource_url_for(@post, interaction: :publish)
|
|
383
|
+
# => /posts/:id/record_actions/publish
|
|
384
|
+
|
|
385
|
+
# Resource (class-level) action — class with no ids
|
|
386
|
+
resource_url_for(Post, interaction: :import)
|
|
387
|
+
# => /posts/resource_actions/import
|
|
388
|
+
|
|
389
|
+
# Bulk action — class + ids
|
|
390
|
+
resource_url_for(Post, interaction: :archive, ids: [1, 2, 3])
|
|
391
|
+
# => /posts/bulk_actions/archive?ids[]=1&ids[]=2&ids[]=3
|
|
392
|
+
|
|
393
|
+
# Composes with parent / entity scoping
|
|
394
|
+
resource_url_for(@post, parent: @user, interaction: :publish)
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
The same URL serves both GET (form/confirmation) and POST (commit) — the verb determines which controller action runs. Passing both `interaction:` and `action:` raises `ArgumentError`.
|
|
398
|
+
|
|
376
399
|
## Best Practices
|
|
377
400
|
|
|
378
401
|
1. **Keep interactions focused** - One action per interaction
|
|
@@ -178,6 +178,16 @@ resource_url_for(company_profile, parent: company)
|
|
|
178
178
|
|
|
179
179
|
resource_url_for(CompanyProfile, action: :new, parent: company)
|
|
180
180
|
# => /companies/123/nested_company_profile/new
|
|
181
|
+
|
|
182
|
+
# Interactions (composes with parent — see plutonium-interaction skill)
|
|
183
|
+
resource_url_for(property, parent: company, interaction: :archive)
|
|
184
|
+
# => /companies/123/nested_properties/456/record_actions/archive
|
|
185
|
+
|
|
186
|
+
resource_url_for(Property, parent: company, interaction: :import)
|
|
187
|
+
# => /companies/123/nested_properties/resource_actions/import
|
|
188
|
+
|
|
189
|
+
resource_url_for(Property, parent: company, interaction: :bulk_delete, ids: [1, 2])
|
|
190
|
+
# => /companies/123/nested_properties/bulk_actions/bulk_delete?ids[]=1&ids[]=2
|
|
181
191
|
```
|
|
182
192
|
|
|
183
193
|
### Cross-Package URL Generation
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plutonium-testing
|
|
3
|
+
description: Use BEFORE writing tests for a Plutonium resource, running pu:test:scaffold, or including Plutonium::Testing::* concerns. Covers the full testing toolkit — CRUD, policy, definition, interaction, model, nested, portal access, and auth helpers.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Plutonium Testing
|
|
7
|
+
|
|
8
|
+
## 🚨 Critical (read first)
|
|
9
|
+
|
|
10
|
+
- **Use the generators.** `pu:test:install` once per app, then `pu:test:scaffold ResourceClass --portals=...` per resource × portal. Hand-written test files drift from conventions.
|
|
11
|
+
- **Tests are opt-in.** `Plutonium::Testing` is only loaded when `require "plutonium/testing"` runs — it's never autoloaded, never present in production.
|
|
12
|
+
- **One file per (resource × portal).** Same model in admin and org portals = two test files. Each portal has different auth, scoping, and allowed actions.
|
|
13
|
+
- **Stub methods are required.** Concerns ship with `NotImplementedError` stubs — your test class supplies the test data via `create_resource!`, `valid_create_params`, `policy_roles`, etc.
|
|
14
|
+
|
|
15
|
+
## Quick start
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Once per app
|
|
19
|
+
rails g pu:test:install
|
|
20
|
+
|
|
21
|
+
# Per resource × portal pairing
|
|
22
|
+
rails g pu:test:scaffold Blogging::Post --portals=admin,org
|
|
23
|
+
|
|
24
|
+
# Run
|
|
25
|
+
bin/rails test
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`pu:test:install` adds `require "plutonium/testing"` to `test/test_helper.rb` and creates `test/support/plutonium_testing.rb` (a stub for non-Rodauth auth overrides).
|
|
29
|
+
|
|
30
|
+
## DSL reference
|
|
31
|
+
|
|
32
|
+
Every concern uses the same class-level DSL:
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
resource_tests_for ResourceClass,
|
|
36
|
+
portal: :admin, # required
|
|
37
|
+
path_prefix: "/admin", # optional override
|
|
38
|
+
parent: :organization, # for nested resources
|
|
39
|
+
actions: %i[index show new create edit update destroy],
|
|
40
|
+
skip: %i[destroy],
|
|
41
|
+
associated_with: :organization, # ResourceModel only
|
|
42
|
+
sgid_routing: true, # ResourceModel only
|
|
43
|
+
has_cents: %i[price] # ResourceModel only
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The **portal symbol** drives:
|
|
47
|
+
|
|
48
|
+
| Derived | `:admin` example | `:org` example |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `path_prefix` | `/admin` | `/org` |
|
|
51
|
+
| Default sign-in helper | admin Rodauth | user Rodauth |
|
|
52
|
+
| Allowed action set | from definition | from definition |
|
|
53
|
+
|
|
54
|
+
`path_prefix` is auto-resolved from the mounted portal engine. For mounts inside `constraints` (typical Plutonium setup), the resolver walks the route tree and finds the engine.
|
|
55
|
+
|
|
56
|
+
## Concerns catalog
|
|
57
|
+
|
|
58
|
+
Each concern is `include`d separately. Pick the ones you need.
|
|
59
|
+
|
|
60
|
+
### `Plutonium::Testing::ResourceCrud`
|
|
61
|
+
|
|
62
|
+
Generates index / show / new / create / edit / update / destroy integration tests against the portal-mounted resource.
|
|
63
|
+
|
|
64
|
+
**Stubs:**
|
|
65
|
+
- `create_resource!` → persisted record
|
|
66
|
+
- `valid_create_params` → Hash for POST
|
|
67
|
+
- `valid_update_params` → Hash for PATCH
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
class AdminPortal::BloggingPostsTest < ActionDispatch::IntegrationTest
|
|
71
|
+
include IntegrationTestHelper
|
|
72
|
+
include Plutonium::Testing::ResourceCrud
|
|
73
|
+
|
|
74
|
+
resource_tests_for Blogging::Post, portal: :admin
|
|
75
|
+
|
|
76
|
+
setup do
|
|
77
|
+
@admin = create_admin!
|
|
78
|
+
@user = create_user!
|
|
79
|
+
@org = create_organization!
|
|
80
|
+
login_as(@admin)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def create_resource! = create_post!(user: @user, organization: @org)
|
|
84
|
+
def valid_create_params
|
|
85
|
+
{title: "x", body: "y", status: :draft, user: @user.to_sgid.to_s, organization: @org.to_sgid.to_s}
|
|
86
|
+
end
|
|
87
|
+
def valid_update_params = {title: "Updated"}
|
|
88
|
+
end
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### `Plutonium::Testing::ResourcePolicy`
|
|
92
|
+
|
|
93
|
+
Asserts the `permit?` matrix across action × role and verifies `relation_scope` returns an `ActiveRecord::Relation`.
|
|
94
|
+
|
|
95
|
+
**Stubs:**
|
|
96
|
+
- `policy_roles` → `{role_sym => -> { account }}`
|
|
97
|
+
- `policy_record` → persisted record under test
|
|
98
|
+
- `policy_matrix` → `{action_sym => [allowed_role_syms]}`
|
|
99
|
+
- `policy_context` (optional) → extra kwargs (defaults to `{entity_scope: nil}`)
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
def policy_roles = {admin: -> { @admin }, member: -> { @user }}
|
|
103
|
+
def policy_record = create_post!(user: @user, organization: @org)
|
|
104
|
+
def policy_matrix = {
|
|
105
|
+
index: %i[admin member], show: %i[admin member],
|
|
106
|
+
create: %i[admin], update: %i[admin], destroy: %i[admin]
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### `Plutonium::Testing::ResourceDefinition`
|
|
111
|
+
|
|
112
|
+
Smoke-tests the resource definition: the class is constantize-able, every defineable prop dictionary (fields/inputs/displays/columns/scopes/filters/sorts/actions) is queryable, and declared fields exist on the model.
|
|
113
|
+
|
|
114
|
+
**No stubs required** for the happy path.
|
|
115
|
+
|
|
116
|
+
### `Plutonium::Testing::ResourceInteraction`
|
|
117
|
+
|
|
118
|
+
Outcome-assertion helpers for `Plutonium::Interaction::Base` subclasses.
|
|
119
|
+
|
|
120
|
+
**Helpers:**
|
|
121
|
+
- `assert_interaction_success(klass, **input)` → returns the success outcome
|
|
122
|
+
- `assert_interaction_failure(klass, **input)` → returns the failure outcome
|
|
123
|
+
- `interaction_view_context` (overridable) → defaults to a mock view context
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
test "RebuildSearchInteraction succeeds" do
|
|
127
|
+
outcome = assert_interaction_success(RebuildSearchInteraction, since: 1.day.ago)
|
|
128
|
+
assert_equal 42, outcome.value[:rebuilt_count]
|
|
129
|
+
end
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### `Plutonium::Testing::ResourceModel`
|
|
133
|
+
|
|
134
|
+
Tests `associated_with` scope, SGID routing, and `has_cents` accessors — gated by DSL flags.
|
|
135
|
+
|
|
136
|
+
**Stubs:**
|
|
137
|
+
- `model_test_record` → persisted record
|
|
138
|
+
|
|
139
|
+
```ruby
|
|
140
|
+
resource_tests_for Catalog::Product, portal: :admin,
|
|
141
|
+
associated_with: :organization,
|
|
142
|
+
sgid_routing: true,
|
|
143
|
+
has_cents: %i[price]
|
|
144
|
+
|
|
145
|
+
def model_test_record = create_product!(user: @user, organization: @org)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Only the flagged features generate tests.
|
|
149
|
+
|
|
150
|
+
### `Plutonium::Testing::NestedResource`
|
|
151
|
+
|
|
152
|
+
Asserts CRUD under a parent + scope-boundary tests (sibling tenants invisible).
|
|
153
|
+
|
|
154
|
+
**Stubs:**
|
|
155
|
+
- `parent_record!` → current tenant
|
|
156
|
+
- `other_parent_record!` → sibling tenant
|
|
157
|
+
- `create_resource!(parent:)` → persisted record under given parent
|
|
158
|
+
|
|
159
|
+
### `Plutonium::Testing::PortalAccess`
|
|
160
|
+
|
|
161
|
+
Cross-portal access boundaries. Uses its own DSL — not `resource_tests_for`.
|
|
162
|
+
|
|
163
|
+
```ruby
|
|
164
|
+
class PortalAccessTest < ActionDispatch::IntegrationTest
|
|
165
|
+
include IntegrationTestHelper
|
|
166
|
+
include Plutonium::Testing::PortalAccess
|
|
167
|
+
|
|
168
|
+
portal_access_for portals: %i[admin org],
|
|
169
|
+
matrix: {admin: %i[admin], member: %i[org]}
|
|
170
|
+
|
|
171
|
+
setup do
|
|
172
|
+
@admin = create_admin!
|
|
173
|
+
@user = create_user!
|
|
174
|
+
@org = create_organization!
|
|
175
|
+
create_membership!(organization: @org, user: @user)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def login_as_role(role)
|
|
179
|
+
case role
|
|
180
|
+
when :admin then login_as(@admin, portal: :admin)
|
|
181
|
+
when :member then login_as(@user, portal: :user)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def portal_root_path(portal)
|
|
186
|
+
case portal
|
|
187
|
+
when :admin then "/admin"
|
|
188
|
+
when :org then "/org/#{@org.id}"
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Generates one test per (role × portal). Allowed = `200|302`; blocked = `302|401|403|404`.
|
|
195
|
+
|
|
196
|
+
## Auth helpers
|
|
197
|
+
|
|
198
|
+
`Plutonium::Testing::AuthHelpers` is included transitively by every concern.
|
|
199
|
+
|
|
200
|
+
```ruby
|
|
201
|
+
login_as(account) # uses portal from DSL
|
|
202
|
+
login_as(account, portal: :admin) # explicit override
|
|
203
|
+
sign_out # uses portal from DSL
|
|
204
|
+
sign_out(portal: :admin)
|
|
205
|
+
current_account # uses portal from DSL
|
|
206
|
+
current_account(portal: :admin)
|
|
207
|
+
with_portal(:org) { ... } # scoped portal switch
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Override hook for non-Rodauth apps:** define `sign_in_for_tests(account, portal:)` in your test class (or in `test/support/plutonium_testing.rb` for project-wide use). `AuthHelpers` will defer to it.
|
|
211
|
+
|
|
212
|
+
```ruby
|
|
213
|
+
def sign_in_for_tests(account, portal:)
|
|
214
|
+
# your custom auth flow here
|
|
215
|
+
end
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Generator reference
|
|
219
|
+
|
|
220
|
+
### `pu:test:install`
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
rails g pu:test:install
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
- Adds `require "plutonium/testing"` to `test/test_helper.rb` (idempotent)
|
|
227
|
+
- Creates `test/support/plutonium_testing.rb` with override stub
|
|
228
|
+
|
|
229
|
+
### `pu:test:scaffold`
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
rails g pu:test:scaffold Blogging::Post --portals=admin,org
|
|
233
|
+
rails g pu:test:scaffold Blogging::Post --portals=admin --concerns=crud,policy,definition
|
|
234
|
+
rails g pu:test:scaffold Blogging::Post --portals=org --parent=organization --dest=blogging
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
| Flag | Default | Purpose |
|
|
238
|
+
|---|---|---|
|
|
239
|
+
| `--portals=admin,org` | required | Emit one file per portal |
|
|
240
|
+
| `--concerns=...` | `crud,policy,definition` | Concerns to include (`crud,policy,definition,nested,model,interaction,portal_access`) |
|
|
241
|
+
| `--parent=organization` | none | Wires `NestedResource` parent |
|
|
242
|
+
| `--dest=main_app\|<package>` | `main_app` | Output destination |
|
|
243
|
+
|
|
244
|
+
Output path: `test/integration/<portal>_portal/<resource_underscored>_test.rb`.
|
|
245
|
+
|
|
246
|
+
## Customization & escape hatches
|
|
247
|
+
|
|
248
|
+
- **Skip individual tests:** `resource_tests_for Klass, portal: :admin, skip: %i[destroy]`
|
|
249
|
+
- **Restrict action set:** `resource_tests_for Klass, portal: :admin, actions: %i[index show]`
|
|
250
|
+
- **Custom assertions:** add regular `test "..."` blocks alongside the generated matrix — they coexist.
|
|
251
|
+
- **Non-Rodauth auth:** override `sign_in_for_tests`. See AuthHelpers section.
|
|
252
|
+
- **Custom path prefix:** `path_prefix: "/v2/admin"` overrides portal resolution.
|
|
253
|
+
|
|
254
|
+
## Common pitfalls
|
|
255
|
+
|
|
256
|
+
- **Forgotten stubs raise `NotImplementedError`** with the stub name. Look for the missing method in your test class.
|
|
257
|
+
- **Portal mismatch:** `:admin` portal expects `AdminPortal::Engine` constant. If your portal is named differently, pass `path_prefix:` explicitly.
|
|
258
|
+
- **Tenant leakage in stubs:** `create_resource!` for an org portal must return a record bound to the test's `@org`. Otherwise scope filtering tests will pass for the wrong reason.
|
|
259
|
+
- **`policy_record` for tenant-scoped resources** must belong to a tenant the role has access to — otherwise even allowed roles will see `false`.
|
|
260
|
+
- **Nested resources need `parent: :foo`** in the DSL AND a real parent record from `parent_record!`. Without both, path interpolation fails.
|
|
261
|
+
- **`PortalAccess` doesn't use `resource_tests_for`** — use `portal_access_for` instead. Mixing them on the same class is undefined behavior.
|
|
262
|
+
|
|
263
|
+
## See also
|
|
264
|
+
|
|
265
|
+
- `plutonium-policy` — write the policy this concern verifies
|
|
266
|
+
- `plutonium-definition` — definition props the smoke test introspects
|
|
267
|
+
- `plutonium-portal` — portal mounting and entity strategies that drive auth/scoping
|
|
268
|
+
- `plutonium-auth` — Rodauth setup behind the default login flow
|
data/.yarnrc.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
nodeLinker: node-modules
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
## [0.48.0] - 2026-04-16
|
|
2
|
+
|
|
3
|
+
### 🚀 Features
|
|
4
|
+
|
|
5
|
+
- *(turbo)* Preserve scroll by emitting refresh when redirect target matches referer
|
|
6
|
+
|
|
7
|
+
### 🐛 Bug Fixes
|
|
8
|
+
|
|
9
|
+
- *(action)* Respect `confirmation: false` on interactive actions
|
|
10
|
+
|
|
11
|
+
### 🧪 Testing
|
|
12
|
+
|
|
13
|
+
- *(system)* Browser coverage for Turbo refresh + scroll preservation
|
|
14
|
+
## [0.47.0] - 2026-04-15
|
|
15
|
+
|
|
16
|
+
### 🚀 Features
|
|
17
|
+
|
|
18
|
+
- *(core)* Add `interaction:` kwarg to resource_url_for
|
|
19
|
+
- *(testing)* Add Plutonium::Testing module, generators, skill, docs, and migrate in-repo tests
|
|
20
|
+
|
|
21
|
+
### ⚙️ Miscellaneous Tasks
|
|
22
|
+
|
|
23
|
+
- Update yarn
|
|
1
24
|
## [0.46.0] - 2026-04-11
|
|
2
25
|
|
|
3
26
|
### 🚀 Features
|
data/Rakefile
CHANGED
|
@@ -17,7 +17,16 @@ Rake::Task["build"].enhance ["assets"]
|
|
|
17
17
|
# Unit + integration tests (safe to run together)
|
|
18
18
|
Rake::TestTask.new(:test) do |t|
|
|
19
19
|
t.libs << "test"
|
|
20
|
-
t.test_files = FileList["test/**/*_test.rb"]
|
|
20
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
|
21
|
+
.exclude("test/generators/**/*_test.rb")
|
|
22
|
+
.exclude("test/system/**/*_test.rb")
|
|
23
|
+
t.verbose = true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# System tests — require a browser (headless Chrome) and run real Turbo/JS.
|
|
27
|
+
Rake::TestTask.new("test:system") do |t|
|
|
28
|
+
t.libs << "test"
|
|
29
|
+
t.test_files = FileList["test/system/**/*_test.rb"]
|
|
21
30
|
t.verbose = true
|
|
22
31
|
end
|
|
23
32
|
|