require "rails_helper"

RSpec.describe Api::SessionsController do

  context "#validate" do

    let(:validate_url) { ENV.fetch("TEACHABLE_SSO_BASE_URL", "https://sso.zeachable.com") + "/api/v1/my_teachable_sign_in/validate" }
    let(:valid_credentials) { { email: "owner+#{rand(9001)}@test.com", password: SecureRandom.hex(10) } }

    context "with reCAPTCHA enabled" do
      before(:each) do
        ENV["RECAPTCHA_SECRET_KEY"] = "test"
        ENV["RECAPTCHA_SITE_KEY"]   = "test"
      end

      after(:all) do
        ENV["RECAPTCHA_SECRET_KEY"] = nil
        ENV["RECAPTCHA_SITE_KEY"]   = nil
      end

      context "with valid credentials" do
        it "returns successfully" do
          recaptcha_response = SecureRandom.hex(64)
          stub_request(
            :post,
            "https://www.google.com/recaptcha/api/siteverify"
          ).with(
            body: hash_including(
              secret: ENV["RECAPTCHA_SECRET_KEY"],
              response: recaptcha_response,
              remoteip: "0.0.0.0",
            )
          ).to_return(body: { "success" => true }.to_json, headers: { "Content-Type"=> "application/json" })
          stub_request(
            :post,
            validate_url
          ).with(
            body: "email=#{CGI.escape(valid_credentials[:email])}&password=#{valid_credentials[:password]}&referral=&auth_token=#{ENV["MARKETING_API_AUTH_TOKEN"]}"
          ).to_return(
            body: {
              teachable_account: {
                authenticated_url: "https://sso.zeachable.com/secure/teachagble_accounts/profile",
              },
            }.to_json,
            headers: {
              "Content-Type"=> "application/json",
            }
          )
          post :validate, params: { email: valid_credentials[:email], password: valid_credentials[:password], recaptcha: recaptcha_response }
          expect(response).to be_success
          expect(response).to have_http_status(200)
        end
      end

      context "with invalid credentials" do
        it "returns unsuccessfully" do
          recaptcha_response = SecureRandom.hex(64)
          stub_request(
            :post,
            "https://www.google.com/recaptcha/api/siteverify"
          ).with(
            body: hash_including(
              secret: ENV["RECAPTCHA_SECRET_KEY"],
              response: recaptcha_response,
              remoteip: "0.0.0.0",
            )
          ).to_return(body: { "success" => true }.to_json, headers: { "Content-Type"=> "application/json" })
          stub_request(
            :post,
            validate_url
          ).with(
            body: "email=#{CGI.escape(valid_credentials[:email])}&password=bad_password&referral=&auth_token=#{ENV["MARKETING_API_AUTH_TOKEN"]}"
          ).to_return(
            body: {
            }.to_json,
            headers: {
              "Content-Type"=> "application/json",
            },
            status: 401
          )
          post :validate, params: { email: valid_credentials[:email], password: "bad_password", recaptcha: recaptcha_response }
          expect(response).to have_http_status(401)
        end
      end
    end

    context "without reCAPTCHA enabled" do
      context "with valid credentials" do
        it "returns successfully" do
          stub_request(
            :post,
            validate_url
          ).with(
            body: "email=#{CGI.escape(valid_credentials[:email])}&password=#{valid_credentials[:password]}&referral=&auth_token=#{ENV["MARKETING_API_AUTH_TOKEN"]}"
          ).to_return(
            body: {
              teachable_account: {
                authenticated_url: "https://sso.zeachable.com/secure/teachagble_accounts/profile",
              },
            }.to_json,
            headers: {
              "Content-Type"=> "application/json",
            }
          )
          post :validate, params: { email: valid_credentials[:email], password: valid_credentials[:password] }
          expect(response).to be_success
          expect(response).to have_http_status(200)
        end
      end

      context "with invalid credentials" do
        it "returns unsuccessfully" do
          stub_request(
            :post,
            validate_url
          ).with(
            body: "email=#{CGI.escape(valid_credentials[:email])}&password=bad_password&referral=&auth_token=#{ENV["MARKETING_API_AUTH_TOKEN"]}"
          ).to_return(
            body: {
            }.to_json,
            headers: {
              "Content-Type"=> "application/json",
            },
            status: 401
          )
          post :validate, params: { email: valid_credentials[:email], password: "bad_password" }
          expect(response).to have_http_status(401)
        end
      end
    end

  end

end
