# frozen_string_literal: true

RSpec.describe OAuth2::Strategy::Password do
  subject { client.password }

  let(:client) do
    cli = OAuth2::Client.new("abc", "def", site: "http://api.example.com")
    cli.connection = Faraday.new(cli.site, cli.options[:connection_opts]) do |b|
      b.request :url_encoded
      b.adapter :test do |stub|
        stub.post("/oauth/token") do |_env|
          case @mode
          when "formencoded"
            [200, {"Content-Type" => "application/x-www-form-urlencoded"}, "expires_in=600&access_token=salmon&refresh_token=trout"]
          when "json"
            [200, {"Content-Type" => "application/json"}, '{"expires_in":600,"access_token":"salmon","refresh_token":"trout"}']
          else raise ArgumentError, "Bad @mode: #{@mode}"
          end
        end
      end
    end
    cli
  end

  describe "#authorize_url" do
    it "raises NotImplementedError" do
      expect { subject.authorize_url }.to raise_error(NotImplementedError)
    end
  end

  %w[json formencoded].each do |mode|
    describe "#get_token (#{mode})" do
      before do
        @mode = mode
        @access = subject.get_token("username", "password")
      end

      it "returns AccessToken with same Client" do
        expect(@access.client).to eq(client)
      end

      it "returns AccessToken with #token" do
        expect(@access.token).to eq("salmon")
      end

      it "returns AccessToken with #refresh_token" do
        expect(@access.refresh_token).to eq("trout")
      end

      it "returns AccessToken with #expires_in" do
        expect(@access.expires_in).to eq(600)
      end

      it "returns AccessToken with #expires_at" do
        expect(@access.expires_at).not_to be_nil
      end
    end
  end
end
