Gli header Accept-Language dalle app e i fix di padding/menu sul web chiudono il giro password-policy; il doc guida il lavoro su Mac. Co-authored-by: Cursor <cursoragent@cursor.com>
128 lines
4.8 KiB
Ruby
128 lines
4.8 KiB
Ruby
require "rails_helper"
|
|
|
|
RSpec.describe "Account API", type: :request do
|
|
let!(:user) { User.create!(email: "account@example.com", name: "Account User", password: "Password123", role: "coach") }
|
|
let(:auth_headers) do
|
|
post "/api/v1/auth/login", params: { email: user.email, password: "Password123" }
|
|
token = JSON.parse(response.body).fetch("access_token")
|
|
{ "Authorization" => "Bearer #{token}" }
|
|
end
|
|
|
|
describe "GET /api/v1/account" do
|
|
it "returns the current user profile" do
|
|
get "/api/v1/account", headers: auth_headers
|
|
expect(response).to have_http_status(:ok)
|
|
body = JSON.parse(response.body)
|
|
expect(body).to include("email" => user.email, "name" => "Account User", "role" => "coach")
|
|
end
|
|
|
|
it "requires authentication" do
|
|
get "/api/v1/account"
|
|
expect(response).to have_http_status(:unauthorized)
|
|
end
|
|
end
|
|
|
|
describe "PATCH /api/v1/account" do
|
|
it "updates the name" do
|
|
patch "/api/v1/account", params: { name: "Nuovo Nome" }, headers: auth_headers
|
|
expect(response).to have_http_status(:ok)
|
|
expect(JSON.parse(response.body)["name"]).to eq("Nuovo Nome")
|
|
expect(user.reload.name).to eq("Nuovo Nome")
|
|
end
|
|
|
|
it "rejects a blank name" do
|
|
patch "/api/v1/account", params: { name: " " }, headers: auth_headers
|
|
expect(response).to have_http_status(:unprocessable_entity)
|
|
end
|
|
end
|
|
|
|
describe "PATCH /api/v1/account/password" do
|
|
it "changes the password with the current password" do
|
|
patch "/api/v1/account/password",
|
|
params: {
|
|
current_password: "Password123",
|
|
password: "NewPass123",
|
|
password_confirmation: "NewPass123"
|
|
},
|
|
headers: auth_headers
|
|
expect(response).to have_http_status(:ok)
|
|
expect(user.reload.authenticate("NewPass123")).to be_truthy
|
|
end
|
|
|
|
it "rejects an incorrect current password" do
|
|
patch "/api/v1/account/password",
|
|
params: {
|
|
current_password: "wrong",
|
|
password: "NewPass123",
|
|
password_confirmation: "NewPass123"
|
|
},
|
|
headers: auth_headers
|
|
expect(response).to have_http_status(:unprocessable_entity)
|
|
expect(user.reload.authenticate("Password123")).to be_truthy
|
|
end
|
|
|
|
it "rejects a password that fails complexity rules" do
|
|
patch "/api/v1/account/password",
|
|
params: {
|
|
current_password: "Password123",
|
|
password: "newpass123",
|
|
password_confirmation: "newpass123"
|
|
},
|
|
headers: auth_headers.merge("Accept-Language" => "en")
|
|
expect(response).to have_http_status(:unprocessable_entity)
|
|
expect(JSON.parse(response.body)["error"]).to match(/3 of/i)
|
|
expect(user.reload.authenticate("Password123")).to be_truthy
|
|
end
|
|
|
|
it "rejects reusing the current password" do
|
|
patch "/api/v1/account/password",
|
|
params: {
|
|
current_password: "Password123",
|
|
password: "Password123",
|
|
password_confirmation: "Password123"
|
|
},
|
|
headers: auth_headers.merge("Accept-Language" => "en")
|
|
expect(response).to have_http_status(:unprocessable_entity)
|
|
expect(JSON.parse(response.body)["error"]).to match(/different/i)
|
|
expect(user.reload.authenticate("Password123")).to be_truthy
|
|
end
|
|
|
|
it "localizes password errors from Accept-Language" do
|
|
patch "/api/v1/account/password",
|
|
params: {
|
|
current_password: "Password123",
|
|
password: "Password123",
|
|
password_confirmation: "Password123"
|
|
},
|
|
headers: auth_headers.merge("Accept-Language" => "it")
|
|
expect(response).to have_http_status(:unprocessable_entity)
|
|
expect(JSON.parse(response.body)["error"]).to eq("La nuova password deve essere diversa da quella attuale")
|
|
end
|
|
end
|
|
|
|
describe "POST /api/v1/auth/password/forgot" do
|
|
it "always returns ok and sends mail when the user exists" do
|
|
expect {
|
|
post "/api/v1/auth/password/forgot", params: { email: user.email }
|
|
}.to change { ActionMailer::Base.deliveries.size }.by(1)
|
|
expect(response).to have_http_status(:ok)
|
|
expect(user.reload.password_reset_digest).to be_present
|
|
end
|
|
|
|
it "returns the same message for unknown emails" do
|
|
expect {
|
|
post "/api/v1/auth/password/forgot", params: { email: "nobody@example.com" }
|
|
}.not_to change { ActionMailer::Base.deliveries.size }
|
|
expect(response).to have_http_status(:ok)
|
|
end
|
|
|
|
it "localizes the response message from Accept-Language" do
|
|
post "/api/v1/auth/password/forgot",
|
|
params: { email: user.email },
|
|
headers: { "Accept-Language" => "fr" }
|
|
expect(response).to have_http_status(:ok)
|
|
expect(JSON.parse(response.body)["message"]).to include("réinitialiser")
|
|
end
|
|
end
|
|
end
|