spec/lib/release_tools/release_managers/schedule_spec.rb (182 lines of code) (raw):

# frozen_string_literal: true require 'spec_helper' describe ReleaseTools::ReleaseManagers::Schedule do let(:schedule) { described_class.new } let(:version) { ReleaseTools::Version.new('11.8') } let(:yaml) do <<~YAML - version: '11.8' date: November 16th, 2023 manager_americas: - Robert Speicher manager_apac_emea: - Yorick Peterse appsec: - Security Member 1 - Security Member 2 - version: '11.9' date: December 21st, 2023 manager_americas: - Robert Speicher manager_apac_emea: - New Team Member appsec: - Security Member 3 - Security Member 4 - version: '11.10' date: January 18th, 2024 manager_americas: - Robert Speicher manager_apac_emea: - Yorick Peterse appsec: - Security Member 1 - Security Member 4 YAML end def stub_schedule(body) stub_request(:get, described_class::RELEASES_YAML).to_return(body: body) end before do # Prevent retry delay from slowing down specs stub_const("#{described_class}::RETRY_INTERVAL", 0) end describe '#version_for_date' do it 'calls the gitlab_releases gem' do expect(ReleaseTools::GitlabReleasesGemClient) .to receive(:version_for_date) .and_return('16.6') schedule.version_for_date(Date.today) end context 'when there are no releases scheduled at all' do it 'returns nil' do expect(ReleaseTools::GitlabReleasesGemClient) .to receive(:version_for_date) expect(schedule.version_for_date(Date.today)).to be_nil end end end describe '#ids_for_version' do context 'for authorized release managers' do let(:member1) { double(:member, name: 'Robert Speicher', id: 1, username: 'rspeicher') } let(:member2) { double(:member, name: 'Yorick Peterse', id: 2, username: 'yorickpeterse') } it 'returns an array of usernames' do allow(schedule) .to receive(:authorized_release_managers) .and_return([member1, member2]) expect(schedule.ids_for_version(version)).to eq([1, 2]) end end end describe '#usernames_for_version' do context 'for authorized release managers' do let(:member1) { double(:member, name: 'Robert Speicher', id: 1, username: 'rspeicher') } let(:member2) { double(:member, name: 'Yorick Peterse', id: 2, username: 'yorickpeterse') } it 'returns an array of usernames' do allow(schedule) .to receive(:authorized_release_managers) .and_return([member1, member2]) expect(schedule.usernames_for_version(version)).to eq(%w(rspeicher yorickpeterse)) end end end describe '#authorized_release_managers' do let(:version) { ReleaseTools::Version.new('11.9') } let(:release_managers_fixture) { File.expand_path('../../../fixtures/release_managers.yml', __dir__) } let(:definitions) { ReleaseTools::ReleaseManagers::Definitions.new(release_managers_fixture) } context 'for authorized release managers' do let(:member1) { double(:robert, name: 'Robert Speicher', id: 1, username: 'rspeicher') } let(:member2) { double(:new_team_member, name: 'New Team Member', id: 2, username: 'new-team-member') } it 'returns an array of users' do client = double('client') expect(client).to receive(:get_user).with('rspeicher').and_return(member1) expect(client).to receive(:get_user).with('new-team-member').and_return(member2) allow(ReleaseTools::ReleaseManagers::Client) .to receive(:new) .and_return(client) stub_schedule(yaml) expect(ReleaseTools::ReleaseManagers::Definitions).to receive(:new).and_return(definitions) expect(schedule.authorized_release_managers(version)).to contain_exactly(member1, member2) end end context 'when no release manager data is available' do it 'raises an error' do stub_schedule('') expect { schedule.authorized_release_managers(version) } .to raise_error(described_class::VersionNotFoundError) end end end describe '#group_members' do it 'returns a Hash mapping release manager names to their user attributes' do client = instance_spy(ReleaseTools::ReleaseManagers::Client) allow(ReleaseTools::ReleaseManagers::Client) .to receive(:new) .and_return(client) allow(client) .to receive(:members) .and_return([ double(:member, name: 'Robert Speicher', id: 1, username: 'rspeicher'), double(:member, name: 'Yorick Peterse', id: 2, username: 'yorickpeterse') ]) expect(schedule.group_members.fetch('Robert Speicher').id) .to eq(1) expect(schedule.group_members.fetch('Yorick Peterse').username) .to eq('yorickpeterse') end end describe '#schedule_yaml' do context 'when the download succeeds' do it 'returns the release manager data' do stub_schedule(yaml) expect(schedule.schedule_yaml.length).to eq(3) end end context 'when the download fails' do it 'returns an empty Array' do stub_request(:any, /.*/).to_raise(Errno::ENOENT) expect(schedule.schedule_yaml).to be_empty end end end describe '#active_release_managers' do it 'return the authorized release managers for the active milestone' do users = double('users') expect(schedule) .to receive(:active_version) .and_return(version) expect(schedule) .to receive(:authorized_release_managers) .with(version) .and_return(users) expect(schedule.active_release_managers).to eq(users) end end describe '#active_appsec_release_managers' do let(:user1) { build(:user, name: 'Security Member 1', id: 111) } let(:user2) { build(:user, name: 'Security Member 2', id: 222) } let(:user3) { build(:user, name: 'Security Member 3', id: 333) } let(:user4) { build(:user, name: 'Security Member 4', id: 444) } let(:user5) { build(:user, name: 'Security Member 5', id: 555) } let(:internal_client) do spy( group_members: [user1, user2, user3, user4, user5] ) end subject { schedule.active_appsec_release_managers } it 'returns the active appsec release managers' do stub_schedule(yaml) allow(ReleaseTools::GitlabClient).to receive(:client).and_return(internal_client) allow(schedule).to receive(:active_version).and_return(ReleaseTools::Version.new('11.10')) expect(subject).to eq([user3, user4]) end end describe '#active_version' do subject(:active_version) { schedule.active_version } it 'uses the GitlabReleasesGemClient to fetch the active_version' do expect(ReleaseTools::GitlabReleasesGemClient) .to receive(:active_version) .and_return(version.to_s) expect(schedule).not_to receive(:version_for_date) expect(active_version).to eq(version) end end end