require "rails_helper"

RSpec.describe PasswordResetsController, type: :controller do
  render_views

  let(:user) { create(:user) }

  describe "#new" do
    it "responds successfully" do
      get :new

      expect(response).to be_successful
    end

    it "renders the content" do
      get :new

      expect(response.body).to have_content("Password Reset")
      expect(response.body).to have_field("Email")
    end
  end

  describe "#create" do
    it "redirects to new_session_path" do
      post :create, params: { password_reset: { email: user.email } }

      expect(response).to be_redirect
      expect(response).to redirect_to(new_session_path)
    end

    it "shows an alert message" do
      post :create, params: { password_reset: { email: user.email } }

      expect(flash.notice).not_to be_nil
    end

    it "sends the reset email" do
      assert_enqueued_emails 1 do
        post :create, params: { password_reset: { email: user.email } }
      end
    end
  end

  describe "#edit" do
    it "responds successfully" do
      get :edit, params: { id: user.password_reset_token }

      expect(response).to be_successful
    end

    it "renders the right content" do
      user = create(:user) 

      get :edit, params: { id: user.password_reset_token }

      expect(response.body).to have_content("Password Reset")
      expect(response.body).to have_selector("input[name='password_reset[password]']")
    end

    context "when reset token is invalid" do
      it "redirects to the sign in page" do
        get :edit, params: { id: "bad token" }

        expect(response).to be_redirect
        expect(response).to redirect_to(new_session_path)
        expect(flash.notice).to be_present
      end
    end
  end

  describe "#update" do
    it "redirects to new_session_path" do
      patch :update, params: { id: user.password_reset_token, password_reset: { password: "newpassword" } }

      expect(response).to be_redirect
      expect(response).to redirect_to(new_session_path)
    end

    it "shows an alert message" do
      patch :update, params: { id: user.password_reset_token, password_reset: { password: "newpassword" } }

      expect(flash.notice).not_to be_nil
    end

    it "resets the user password" do
      expect { 
        patch :update, params: { id: user.password_reset_token, password_reset: { password: "newpassword" } }
      }.to change { user.reload.password_digest }
    end

    it "generates a new password reset token for the user" do
      user = create(:user)

      expect { 
        patch :update, params: { id: user.password_reset_token, password_reset: { password: "foo" } }
      }.to change { user.reload.password_reset_token }
    end

    context "when no new password is set" do
      it "responds successfully" do
        patch :update, params: { id: user.password_reset_token, password_reset: { password: "" } }

        expect(response).to be_successful
      end

      it "shows an alert message" do
        patch :update, params: { id: user.password_reset_token, password_reset: { password: "" } }

        expect(flash.alert).not_to be_nil
      end
    end
  end
end
