require 'retrospective'
require 'team'

RSpec.describe Retrospective do
  let(:teams) do
    {
      'Plan' => {
        'label' => 'plan',
        'project' => 'plan',
        'owner' => 'smcgivern',
        'mention_team' => false,
        'mention_team_on_creation' => false,
        'create_discussions' => false,
        'create_individual_discussions' => false,
      },
      'Create' => {
        'label' => 'group::code%20review',
        'project' => 'create-stage%2fcode-review',
        'owner' => 'm_gill',
        'mention_team' => false,
        'mention_team_on_creation' => false,
        'create_discussions' => false,
        'create_individual_discussions' => false,
      },
      'Discussion' => {
        'label' => 'group::discussion',
        'project' => 'create-stage%2fdiscussion',
        'owner' => 'n_g_neering',
        'mention_team' => false,
        'mention_team_on_creation' => false,
        'create_discussions' => true,
        'create_individual_discussions' => false,
      }
    }
  end

  let(:read_client) { GitlabApi.new(token: '1234') }
  let(:write_client) { GitlabApi.new(token: '4567') }
  let(:subject) { Retrospective.new(read_client: read_client, write_client: write_client) }

  before do
    allow(Team).to receive(:hash_from_file).and_return(teams)
    # Allow puts to prevent test output pollution
    allow(subject).to receive(:puts)
  end

  describe '#create_issue' do
    let(:issue) do
      {
        '_links' => {
          'self' => 'issue_link'
        }
      }
    end
    let(:milestone) do
      {
        'start_date' => (Date.today - 3).to_s,
        'title' => '30.5'
      }
    end
    let(:success_response) { double(code: 200) }
    let(:issue_discussions_path) { issue['_links']['self'] + '/discussions' }

    before do
      allow_any_instance_of(DescriptionTemplate).to receive(:result_with_hash).and_return('issue_description')
      allow(write_client).to receive(:post).with("projects/gl-retrospectives%2F#{team.project}/issues", hash_including(:body)).and_return(issue)
    end

    context 'when performing a dry run' do
      let(:team) { Team.find('Discussion') }

      it 'passes release as a hash to DescriptionTemplate' do
        expect(DescriptionTemplate).to receive(:new).with(team, milestone, anything).and_call_original
        subject.create_issue(team: team, release: milestone, dry_run: true)
      end
    end

    context 'when creating an issue' do
      let(:team) { Team.find('Plan') }
      let(:expected_body) do
        {
          title: "#{milestone['title']} #{team.name} retrospective",
          description: anything,
          confidential: false
        }
      end

      it 'makes a post request with valid fields' do
        expect(write_client).to receive(:post).with("projects/gl-retrospectives%2F#{team.project}/issues", body: expected_body)
        subject.create_issue(team: team, release: milestone, dry_run: false)
      end 
    end 
    
    context 'when discussions should be created' do let(:team) { Team.find('Discussion') }
      it 'makes post requests with set discussion topics' do
        expect(write_client).to receive(:post).with(issue_discussions_path, body: { body: '## 👍 What went well this release?' }).and_return(success_response)
        expect(write_client).to receive(:post).with(issue_discussions_path, body: { body: '## 👎 What didn\'t go well this release?' }).and_return(success_response)
        expect(write_client).to receive(:post).with(issue_discussions_path, body: { body: '## 📈 What can we improve going forward?' }).and_return(success_response)
        expect(write_client).to receive(:post).with(issue_discussions_path, body: { body: '## 🌟 What praise do you have for the group?' }).and_return(success_response)

        subject.create_issue(team: team, release: milestone, dry_run: false)
      end
    end

    context 'when discussion should not be created' do
      let(:team) { Team.find('Plan') }

      it 'makes no post requests' do
        expect(write_client).not_to receive(:post).with(issue_discussions_path, hash_including(:body))

        subject.create_issue(team: team, release: milestone, dry_run: false)
      end
    end

    context 'when parent topic should not be created' do
      let(:team) { Team.find('Plan') }

      it 'makes no post request' do
        expect(write_client).not_to receive(:post).with(issue_discussions_path, hash_including(:body))

        subject.create_issue(team: team, release: milestone, dry_run: false)
      end
    end
  end
end
