mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-10 01:01:39 -05:00
Fix missing error messages on user registration and other forms
This commit is contained in:
parent
888e48ccf2
commit
2f160b8d97
7 changed files with 103 additions and 18 deletions
|
|
@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||
## Fixed
|
||||
|
||||
- Taiwan flag is now shown on its own instead of in combination with China flag.
|
||||
- On the registration page and other user forms, if something goes wrong, error messages are now shown to the user.
|
||||
|
||||
## Changed
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class Users::RegistrationsController < Devise::RegistrationsController
|
|||
end
|
||||
|
||||
def set_invitation
|
||||
return unless invitation_token.present?
|
||||
return if invitation_token.blank?
|
||||
|
||||
@invitation = Family::Invitation.find_by(token: invitation_token)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
</div>
|
||||
<div class="card flex-shrink-0 w-full max-w-sm shadow-2xl bg-base-100 px-5 py-5">
|
||||
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), class: 'form-body', method: :put, data: { turbo_method: :put, turbo: false }) do |f| %>
|
||||
<%= render "devise/shared/error_messages", resource: resource %>
|
||||
|
||||
<div class="form-control">
|
||||
<%= f.label :email, class: 'label' do %>
|
||||
<span class="label-text">Email</span>
|
||||
|
|
|
|||
|
|
@ -16,12 +16,23 @@
|
|||
</span>
|
||||
</div>
|
||||
<% else %>
|
||||
<h1 class="text-5xl font-bold text-base-content">Register now!</h1>
|
||||
<p class="py-6 text-base-content opacity-70">and take control over your location data.</p>
|
||||
<h1 class="text-5xl font-bold text-base-content">Almost there!</h1>
|
||||
<% end %>
|
||||
<p class="py-6 text-base-content opacity-70">
|
||||
Only a few steps left until you get control over your location data!
|
||||
</p>
|
||||
<ol>
|
||||
<li class="mb-2">1. Create your account</li>
|
||||
<li class="mb-2">2. Configure your mobile app</li>
|
||||
<li class="mb-2">3. Start tracking your location data securely</li>
|
||||
<li class="mb-2">4. ...</li>
|
||||
<li class="mb-2">5. You're beautiful!</li>
|
||||
</ol>
|
||||
|
||||
</div>
|
||||
<div class="card flex-shrink-0 w-full max-w-sm shadow-2xl bg-base-100 px-5 py-5">
|
||||
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), class: 'form-body', html: { data: { turbo: session[:dawarich_client] == 'ios' ? false : true } }) do |f| %>
|
||||
<%= render "devise/shared/error_messages", resource: resource %>
|
||||
<% if @invitation %>
|
||||
<%= f.hidden_field :invitation_token, value: params[:invitation_token] %>
|
||||
<% end %>
|
||||
|
|
@ -32,7 +43,7 @@
|
|||
<% end %>
|
||||
<%= f.email_field :email, autofocus: true, autocomplete: "email",
|
||||
readonly: @invitation.present?,
|
||||
class: "input input-bordered #{@invitation ? 'input-disabled' : ''}" %>
|
||||
class: "input input-bordered w-full #{@invitation ? 'input-disabled' : ''}" %>
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
|
|
@ -42,7 +53,7 @@
|
|||
<% if @minimum_password_length %>
|
||||
<em class="text-base-content opacity-60 text-sm">(<%= @minimum_password_length %> characters minimum)</em>
|
||||
<% end %><br />
|
||||
<%= f.password_field :password, autocomplete: "new-password", class: 'input input-bordered' %>
|
||||
<%= f.password_field :password, autocomplete: "new-password", class: 'input input-bordered w-full' %>
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
|
|
@ -52,7 +63,7 @@
|
|||
<% if @minimum_password_length %>
|
||||
<em class="text-base-content opacity-60 text-sm">(<%= @minimum_password_length %> characters minimum)</em>
|
||||
<% end %><br />
|
||||
<%= f.password_field :password_confirmation, autocomplete: "new-password", class: 'input input-bordered' %>
|
||||
<%= f.password_field :password_confirmation, autocomplete: "new-password", class: 'input input-bordered w-full' %>
|
||||
</div>
|
||||
|
||||
<% if !DawarichSettings.self_hosted? %>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
</div>
|
||||
<div class="card flex-shrink-0 w-full max-w-sm shadow-2xl bg-base-100 px-5 py-5">
|
||||
<%= form_for(resource, as: resource_name, url: session_path(resource_name), class: 'form-body', html: { data: { turbo: session[:dawarich_client] == 'ios' ? false : true } }) do |f| %>
|
||||
<%= render "devise/shared/error_messages", resource: resource %>
|
||||
|
||||
<% if @invitation %>
|
||||
<%= hidden_field_tag :invitation_token, params[:invitation_token] %>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,20 @@
|
|||
<% if resource.errors.any? %>
|
||||
<div id="error_explanation" data-turbo-cache="false">
|
||||
<h2>
|
||||
<%= I18n.t("errors.messages.not_saved",
|
||||
count: resource.errors.count,
|
||||
resource: resource.class.model_name.human.downcase)
|
||||
%>
|
||||
</h2>
|
||||
<ul>
|
||||
<% resource.errors.full_messages.each do |message| %>
|
||||
<li><%= message %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<div id="error_explanation" class="alert alert-error mb-4" data-turbo-cache="false">
|
||||
<%= icon 'circle-x' %>
|
||||
<div class="font-bold mb-4 flex items-center gap-2">
|
||||
<div>
|
||||
<h3 class="font-bold">
|
||||
<%= I18n.t("errors.messages.not_saved",
|
||||
count: resource.errors.count,
|
||||
resource: resource.class.model_name.human.downcase)
|
||||
%>
|
||||
</h3>
|
||||
<ul class="text-sm mt-1">
|
||||
<% resource.errors.full_messages.each do |message| %>
|
||||
<li><%= message %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -326,6 +326,70 @@ RSpec.describe 'Users::Registrations', type: :request do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'Validation Error Handling' do
|
||||
context 'when trying to register with an existing email' do
|
||||
let!(:existing_user) { create(:user, email: 'existing@example.com') }
|
||||
|
||||
it 'renders the registration form with error message' do
|
||||
post user_registration_path, params: {
|
||||
user: {
|
||||
email: existing_user.email,
|
||||
password: 'password123',
|
||||
password_confirmation: 'password123'
|
||||
}
|
||||
}
|
||||
|
||||
expect(response).to have_http_status(:unprocessable_content)
|
||||
expect(response.body).to include('Email has already been taken')
|
||||
expect(response.body).to include('error_explanation')
|
||||
end
|
||||
|
||||
it 'does not create a new user' do
|
||||
expect do
|
||||
post user_registration_path, params: {
|
||||
user: {
|
||||
email: existing_user.email,
|
||||
password: 'password123',
|
||||
password_confirmation: 'password123'
|
||||
}
|
||||
}
|
||||
end.not_to change(User, :count)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when password is too short' do
|
||||
it 'renders the registration form with error message' do
|
||||
post user_registration_path, params: {
|
||||
user: {
|
||||
email: 'newuser@example.com',
|
||||
password: 'short',
|
||||
password_confirmation: 'short'
|
||||
}
|
||||
}
|
||||
|
||||
expect(response).to have_http_status(:unprocessable_content)
|
||||
expect(response.body).to include('Password is too short')
|
||||
expect(response.body).to include('error_explanation')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when passwords do not match' do
|
||||
it 'renders the registration form with error message' do
|
||||
post user_registration_path, params: {
|
||||
user: {
|
||||
email: 'newuser@example.com',
|
||||
password: 'password123',
|
||||
password_confirmation: 'different123'
|
||||
}
|
||||
}
|
||||
|
||||
expect(response).to have_http_status(:unprocessable_content)
|
||||
expect(response.body).to include("Password confirmation doesn")
|
||||
expect(response.body).to include('error_explanation')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'UTM Parameter Tracking' do
|
||||
let(:utm_params) do
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue