Merge branch 'main' into card-steps
* main: (22 commits) Fix that stage should be visible above card background Indicate opens menu Hide dialog targets from screen readers when closed Mark up as heading for screen reader navigation Copy for screen readers Don't hide the input so it's accessible to screen readers Point skip links to correct anchor, don't navigate with turbo There aren't any `li` children so just use `div` Use headings for screen reader navigation Use `h3` for individual cards in collection view Make collection title `h1` for screen reader navigation Esc should not propagate when closing dialogs squash! Remove session controller actions other than delete Screen reader: Use heading for comments navigation Remove the invitation codes for now Remove session controller actions other than delete Correct label for field Style Screen reader: De-duplicate links for each person in account settings Account.signal_account is no longer optional ...
This commit is contained in:
@@ -85,7 +85,7 @@
|
||||
|
||||
.card__background {
|
||||
.card:has(& img:not([src=""])) {
|
||||
.card__body,
|
||||
.card__content,
|
||||
.card__meta,
|
||||
.workflow-stage:not(.workflow-stage--current) {
|
||||
opacity: 0;
|
||||
|
||||
@@ -37,8 +37,14 @@
|
||||
}
|
||||
|
||||
.comment__author {
|
||||
.comment--system & strong {
|
||||
display: none;
|
||||
.comment--system & {
|
||||
h3 {
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
strong {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
}
|
||||
|
||||
.input--file {
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
display: grid;
|
||||
inline-size: auto;
|
||||
@@ -52,6 +51,7 @@
|
||||
}
|
||||
|
||||
input[type="file"] {
|
||||
--hover-size: 0;
|
||||
--input-border-color: transparent;
|
||||
--input-border-radius: 8px;
|
||||
|
||||
@@ -69,9 +69,9 @@
|
||||
|
||||
&:focus,
|
||||
&:focus-visible {
|
||||
--input-border-color: var(--color-selected-dark);
|
||||
--input-border-radius: 8px;
|
||||
--input-border-size: 0.15rem;
|
||||
.input--file:has(&) {
|
||||
outline: 0.15rem solid var(--color-selected-dark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,11 +48,7 @@ module Authentication
|
||||
def request_authentication
|
||||
session[:return_to_after_authenticating] = request.url
|
||||
|
||||
if Rails.application.config.x.local_authentication
|
||||
redirect_to new_session_path
|
||||
else
|
||||
redirect_to Launchpad.login_url(account: Current.account), allow_other_host: true
|
||||
end
|
||||
redirect_to Launchpad.login_url(account: Current.account), allow_other_host: true
|
||||
end
|
||||
|
||||
def after_authentication_url
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
class Sessions::LaunchpadController < ApplicationController
|
||||
require_unauthenticated_access
|
||||
|
||||
before_action :store_sig, only: :show
|
||||
before_action :restore_and_clear_sig, only: :update
|
||||
before_action :require_sig
|
||||
|
||||
def show
|
||||
end
|
||||
@@ -17,11 +16,7 @@ class Sessions::LaunchpadController < ApplicationController
|
||||
end
|
||||
|
||||
private
|
||||
def store_sig
|
||||
cookies[:_fizzy_launchpad_sig] = params.expect(:sig)
|
||||
end
|
||||
|
||||
def restore_and_clear_sig
|
||||
@sig = cookies.delete :_fizzy_launchpad_sig
|
||||
def require_sig
|
||||
@sig = params.expect(:sig)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,28 +1,6 @@
|
||||
class SessionsController < ApplicationController
|
||||
require_unauthenticated_access only: %i[ new create ]
|
||||
rate_limit to: 10, within: 3.minutes, only: :create, with: -> { redirect_to new_session_path, alert: "Try again later." }
|
||||
|
||||
before_action :require_first_run_completion
|
||||
|
||||
def new
|
||||
end
|
||||
|
||||
def create
|
||||
if user = User.active.authenticate_by(params.permit(:email_address, :password))
|
||||
start_new_session_for user
|
||||
redirect_to after_authentication_url
|
||||
else
|
||||
redirect_to new_session_path, alert: "Try another email address or password."
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
terminate_session
|
||||
redirect_to new_session_path
|
||||
redirect_to Launchpad.login_url, allow_other_host: true
|
||||
end
|
||||
|
||||
private
|
||||
def require_first_run_completion
|
||||
redirect_to first_run_path if Account.none?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
class Signup::BaseController < ApplicationController
|
||||
require_untenanted_access
|
||||
before_action :redirect_if_local_auth
|
||||
|
||||
# TODO: Remove this auth before launch.
|
||||
http_basic_authenticate_with(
|
||||
@@ -34,8 +33,4 @@ class Signup::BaseController < ApplicationController
|
||||
redirect_to account.signal_account.owner.remote_login_url(proceed_to: root_path),
|
||||
allow_other_host: true
|
||||
end
|
||||
|
||||
def redirect_if_local_auth
|
||||
render plain: "Unauthorized", status: :unauthorized if Rails.application.config.x.local_authentication
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,7 +37,7 @@ module EventsHelper
|
||||
|
||||
def event_cluster_tag(hour, col, &)
|
||||
row = 25 - hour
|
||||
tag.ul class: "events__time-block", style: "grid-area: #{row}/#{col}", &
|
||||
tag.div class: "events__time-block", style: "grid-area: #{row}/#{col}", &
|
||||
end
|
||||
|
||||
def event_next_page_link(next_day)
|
||||
|
||||
@@ -6,6 +6,10 @@ export default class extends Controller {
|
||||
modal: { type: Boolean, default: false }
|
||||
}
|
||||
|
||||
connect() {
|
||||
this.dialogTarget.setAttribute('aria-hidden', 'true')
|
||||
}
|
||||
|
||||
open() {
|
||||
const modal = this.modalValue
|
||||
|
||||
@@ -14,6 +18,7 @@ export default class extends Controller {
|
||||
} else {
|
||||
this.dialogTarget.show()
|
||||
}
|
||||
this.dialogTarget.setAttribute('aria-hidden', 'false')
|
||||
}
|
||||
|
||||
toggle() {
|
||||
@@ -26,6 +31,7 @@ export default class extends Controller {
|
||||
|
||||
close() {
|
||||
this.dialogTarget.close()
|
||||
this.dialogTarget.setAttribute('aria-hidden', 'true')
|
||||
this.dialogTarget.blur()
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,7 @@ module Account::SignalAccount
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
unless Rails.application.config.x.local_authentication
|
||||
# TODO: remove the "optional: true" once we've populated the accounts properly
|
||||
belongs_to :signal_account, class_name: "SignalId::Account", primary_key: :queenbee_id, foreign_key: :queenbee_id, optional: true
|
||||
end
|
||||
belongs_to :signal_account, class_name: "SignalId::Account", primary_key: :queenbee_id, foreign_key: :queenbee_id
|
||||
end
|
||||
|
||||
class_methods do
|
||||
|
||||
@@ -2,8 +2,6 @@ module User::SignalUser
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
unless Rails.application.config.x.local_authentication
|
||||
belongs_to :signal_user, dependent: :destroy, class_name: "SignalId::User", optional: true
|
||||
end
|
||||
belongs_to :signal_user, dependent: :destroy, class_name: "SignalId::User", optional: true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<li class="flex align-center gap-half pad-inline" data-filter-target="item">
|
||||
<%= avatar_tag user %>
|
||||
<%= avatar_tag user, hidden_for_screen_reader: true %>
|
||||
|
||||
<strong class="overflow-ellipsis">
|
||||
<%= link_to user.name, user, class: "txt-ink btn btn--plain" %>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="panel shadow center flex flex-column">
|
||||
<strong class="divider txt-large margin-block-end">People on the account</strong>
|
||||
<%= render "accounts/invite" %>
|
||||
<%#= render "accounts/invite" # Scheduled work in https://3.basecamp.com/2914079/buckets/37331921/todos/8746162337 %>
|
||||
|
||||
<div class="flex flex-column" data-controller="filter">
|
||||
<div class="pad">
|
||||
|
||||
@@ -8,14 +8,16 @@
|
||||
|
||||
<div class="comment__content flex flex-column flex-item-grow full-width">
|
||||
<div class="comment__author flex align-center gap-half">
|
||||
<strong>
|
||||
<%= link_to comment.creator.name, comment.creator, class: "txt-ink btn btn--plain fill-transparent", data: { turbo_frame: "_top" } %>
|
||||
</strong>
|
||||
<h3 class="font-weight-normal txt-normal flex-item-justify-start">
|
||||
<strong>
|
||||
<%= link_to comment.creator.name, comment.creator, class: "txt-ink btn btn--plain fill-transparent", data: { turbo_frame: "_top" } %>
|
||||
</strong>
|
||||
|
||||
<%= link_to comment, class: "txt-undecorated txt-ink translucent txt-normal txt-capitalize flex-item-justify-start" do %>
|
||||
<%= local_datetime_tag comment.created_at, style: :agoorweekday %>,
|
||||
<%= local_datetime_tag comment.created_at, style: :time %>
|
||||
<% end %>
|
||||
<%= link_to comment, class: "txt-undecorated txt-ink translucent txt-normal txt-capitalize" do %>
|
||||
<%= local_datetime_tag comment.created_at, style: :agoorweekday %>,
|
||||
<%= local_datetime_tag comment.created_at, style: :time %>
|
||||
<% end %>
|
||||
</h3>
|
||||
|
||||
<%= link_to edit_card_comment_path(comment.card, comment),
|
||||
class: "comment__edit btn btn--circle borderless fill-transparent translucent" do %>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="quick-reaction" data-controller="dialog" data-action="keydown.esc->dialog#close click@document->dialog#closeOnClickOutside">
|
||||
<div class="quick-reaction" data-controller="dialog" data-action="keydown.esc->dialog#close:stop click@document->dialog#closeOnClickOutside">
|
||||
<%= yield %>
|
||||
|
||||
<dialog class="quick-reaction__popup popup panel fill-white shadow" data-dialog-target="dialog">
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
<details class="expander" data-controller="details" data-details-target="details" data-action="keydown.esc->details#close click@document->details#closeOnClickOutside">
|
||||
<details class="expander" data-controller="details" data-details-target="details" data-action="keydown.esc->details#close:stop click@document->details#closeOnClickOutside">
|
||||
<summary class="expander__button btn borderless">
|
||||
Close as
|
||||
<%= icon_tag "caret-down" %>
|
||||
|
||||
@@ -5,13 +5,12 @@
|
||||
<% end %>
|
||||
<% elsif !card.closed? %>
|
||||
<%= form_with model: card, url: collection_card_path(card.collection, card), data: { controller: "form" } do |form| %>
|
||||
<label class="btn">
|
||||
<label class="btn input--file">
|
||||
<%= icon_tag "picture-add" %>
|
||||
<span class="for-screen-reader">Add background image</span>
|
||||
<%= form.file_field :image, class: "input",
|
||||
accept: "image/png, image/jpeg, image/jpg, image/webp",
|
||||
data: { action: "upload-preview#previewImage form#submit", upload_preview_target: "input" },
|
||||
hidden: true %>
|
||||
data: { action: "upload-preview#previewImage form#submit", upload_preview_target: "input" } %>
|
||||
</label>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
|
||||
<div class="card__body justify-space-between">
|
||||
<div class="card__content">
|
||||
<h1 class="card__title overflow-line-clamp">
|
||||
<h3 class="card__title overflow-line-clamp">
|
||||
<%= card.title %>
|
||||
</h1>
|
||||
</h3>
|
||||
|
||||
<%= link_to collection_card_path(card.collection, card), draggable: false, class: "card__link", title: card_title_tag(card), data: { action: "dialog#close", turbo_frame: "_top" } do %>
|
||||
<span class="for-screen-reader"><%= card.title %></span>
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
<% end %>
|
||||
|
||||
<header class="margin-block-end">
|
||||
<span class="txt-large overflow-ellipsis margin-none font-black" style="view-transistion-name: card-collection-title">
|
||||
<h1 class="txt-large overflow-ellipsis margin-none font-black" style="view-transistion-name: card-collection-title">
|
||||
<span><%= filter_title @filter %></span>
|
||||
</span>
|
||||
</h1>
|
||||
<%= render "filters/settings", filter: @filter %>
|
||||
</header>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
terminal_target: "form",
|
||||
action: "turbo:submit-start->terminal#commandSubmitted turbo:submit-end->terminal#focus keydown.meta+k@document->terminal#focus:prevent keydown.ctrl+k@document->terminal#focus:prevent keydown.enter->terminal#executeCommand keydown.esc->terminal#hideMenus turbo:submit-end->terminal#handleCommandResponse"
|
||||
} do %>
|
||||
<label class="terminal__label txt-nowrap" for="fizzy_do">Fizzy do ></label>
|
||||
<label class="terminal__label txt-nowrap" for="command">Fizzy do ></label>
|
||||
|
||||
<%= text_field_tag "command", nil,
|
||||
autocomplete: "off",
|
||||
@@ -20,5 +20,5 @@
|
||||
placeholder: platform.desktop? ? "Press #{ hotkey_label(["ctrl", "K"]) } to search or type commands…" : "Search or type commands…",
|
||||
spellcheck: "false" %>
|
||||
|
||||
<%= hidden_field_tag "confirmed", nil, data: { terminal_target: "confirmation" } %>
|
||||
<%= hidden_field_tag "confirmed", nil, data: { terminal_target: "confirmation" } %>
|
||||
<% end %>
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
related_element_group_value: card.id,
|
||||
action: "mouseover->related-element#highlight mouseout->related-element#unhighlight" } do %>
|
||||
<div class="card__header flex align-start gap full-width">
|
||||
<div class="card__collection flex-inline align-start">
|
||||
<h4 class="card__collection flex-inline align-start">
|
||||
<span class="card__id"><%= card.id %></span>
|
||||
<span class="card__collection-name">
|
||||
<span class="overflow-ellipsis"><%= event.collection.name %></span>
|
||||
</span>
|
||||
</div>
|
||||
</h4>
|
||||
|
||||
<% if event_column(event) == 2 %>
|
||||
<span class="event__icon flex-item-justify-end txt-reversed">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<body data-controller="lightbox local-time timezone-cookie" data-action="turbo:morph@window->local-time#refreshAll">
|
||||
<header id="header">
|
||||
<a href="#main-content" class="skip-navigation btn">Skip to main content</a>
|
||||
<a href="#main" class="skip-navigation btn" data-turbo="false">Skip to main content</a>
|
||||
<%= yield :header %>
|
||||
</header>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<body class="public" data-controller="local-time timezone-cookie" data-action="turbo:morph@window->local-time#refreshAll">
|
||||
<header id="header">
|
||||
<a href="#main-content" class="skip-navigation btn">Skip to main content</a>
|
||||
<a href="#main" class="skip-navigation btn" data-turbo="false">Skip to main content</a>
|
||||
<%= yield :header %>
|
||||
</header>
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button class="tray__expander" data-action="dialog#toggle" aria-label="Expand pins stack">
|
||||
<button class="tray__expander" data-action="dialog#toggle" aria-label="Expand pins stack" aria-haspopup="true">
|
||||
<%= icon_tag "pinned" %>
|
||||
</button>
|
||||
</section>
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
<%= avatar_image_tag notification.creator %>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-column min-width flex-item-grow">
|
||||
<h3 class="flex flex-column min-width flex-item-grow font-weight-normal">
|
||||
<%= render "notifications/notification/#{notification.source_type.underscore}/body", notification: notification %>
|
||||
</div>
|
||||
</h3>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<div class="tray__actions">
|
||||
<%= button_to read_all_notifications_path,
|
||||
class: "tray__notification-read-action btn btn--reversed fill-transparent borderless flex-item-justify-start txt-xx-small",
|
||||
title: "Mark all as read",
|
||||
title: "Mark all notifications as read",
|
||||
data: { action: "click->dialog#close", turbo_frame: "notifications" } do %>
|
||||
<%= icon_tag "check" %>
|
||||
<% end %>
|
||||
@@ -34,7 +34,7 @@
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<button class="tray__expander" data-action="dialog#toggle" aria-label="Expand notifications stack">
|
||||
<button class="tray__expander" data-action="dialog#toggle" aria-label="Expand notifications stack" aria-haspopup="true">
|
||||
<%= icon_tag "bell" %>
|
||||
</button>
|
||||
</section>
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
<%= auto_submit_form_with method: :put %>
|
||||
<%= auto_submit_form_with(method: :put) do |form| %>
|
||||
<%= form.hidden_field(:sig, value: @sig) %>
|
||||
<% end %>
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
<% @page_title = "Sign in" %>
|
||||
|
||||
<div class="panel shadow center margin-block-double <%= "shake" if flash[:alert] %>" style="--panel-size: 55ch;">
|
||||
<h1 class="txt-xx-large margin-block-end-double">Fizzy</h1>
|
||||
|
||||
<%= form_with url: session_path, class: "flex flex-column gap txt-large" do |form| %>
|
||||
<div class="flex align-center gap">
|
||||
<label class="flex align-center gap input input--actor">
|
||||
<%= form.email_field :email_address, required: true, class: "input full-width", autofocus: true, autocomplete: "username", placeholder: "Enter your email address" %>
|
||||
<%= icon_tag "email", class: "txt-large" %>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="flex align-center gap">
|
||||
<label class="flex align-center gap input input--actor">
|
||||
<%= form.password_field :password, required: true, class: "input full-width", autocomplete: "current-password", placeholder: "Enter your password", maxlength: 72 %>
|
||||
<%= icon_tag "password", class: "txt-large" %>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<button type="submit" id="log_in" class="btn btn--reversed center">
|
||||
<%= icon_tag "arrow-right" %>
|
||||
<span class="for-screen-reader">Sign in</span>
|
||||
</button>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% content_for :footer do %>
|
||||
<div class="txt-align-center center margin-block-double txt-subtle">Fizzy™ version 0</div>
|
||||
<% end %>
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<% content_for :header do %>
|
||||
<nav>
|
||||
<%= link_to new_session_path, class: "btn flex-item-justify-end", data: { controller: "hotkey", action: "keydown.esc@document->hotkey#click" } do %>
|
||||
<%= link_to Launchpad.login_url(account: Current.account), class: "btn flex-item-justify-end", data: { controller: "hotkey", action: "keydown.esc@document->hotkey#click" } do %>
|
||||
<span class="for-screen-reader">Sign in instead</span>
|
||||
<% end %>
|
||||
</nav>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
</div>
|
||||
|
||||
<div class="panel borderless center margin-block-double">
|
||||
<%= button_to session_path, method: :delete, class: "btn center txt-medium" do %>
|
||||
<%= button_to session_path, method: :delete, class: "btn center txt-medium", data: { turbo: false } do %>
|
||||
<%= icon_tag "logout" %>
|
||||
<span>Sign out</span>
|
||||
<% end %>
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
require "signal_id"
|
||||
|
||||
Rails.application.config.x.local_authentication = ENV["LOCAL_AUTHENTICATION"].present?
|
||||
|
||||
ENV["SIGNAL_ID_SECRET"] = Rails.application.credentials.signal_id_secret
|
||||
|
||||
Rails.application.config.to_prepare do
|
||||
SignalId.product = "fizzy"
|
||||
|
||||
db_config = SignalId::Database.default_configuration
|
||||
if Rails.application.config.x.local_authentication
|
||||
db_config.each do |name, config|
|
||||
config["connect_timeout"] = 1
|
||||
end
|
||||
end
|
||||
SignalId::Database.load_configuration db_config
|
||||
SignalId::Database.enable_rw_splitting!
|
||||
|
||||
|
||||
+2
-2
@@ -85,11 +85,11 @@ Rails.application.routes.draw do
|
||||
get "join/:join_code", to: "users#new", as: :join
|
||||
post "join/:join_code", to: "users#create"
|
||||
|
||||
resource :session do
|
||||
resource :session, only: :destroy do
|
||||
scope module: "sessions" do
|
||||
resources :transfers, only: %i[ show update ]
|
||||
resource :launchpad, only: %i[ show update ], controller: "launchpad"
|
||||
end
|
||||
resource :launchpad, only: %i[ show update ], controller: "sessions/launchpad"
|
||||
end
|
||||
|
||||
namespace :signup do
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class RemovePasswordFromUsers < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
remove_column :users, :password, :string
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddNotNullToAccountsQueenbeeId < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
change_column_null :accounts, :queenbee_id, false
|
||||
end
|
||||
end
|
||||
Generated
+2
-2
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.1].define(version: 2025_06_25_120000) do
|
||||
ActiveRecord::Schema[8.1].define(version: 2025_07_02_160230) do
|
||||
create_table "accesses", force: :cascade do |t|
|
||||
t.datetime "accessed_at"
|
||||
t.integer "collection_id", null: false
|
||||
@@ -28,7 +28,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_06_25_120000) do
|
||||
t.datetime "created_at", null: false
|
||||
t.string "join_code"
|
||||
t.string "name", null: false
|
||||
t.integer "queenbee_id"
|
||||
t.integer "queenbee_id", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["queenbee_id"], name: "index_accounts_on_queenbee_id", unique: true
|
||||
end
|
||||
|
||||
+2
-2
@@ -128,7 +128,7 @@ columns:
|
||||
name: queenbee_id
|
||||
cast_type: *3
|
||||
sql_type_metadata: *4
|
||||
'null': true
|
||||
'null': false
|
||||
default:
|
||||
default_function:
|
||||
collation:
|
||||
@@ -2451,4 +2451,4 @@ indexes:
|
||||
comment:
|
||||
valid: true
|
||||
workflows: []
|
||||
version: 20250625120000
|
||||
version: 20250702160230
|
||||
|
||||
@@ -11,7 +11,7 @@ class EventsControllerTest < ActionDispatch::IntegrationTest
|
||||
test "index" do
|
||||
get events_path
|
||||
|
||||
assert_select "ul.events__time-block[style='grid-area: 17/2']" do
|
||||
assert_select "div.events__time-block[style='grid-area: 17/2']" do
|
||||
assert_select "strong", text: "David assigned JZ to Layout is broken"
|
||||
end
|
||||
end
|
||||
@@ -21,7 +21,7 @@ class EventsControllerTest < ActionDispatch::IntegrationTest
|
||||
|
||||
get events_path
|
||||
|
||||
assert_select "ul.events__time-block[style='grid-area: 22/2']" do
|
||||
assert_select "div.events__time-block[style='grid-area: 22/2']" do
|
||||
assert_select "strong", text: "David assigned JZ to Layout is broken"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,14 +6,16 @@ class Sessions::LaunchpadControllerTest < ActionDispatch::IntegrationTest
|
||||
|
||||
assert_response :success
|
||||
|
||||
assert_equal cookies[:_fizzy_launchpad_sig], "test-sig"
|
||||
assert_select "form input#sig" do |node|
|
||||
assert_equal node.length, 1
|
||||
assert_equal node.first["value"], "test-sig"
|
||||
end
|
||||
end
|
||||
|
||||
test "create establishes a session when the sig is valid" do
|
||||
user = users(:david)
|
||||
cookies[:_fizzy_launchpad_sig] = user.signal_user.perishable_signature
|
||||
|
||||
put session_launchpad_path
|
||||
put session_launchpad_path(params: { sig: user.signal_user.perishable_signature })
|
||||
|
||||
assert_redirected_to root_url
|
||||
assert parsed_cookies.signed[:session_token]
|
||||
@@ -21,9 +23,8 @@ class Sessions::LaunchpadControllerTest < ActionDispatch::IntegrationTest
|
||||
|
||||
test "returns 401 when the sig is invalid" do
|
||||
user = users(:david)
|
||||
cookies[:sig] = "not-valid"
|
||||
|
||||
put session_launchpad_path
|
||||
put session_launchpad_path(params: { sig: "invalid" })
|
||||
|
||||
assert_response :unauthorized
|
||||
end
|
||||
|
||||
@@ -1,38 +1,10 @@
|
||||
require "test_helper"
|
||||
|
||||
class SessionsControllerTest < ActionDispatch::IntegrationTest
|
||||
ALLOWED_BROWSER = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15"
|
||||
DISALLOWED_BROWSER = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0"
|
||||
|
||||
test "new" do
|
||||
get new_session_path
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "new enforces browser compatibility" do
|
||||
get new_session_path, env: { "HTTP_USER_AGENT" => DISALLOWED_BROWSER }
|
||||
assert_select "svg", message: /Your browser is not supported/
|
||||
|
||||
get new_session_path, env: { "HTTP_USER_AGENT" => ALLOWED_BROWSER }
|
||||
assert_select "svg", text: /Your browser is not supported/, count: 0
|
||||
end
|
||||
|
||||
test "create with valid credentials" do
|
||||
post session_path, params: { email_address: "david@37signals.com", password: "secret123456" }
|
||||
assert_redirected_to root_path
|
||||
assert cookies[:session_token].present?
|
||||
end
|
||||
|
||||
test "create with invalid credentials" do
|
||||
post session_path, params: { email_address: "david@37signals.com", password: "wrong" }
|
||||
assert_redirected_to new_session_path
|
||||
assert_not cookies[:session_token].present?
|
||||
end
|
||||
|
||||
test "destroy" do
|
||||
sign_in_as :kevin
|
||||
delete session_path
|
||||
assert_redirected_to new_session_path
|
||||
assert_redirected_to Launchpad.login_url
|
||||
assert_not cookies[:session_token].present?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,7 +6,7 @@ module SessionTestHelper
|
||||
def sign_in_as(user)
|
||||
cookies[:session_token] = nil
|
||||
user = users(user) unless user.is_a? User
|
||||
post session_path, params: { email_address: user.email_address, password: "secret123456" }
|
||||
put session_launchpad_path, params: { sig: user.signal_user.perishable_signature }
|
||||
assert cookies[:session_token].present?
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user