require 'db/mongo/connectors/project' require 'spec/connectors/tester_connector/project' require_relative 'shared_connectors_context' RSpec.describe Connectors::Project, type: :connector do set_tester_connector TesterConnector::Project include_context 'connectors' let(:model_class) { Devops::Model::Project } include_examples 'mongo connector', { model_name: :project, factory_name: :project, only: [:insert, :show, :delete], field_to_update: :deploy_envs } describe '#is_project_exists?' do subject { @connector.is_project_exists?(build(:project, id: 'foo')) } it 'returns true if project exists' do @tester_connector.create(id: 'foo') do expect(subject).to be true end end it 'returns false if project doesn\'t exists' do expect(subject).to be false end end describe '#projects_all' do it 'returns array of projects' do @tester_connector.create_list(2) do result = @connector.projects_all expect(result).to be_an_array_of(model_class).and have_size(2) end end end describe '#projects', cleanup_after: :all do before(:all) do @tester_connector.create build(:project, id: 'foo', type: 'multi').to_mongo_hash @tester_connector.create build(:project, id: 'bar', archived: true).to_mongo_hash @tester_connector.create build(:project, id: 'baz').to_mongo_hash end it 'returns non archived projects with all params unset' do expect(@connector.projects).to have_size(2) end it 'returns projects with given ids' do result = @connector.projects(%w(foo baz)) expect(result).to be_an_array_of(model_class) expect(result.map(&:id)).to match_array(%w(foo baz)) end it 'returns multi projects if @type == :multi' do expect( @connector.projects(nil, :multi).map(&:id) ).to match_array ['foo'] end it 'returns only given fields and id if @fields is set' do result = @connector.projects(nil, nil, [:deploy_envs]) expect(result.map(&:id).compact).not_to eq [] expect(result.map(&:deploy_envs).compact).not_to eq [] expect(result.map(&:description).compact).to eq [] end it 'returns only archived projects if @archived=true' do result = @connector.projects(nil, nil, [], true) expect(result.map(&:id)).to match_array(%w(bar)) end end describe '#project_names_with_envs', cleanup_after: :all do before(:all) do @tester_connector.create( id: 'foo', deploy_envs: [{identifier: 'env1'}, {identifier: 'env2'}] ) @tester_connector.create( id: 'bar', deploy_envs: [{identifier: 'env3'}, {identifier: 'env4'}] ) end it 'returns hash like {"project_name" => ["env1", "env2]}' do result = @connector.project_names_with_envs expect(result.keys.sort).to match_array %w(foo bar) expect(result['foo'].sort).to match_array %w(env1 env2) expect(result['bar'].sort).to match_array %w(env3 env4) end it 'returns only projects with given names' do expect(@connector.project_names_with_envs(['bar']).keys).to match_array %w(bar) end end describe '#projects_by_image', cleanup_after: :each do def env(image) {image: image, provider: 'ec2'} end it 'returns projects deploy_envs of which have given image' do @tester_connector.create(id: 'foo', deploy_envs: [env('a'), env('b')]) @tester_connector.create(id: 'bar', deploy_envs: [env('a'), env('a')]) @tester_connector.create(id: 'baz', deploy_envs: [env('b'), env('b')]) result = @connector.projects_by_image('a') expect(result).to be_an_array_of(model_class) expect(result.map(&:id)).to match_array %w(foo bar) end end describe '#projects_by_user', cleanup_after: :each do def env(users) {users: users, provider: 'ec2'} end it 'returns projects deploy_envs of which have given user' do @tester_connector.create(id: 'foo', deploy_envs: [ env(%w(user1 user2)) ]) @tester_connector.create(id: 'bar', deploy_envs: [ env(%w(user1 user1)) ]) @tester_connector.create(id: 'baz', deploy_envs: [ env(%w(user2 user2)) ]) @tester_connector.create(id: 'baf', deploy_envs: [ env(%w(user1)), env(%w(user2)) ]) result = @connector.projects_by_user('user1') expect(result).to be_an_array_of(model_class) expect(result.map(&:id)).to match_array %w(foo bar baf) end end describe '#archive_project' do it 'sets archived to true' do @tester_connector.create(id: 'foo') do @connector.archive_project('foo') expect(@tester_connector.show('foo')).to include('archived' => true) end end end describe '#unarchive_project' do it 'unsets archived' do @tester_connector.create(id: 'foo', archived: true) do @connector.unarchive_project('foo') expect(@tester_connector.show('foo')).not_to include('archived') end end end describe '#check_project_auth', cleanup_after: :all do before(:all) do @tester_connector.create(id: 'foo', deploy_envs: [ {identifier: 'bar', provider: 'ec2', users: %w(user1)} ]) end it "raises InvalidPrivileges if given env users don't include given user" do expect { @connector.check_project_auth('foo', 'bar', 'user2') }.to raise_error(InvalidPrivileges) end it "returns project if env's users include given user" do result = @connector.check_project_auth('foo', 'bar', 'user1') expect(result).to be_an_instance_of(model_class) expect(result.id).to eq 'foo' end end describe '#projects_and_deploy_envs_by_field', cleanup_after: :all do def env(field, value) {provider: 'ec2', field => value} end before(:all) do @tester_connector.create(id: 'foo', deploy_envs: [ env(:image, 'image1'), env(:stack_template, 'template1') ]) end it 'returns projects with deploy envs containing given field with given value' do expect( @connector.projects_and_deploy_envs_by_field(:image, 'image1').map(&:id) ).to match_array %w(foo) expect( @connector.projects_and_deploy_envs_by_field(:stack_template, 'template1').map(&:id) ).to match_array %w(foo) end end describe '#set_project_deploy_env_field', cleanup_after: :each do it 'updates given env from given field_value_hash' do @tester_connector.create(id: 'foo', deploy_envs: [ {identifier: 'bar', provider: 'ec2'} ]) @connector.set_project_deploy_env_field('foo', 'bar', image: 'a', stack_template: 'b') updated_project = @tester_connector.show('foo') expect(updated_project['deploy_envs'].first['image']).to eq 'a' expect(updated_project['deploy_envs'].first['stack_template']).to eq 'b' end end describe '#set_project_env_run_list', cleanup_after: :all do before(:all) do @tester_connector.create(id: 'foo', deploy_envs: [{identifier: 'bar', provider: 'ec2'}]) end before { allow_any_instance_of(Validators::Helpers::RunList).to receive(:validate!) } it 'validates run list' do run_list = [] expect_any_instance_of(Validators::Helpers::RunList).to receive(:validate!) @connector.set_project_env_run_list('foo', 'bar', run_list) end it "updates env's RunList" do run_list = ['role[foo]'] @connector.set_project_env_run_list('foo', 'bar', run_list) expect(@tester_connector.show('foo')['deploy_envs'].first['run_list']).to eq run_list end end describe '#set_project_env_run_list', cleanup_after: :all do before(:all) do @tester_connector.create(id: 'foo') end before { allow_any_instance_of(Validators::Helpers::RunList).to receive(:validate!) } it 'validates run list' do run_list = [] expect_any_instance_of(Validators::Helpers::RunList).to receive(:validate!) @connector.set_project_run_list('foo', run_list) end it "updates project's RunList" do run_list = ['role[foo]'] @connector.set_project_run_list('foo', run_list) expect(@tester_connector.show('foo')['run_list']).to eq run_list end end describe '#add_deploy_env_to_project' do it 'adds env to project' do @tester_connector.create(id: 'foo', deploy_envs: []) do @connector.add_deploy_env_to_project('foo', build(:deploy_env)) expect(@tester_connector.show('foo')['deploy_envs']).not_to be_empty end end end describe '#remove_deploy_env_from_project', cleanup_after: :each do before { @tester_connector.create(id: 'foo', deploy_envs: [{identifier: 'bar'}]) } it "removes env from project" do @connector.remove_deploy_env_from_project('foo', 'bar') expect(@tester_connector.show('foo')['deploy_envs']).to be_empty end it 'raises ArgumentError if given env is not a String' do env = build(:deploy_env_ec2, identifier: 'bar') expect { @connector.remove_deploy_env_from_project('foo', env) }.to raise_error(ArgumentError) end end describe '#project_update_field', cleanup_after: :each do before { @tester_connector.create(id: 'foo', description: 'desc', run_list: []) } subject { @connector.project_update_field('foo', 'run_list', ['role[a]']) } it 'updates given field of given project' do expect {subject}.to change { @tester_connector.show('foo')['run_list'] }.to ['role[a]'] end it "doesn't affect other fields" do expect {subject}.not_to change { @tester_connector.show('foo')['desc'] } end end describe '#project_update', cleanup_after: :each do before { @tester_connector.create(id: 'foo', deploy_envs: [], description: 'desc', run_list: []) } subject { attrs = {'id' => 'foo2', 'deploy_envs' => [build(:deploy_env)], 'description' => 'desc2', 'run_list' => ['role[asd]']} @connector.project_update('foo', attrs) } let(:updated_project) { @tester_connector.show('foo') } it 'can update run_list and description' do subject expect(updated_project['run_list']).to eq ['role[asd]'] expect(updated_project['description']).to eq 'desc2' end it 'can not update other fields' do subject expect(updated_project['_id']).to eq 'foo' expect(updated_project['deploy_envs']).to eq [] end end end