require "rails_helper"
RSpec.describe UsersController, type: :request do
let(:user) { FactoryBot.create(:user) }
let(:other_user) { FactoryBot.create(:user) }
let(:headers) { { "Accept" => "text/html" } }
let(:page) { Capybara::Node::Simple.new(response.body) }
let(:new_name) { "new test name" }
let(:new_email) { "new@example.com" }
let(:params) { { id: user.id, user: { name: new_name } } }
let(:notify_client) { instance_double(Notifications::Client) }
let(:devise_notify_mailer) { DeviseNotifyMailer.new }
before do
allow(DeviseNotifyMailer).to receive(:new).and_return(devise_notify_mailer)
allow(devise_notify_mailer).to receive(:notify_client).and_return(notify_client)
allow(notify_client).to receive(:send_email).and_return(true)
end
context "when user is not signed in" do
describe "#show" do
it "does not let you see user details" do
get "/users/#{user.id}", headers: headers, params: {}
expect(response).to redirect_to("/account/sign-in")
end
end
describe "#edit" do
it "does not let you edit user details" do
get "/users/#{user.id}/edit", headers: headers, params: {}
expect(response).to redirect_to("/account/sign-in")
end
end
describe "#password" do
it "does not let you edit user passwords" do
get "/account/edit/password", headers: headers, params: {}
expect(response).to redirect_to("/account/sign-in")
end
end
describe "#patch" do
it "does not let you update user details" do
patch "/logs/#{user.id}", params: {}
expect(response).to redirect_to("/account/sign-in")
end
end
describe "reset password" do
it "renders the user edit password view" do
_raw, enc = Devise.token_generator.generate(User, :reset_password_token)
get "/account/password/edit?reset_password_token=#{enc}"
expect(page).to have_css("h1", class: "govuk-heading-l", text: "Reset your password")
end
context "when updating a user password" do
context "when the reset token is valid" do
let(:params) do
{
id: user.id, user: { password: new_name, password_confirmation: "something_else" }
}
end
before do
sign_in user
put "/account", headers:, params:
end
it "shows an error if passwords don't match" do
expect(response).to have_http_status(:unprocessable_entity)
expect(page).to have_selector("#error-summary-title")
expect(page).to have_content("Password confirmation doesn’t match new password")
end
end
context "when a reset token is more than 3 hours old" do
let(:raw) { user.send_reset_password_instructions }
let(:params) do
{
id: user.id,
user: {
password: new_name,
password_confirmation: new_name,
reset_password_token: raw,
},
}
end
before do
allow(User).to receive(:find_or_initialize_with_error_by).and_return(user)
allow(user).to receive(:reset_password_sent_at).and_return(4.hours.ago)
put "/account/password", headers:, params:
end
it "shows an error" do
expect(response).to have_http_status(:unprocessable_entity)
expect(page).to have_selector("#error-summary-title")
expect(page).to have_content(I18n.t("errors.messages.expired"))
end
end
end
end
describe "title link" do
it "routes user to the /logs page" do
sign_in user
get "/", headers:, params: {}
follow_redirect!
expect(path).to include("/logs")
expected_link = "