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