require 'description_template'
require 'team'

RSpec.describe DescriptionTemplate do
  let(:api_client) { GitlabApi.new(token: 'token') }

  describe '#result_with_hash' do
    ISSUE_FIELDS = ['deliverables', 'features', 'bugs', 'issues', 'slipped', 'current_retrospective', 'issue_count', 'total_weight', 'merge_request_count']
    EXPECTED_KEYS = ISSUE_FIELDS + ['issue_url_prefix', 'vsa_url_prefix', 'release_start_date', 'release_due_date']

    let(:team) { Team::TeamInfo.new('backend') }
    let(:erb_template) { ERB.new('', trim_mode: '<>') }
    let(:release) { { 'title' => '1.0' } }
    let(:description_template) { described_class.new(team, release, api_client: api_client) }

    before do
      allow(description_template).to receive(:load_template).and_return(erb_template)

      ISSUE_FIELDS.each do |field|
        allow(description_template).to receive(field).and_return(field)
      end
    end

    context 'when the hash contains updating_description' do
      EXPECTED_KEYS.each do |field|
        it "includes #{field}" do
          expect(erb_template)
            .to receive(:result_with_hash).with(a_hash_including(field.to_sym))

          description_template.result_with_hash(updating_description: true)
        end
      end
    end

    context 'when the hash does not contain updating_description' do
      EXPECTED_KEYS.each do |field|
        it "does not includes #{field}" do
          expect(erb_template).to receive(:result_with_hash) do |hash|
            expect(hash).not_to include(field.to_sym)
          end

          description_template.result_with_hash(updating_description: false)
        end
      end
    end

    context 'for a team with the default template' do
      before do
        allow(description_template).to receive(:load_template).and_call_original
      end

      let(:team) { Team.find('Create:Source Code') }

      it 'includes a quick action to apply the team label' do
        result = description_template.result_with_hash(updating_description: false)
        expect(result).to include("~\"#{team.label}\"")
      end
    end

    context 'for a team with the multiple owners' do
      before do
        allow(description_template).to receive(:load_template).and_call_original
      end

      let(:team) { Team.find('UX') }

      it 'includes a quick action to assign to all owners' do
        result = description_template.result_with_hash(updating_description: false)
        expect(result).to include("/assign @vkarnes @susantacker @ampesta")
      end
    end

    it 'supports nested templates' do
      default_template = ERB.new('<%= include_template.call("foo") %>')
      foo_template = ERB.new('<%= include_template.call("bar") %>')
      bar_template = ERB.new('This is bar: <%= release %>')

      allow(description_template)
        .to receive(:load_template).with('default').and_return(default_template)
      allow(description_template)
        .to receive(:load_template).with('foo').and_return(foo_template)
      allow(description_template)
        .to receive(:load_template).with('bar').and_return(bar_template)

      expect(description_template.result_with_hash({}))
        .to include('This is bar')
        .and include(release['title'])
    end
  end

  describe 'using the teams in teams.yml' do
    before do
      stub_request(:get, /\A#{Regexp.quote(GitlabApi::ENDPOINT)}/)
        .to_return(
          body: [ { title: 'title', web_url: 'url', labels: ['group::certify'] } ].to_json,
          headers: { 'Content-Type' => 'application/json' },
        )
    end

    Team.all.each do |team|
      it "renders the #{team.name} team template without errors" do
        release = { title: '12.0' }
        expect do
          described_class.new(team, release, api_client: api_client).result_with_hash(updating_description: false)
          described_class.new(team, release, api_client: api_client).result_with_hash(updating_description: true)
        end.not_to raise_error
      end
    end
  end
end
