require 'gitlab_api'

RSpec.describe GitlabApi do
  let(:token) { nil }
  subject(:api) { described_class.new(token: token) }

  shared_examples 'unsuccessful response' do |verb, options = {}|
    let(:token) { 'Baz' }

    context 'when the request is not successful' do
      let(:failure_response) { double(code: 400, body: 'Foo') }

      it 'prints the failure and raises UpdateFailed' do
        allow(HTTParty).to receive(verb).and_return(failure_response)
        allow(api).to receive(:p)
        allow(api).to receive(:puts)

        expect(api)
          .to receive(:puts).with(a_string_starting_with(verb.to_s.upcase))

        expect { api.public_send(verb, '/', **options) }
          .to raise_error(described_class::UpdateFailed)
      end
    end
  end

  describe '#count' do
    let(:success_response) { double(code: 200, headers: { 'X-Total': 333 }) }

    context 'with token' do
      let(:token) { 'foo' }

      it 'adds the private token as a header' do
        expect(HTTParty).to receive(:get)
          .with(anything, { headers: { 'Private-Token': token }})
          .and_return(success_response)

        api.count('/foo')
      end
    end
  end

  describe '#get' do
    let(:success_response) { double(code: 200) }

    it 'treats the path as a URL if it starts with ENDPOINT' do
      url = 'https://gitlab.com/api/v4/projects/gitlab-org%2fgitlab-ce/issues?per_page=50&state=opened'

      expect(HTTParty).to receive(:get)
        .with(a_string_starting_with(url), anything)
        .and_return(success_response)

      api.get(url)
    end

    it 'treats the path as a path if it does not start with ENDPOINT' do
      expect(HTTParty).to receive(:get)
        .with(a_string_starting_with(described_class::ENDPOINT), anything)
        .and_return(success_response)

      api.get('/foo')
    end

    context 'with token' do
      let(:token) { 'foo' }

      it 'provides private token in the header' do
        expect(HTTParty).to receive(:get)
          .with(anything, { headers: { 'Private-Token': token }})
          .and_return(success_response)

        api.get('/foo')
      end
    end

    it 'adds per_page=50 to the request URL' do
      expect(HTTParty).to receive(:get)
        .with(a_string_ending_with('?per_page=50'), anything)
        .and_return(success_response)

      api.get('/foo')
    end

    include_examples 'unsuccessful response', :get
  end

  describe '#post' do
    include_examples 'unsuccessful response', :post, body: 'Foo'
  end

  describe '#put' do
    include_examples 'unsuccessful response', :put, body: 'Foo'
  end
end
