generated from block/oss-project-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Use Turbo Streams for token create/destroy and add system tests #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| <h2>Create New Token</h2> | ||
| <%= form_with url: settings_tokens_path, method: :post, class: "form-inline" do |f| %> | ||
| <div class="form-group"> | ||
| <%= f.label :name, "Token Name" %> | ||
| <%= f.text_field :name, name: "api_token[name]", placeholder: "e.g. My Agent", required: true, class: "form-control" %> | ||
| </div> | ||
| <%= f.submit "Create Token", class: "btn btn--primary" %> | ||
| <% end %> |
7 changes: 7 additions & 0 deletions
7
engine/app/views/coplan/settings/tokens/_token_reveal.html.erb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| <div class="token-reveal"> | ||
| <h3>Your new API token</h3> | ||
| <p>Copy this token now. It will not be shown again.</p> | ||
| <div class="token-reveal__value"> | ||
| <code><%= raw_token %></code> | ||
| </div> | ||
| </div> |
24 changes: 24 additions & 0 deletions
24
engine/app/views/coplan/settings/tokens/_token_row.html.erb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| <tr id="<%= dom_id(token) %>" class="<%= 'data-table__row--muted' if token.revoked? %>"> | ||
| <td> | ||
| <strong><%= token.name %></strong> | ||
| <% if token.token_prefix.present? %> | ||
| <br><code><%= token.token_prefix %>…</code> | ||
| <% end %> | ||
| </td> | ||
| <td> | ||
| <% if token.revoked? %> | ||
| <span class="badge badge--danger">Revoked</span> | ||
| <% elsif token.expired? %> | ||
| <span class="badge badge--warning">Expired</span> | ||
| <% else %> | ||
| <span class="badge badge--success">Active</span> | ||
| <% end %> | ||
| </td> | ||
| <td><%= token.last_used_at ? time_ago_in_words(token.last_used_at) + " ago" : "Never" %></td> | ||
| <td><%= token.created_at.strftime("%b %d, %Y") %></td> | ||
| <td> | ||
| <% unless token.revoked? %> | ||
| <%= button_to "Revoke", settings_token_path(token), method: :delete, class: "btn btn--danger btn--sm" %> | ||
| <% end %> | ||
| </td> | ||
| </tr> |
11 changes: 11 additions & 0 deletions
11
engine/app/views/coplan/settings/tokens/create.turbo_stream.erb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| <%= turbo_stream.update "token-reveal" do %> | ||
| <%= render "token_reveal", raw_token: @raw_token %> | ||
| <% end %> | ||
|
|
||
| <%= turbo_stream.update "create-token-form" do %> | ||
| <%= render "form" %> | ||
| <% end %> | ||
|
|
||
| <%= turbo_stream.prepend "tokens-list" do %> | ||
| <%= render "token_row", token: @api_token %> | ||
| <% end %> | ||
5 changes: 5 additions & 0 deletions
5
engine/app/views/coplan/settings/tokens/destroy.turbo_stream.erb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| <%= turbo_stream.replace @token do %> | ||
| <%= render "token_row", token: @token %> | ||
| <% end %> | ||
|
|
||
| <%= turbo_stream.update "token-reveal", "" %> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| require "capybara/rspec" | ||
|
|
||
| RSpec.configure do |config| | ||
| config.before(:each, type: :system) do | ||
| driven_by :selenium_chrome_headless | ||
| end | ||
| end | ||
|
|
||
| Capybara.server = :puma, { Silent: true } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| require "rails_helper" | ||
|
|
||
| RSpec.describe "Token management", type: :system do | ||
| before do | ||
| visit sign_in_path | ||
| fill_in "Email address", with: "testuser@example.com" | ||
| click_button "Sign In" | ||
| expect(page).to have_content("Sign out") | ||
| end | ||
|
|
||
| it "creates a token and displays the raw value via Turbo Stream" do | ||
| visit settings_tokens_path | ||
|
|
||
| # Verify no token reveal is shown initially | ||
| expect(page).not_to have_css(".token-reveal") | ||
|
|
||
| fill_in "Token Name", with: "My Test Token" | ||
| click_button "Create Token" | ||
|
|
||
| # The token reveal should appear without a full page reload | ||
| expect(page).to have_css(".token-reveal") | ||
| expect(page).to have_content("Your new API token") | ||
| expect(page).to have_content("Copy this token now") | ||
|
|
||
| # The raw token value should be a 64-char hex string | ||
| token_code = find(".token-reveal__value code") | ||
| expect(token_code.text).to match(/\A[0-9a-f]{64}\z/) | ||
|
|
||
| # The new token should appear in the table | ||
| expect(page).to have_content("My Test Token") | ||
|
|
||
| # The form should be reset and ready for another token | ||
| expect(find_field("Token Name").value).to be_blank | ||
| end | ||
|
|
||
| it "creates a token when no tokens exist yet (empty state)" do | ||
| visit settings_tokens_path | ||
|
|
||
| # Table should be empty | ||
| expect(page).not_to have_css("#tokens-list tr") | ||
|
|
||
| fill_in "Token Name", with: "First Token" | ||
| click_button "Create Token" | ||
|
|
||
| # Token reveal and table row should both appear | ||
| expect(page).to have_css(".token-reveal") | ||
| expect(page).to have_content("First Token") | ||
| expect(page).to have_css("#tokens-list tr", count: 1) | ||
| end | ||
|
|
||
| it "revokes a token via Turbo Stream" do | ||
| user = CoPlan::User.find_by!(email: "testuser@example.com") | ||
| create(:api_token, user: user, name: "Revokable") | ||
|
|
||
| visit settings_tokens_path | ||
| expect(page).to have_content("Revokable") | ||
| expect(page).to have_css(".badge--success") | ||
|
|
||
| click_button "Revoke" | ||
|
|
||
| # Should update in-place to show revoked state | ||
| expect(page).to have_css(".badge--danger") | ||
| expect(page).not_to have_button("Revoke") | ||
|
|
||
| # Token name should still be visible (not removed from page) | ||
| expect(page).to have_content("Revokable") | ||
| end | ||
| end |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a user creates their first token, this stream prepends into
tokens-list, butindex.html.erbonly renders<tbody id="tokens-list">when@api_tokens.any?is true. In the empty-state path there is no target element, so Turbo ignores the prepend and the new token row does not appear until a full reload, which makes the create flow look broken for new users.Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed! Removed the empty-state conditional entirely — the table always renders (with an empty tbody). The turbo_stream prepend into
#tokens-listnow works regardless of whether it's the first token or not.Also added a dedicated system test for the empty-state flow to keep this covered.