125 lines
3.8 KiB
Ruby
125 lines
3.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'spec_helper'
|
|
|
|
RSpec.describe Members::Enumerable, feature_category: :groups_and_projects do
|
|
using RSpec::Parameterized::TableSyntax
|
|
|
|
before_all do
|
|
ActiveRecord::Schema.define do
|
|
create_table :_test_member_sources, force: true
|
|
end
|
|
end
|
|
|
|
before do
|
|
stub_const('TestMemberSource', klass)
|
|
|
|
# rubocop:disable RSpec/AnyInstanceOf -- stub all instances, hooks and notifications are irrelevant to the tests.
|
|
allow_any_instance_of(SystemHooksService).to receive(:execute_hooks_for)
|
|
allow_any_instance_of(Member).to receive_messages(notifiable?: false, send_request: nil)
|
|
# rubocop:enable RSpec/AnyInstanceOf
|
|
end
|
|
|
|
let_it_be(:klass) do
|
|
Class.new(Namespace) do
|
|
include Members::Enumerable
|
|
|
|
self.table_name = '_test_member_sources'
|
|
|
|
has_many :members, dependent: :destroy, as: :source, class_name: '::Member'
|
|
end
|
|
end
|
|
|
|
let_it_be(:source) { create(:namespace).becomes(klass) } # rubocop: disable Cop/AvoidBecomes -- easier to reuse existing factory object for a dummy model
|
|
let!(:owner) { create(:member, :owner, source: source).user }
|
|
let!(:guest) { create(:member, :guest, source: source).user }
|
|
let!(:requested) { create(:member, :access_request, source: source).user }
|
|
let!(:invited) { create(:member, :invited, source: source, user: create(:user)).user }
|
|
|
|
shared_context 'with parametrized filters table' do
|
|
where(:filters, :selected) do
|
|
nil | [ref(:owner), ref(:guest)]
|
|
{ access_level: Gitlab::Access::OWNER } | [ref(:owner)]
|
|
{ access_level: Gitlab::Access::GUEST } | [ref(:guest)]
|
|
end
|
|
end
|
|
|
|
shared_examples 'extract value from selected members only' do |column|
|
|
it 'extracted value from selected members' do
|
|
expected_values = selected.map { |user| user.public_send(column) }
|
|
expect(values).to contain_exactly(*expected_values)
|
|
end
|
|
|
|
it 'skips members with access request' do
|
|
expect(values).not_to include(requested.public_send(column))
|
|
end
|
|
|
|
it 'skips invited members' do
|
|
expect(values).not_to include(invited.public_send(column))
|
|
end
|
|
end
|
|
|
|
describe '#each_member_user' do
|
|
include_context 'with parametrized filters table'
|
|
|
|
with_them do
|
|
subject(:users) do
|
|
users = []
|
|
source.each_member_user(filters) { |user| users << user }
|
|
users
|
|
end
|
|
|
|
it 'iterates over selected members' do
|
|
expect(users).to contain_exactly(*selected)
|
|
end
|
|
|
|
it 'skips members with access request' do
|
|
expect(users).not_to include(requested)
|
|
end
|
|
|
|
it 'skips invited members' do
|
|
expect(users).not_to include(invited)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#map_member_user' do
|
|
include_context 'with parametrized filters table'
|
|
|
|
with_them do
|
|
subject(:values) { source.map_member_user(filters, &:name) }
|
|
|
|
it_behaves_like 'extract value from selected members only', :name
|
|
end
|
|
end
|
|
|
|
describe '#pluck_member_user' do
|
|
include_context 'with parametrized filters table'
|
|
|
|
with_them do
|
|
context 'when single column passed' do
|
|
subject(:values) { source.pluck_member_user(:name, filters: filters) }
|
|
|
|
it_behaves_like 'extract value from selected members only', :name
|
|
end
|
|
|
|
context 'when multiple column passed' do
|
|
subject(:values) { source.pluck_member_user(:name, :email, filters: filters) }
|
|
|
|
it 'extract multiple values from selected members' do
|
|
expected_values = selected.map { |user| [user.name, user.email] }
|
|
expect(values).to contain_exactly(*expected_values)
|
|
end
|
|
|
|
it 'skips members with access request' do
|
|
expect(values).not_to include([requested.name, requested.email])
|
|
end
|
|
|
|
it 'skips invited members' do
|
|
expect(values).not_to include([invited.name, invited.email])
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|