# frozen_string_literal: true

require 'spec_helper'

RSpec.describe ::Gitlab::Housekeeper::Change do
  let(:change) { described_class.new }
  let(:job_url) { nil }

  before do
    change.title = 'The title'
    change.description = 'The description'
    change.keep_class = Object

    stub_env 'CI_JOB_URL', job_url
  end

  describe '#initialize' do
    it 'sets default values for optional fields' do
      change = described_class.new

      expect(change.labels).to eq([])
      expect(change.assignees).to eq([])
      expect(change.reviewers).to eq([])
      expect(change.push_options.ci_skip).to eq(false)
    end
  end

  describe '#assignees=' do
    it 'always sets an array' do
      change = described_class.new
      change.assignees = 'foo'

      expect(change.assignees).to eq(['foo'])
    end
  end

  describe '#reviewers=' do
    it 'always sets an array' do
      change = described_class.new
      change.reviewers = 'foo'

      expect(change.reviewers).to eq(['foo'])
    end
  end

  describe '#mr_description' do
    it 'includes standard content' do
      expect(change.mr_description).to eq(
        <<~MARKDOWN
        The description

        This change was generated by
        [gitlab-housekeeper](https://gitlab.com/gitlab-org/gitlab/-/tree/master/gems/gitlab-housekeeper)
        locally using the `Object` keep.

        To provide feedback on your experience with `gitlab-housekeeper` please create an issue with the
        label ~"GitLab Housekeeper" and consider pinging the author of this keep.
        MARKDOWN
      )
    end

    context 'when generated in CI' do
      let(:job_url) { 'https://gitlab.com/namespace/project/-/jobs/123456789' }

      it 'includes CI job URL' do
        expect(change.mr_description).to include("in [CI](#{job_url}) using the `Object` keep")
      end
    end
  end

  describe '#update_required?' do
    let(:change) { create_change }

    it 'returns false if the category is in non_housekeeper_changes' do
      change.non_housekeeper_changes = [:code]
      expect(change.update_required?(:code)).to eq(false)
    end

    it 'returns true if the category is not in non_housekeeper_changes' do
      change.non_housekeeper_changes = [:title]
      expect(change.update_required?(:code)).to eq(true)
    end
  end

  describe '#already_approved?' do
    it 'is true when changes include approvals' do
      change.non_housekeeper_changes = [:code, :approvals]
      expect(change.already_approved?).to eq(true)
    end

    it 'is false when changes do not approvals' do
      change.non_housekeeper_changes = [:code, :title]
      expect(change.already_approved?).to eq(false)
    end
  end

  describe '#commit_message' do
    it 'includes standard content' do
      expect(change.commit_message).to eq(
        <<~MARKDOWN
        The title

        The description

        This change was generated by
        [gitlab-housekeeper](https://gitlab.com/gitlab-org/gitlab/-/tree/master/gems/gitlab-housekeeper)
        locally using the `Object` keep.

        To provide feedback on your experience with `gitlab-housekeeper` please create an issue with the
        label ~"GitLab Housekeeper" and consider pinging the author of this keep.


        Changelog: other
        MARKDOWN
      )
    end

    context 'when setting a "changelog_type"' do
      before do
        change.changelog_type = 'removed'
      end

      it 'incudes "Changelog: removed"' do
        expect(change.commit_message).to eq(
          <<~MARKDOWN
          The title

          The description

          This change was generated by
          [gitlab-housekeeper](https://gitlab.com/gitlab-org/gitlab/-/tree/master/gems/gitlab-housekeeper)
          locally using the `Object` keep.

          To provide feedback on your experience with `gitlab-housekeeper` please create an issue with the
          label ~"GitLab Housekeeper" and consider pinging the author of this keep.


          Changelog: removed
          MARKDOWN
        )
      end
    end
  end

  context 'when setting a "changelog_ee"' do
    before do
      change.changelog_ee = true
    end

    it 'includes "EE: true"' do
      expect(change.commit_message).to eq(
        <<~MARKDOWN
          The title

          The description

          This change was generated by
          [gitlab-housekeeper](https://gitlab.com/gitlab-org/gitlab/-/tree/master/gems/gitlab-housekeeper)
          locally using the `Object` keep.

          To provide feedback on your experience with `gitlab-housekeeper` please create an issue with the
          label ~"GitLab Housekeeper" and consider pinging the author of this keep.


          Changelog: other
          EE: true
        MARKDOWN
      )
    end
  end

  describe '#valid?' do
    it 'is not valid if missing required attributes' do
      [:identifiers, :title, :description, :changed_files].each do |attribute|
        change = create_change
        expect(change).to be_valid
        change.public_send("#{attribute}=", nil)
        expect(change).not_to be_valid
      end
    end

    it 'is not valid if changed_files is empty' do
      change = create_change
      change.changed_files = []
      expect(change).not_to be_valid
    end
  end

  describe '#truncated_title' do
    it 'truncates the title to 72 chars' do
      change = create_change(title: 'some long title ' * 10)

      expect(change.truncated_title).to eq('some long title some long title some long title some long title some lon')
      expect(change.truncated_title.length).to eq(72)
    end
  end
end
