fluke/devops-service/spec/models/project_spec.rb
2016-01-20 14:49:30 +03:00

378 lines
12 KiB
Ruby

require 'db/mongo/models/project'
RSpec.describe Devops::Model::Project, type: :model do
let(:project) { build(:project) }
describe 'validation rules:', stubbed_env_validators: true do
include_examples 'field type validation', :id, :not_nil, :non_empty_string
include_examples 'field type validation', :deploy_envs, :not_nil, :non_empty_array
include_examples 'field type validation', :description, :maybe_nil, :maybe_empty_string
include_examples 'field type validation', :run_list, :not_nil, :maybe_empty_array, :run_list
it "isn't valid when has envs with same identifier" do
project = build(:project, with_deploy_env_identifiers: %w(foo foo))
expect(project).not_to be_valid
end
it "is valid when all envs have uniq identifiers" do
project = build(:project, with_deploy_env_identifiers: %w(foo bar))
expect(project).to be_valid
end
it "isn't valid when at least one of envs isn't valid" do
project = build(:project, with_deploy_env_identifiers: ['foo', nil])
expect(project).not_to be_valid
end
describe 'components validation' do
it 'is valid with components with filenames' do
project.components = {'foo' => {'filename' => 'bar'}}
expect{project.validate_components}.not_to raise_error
end
it "isn't valid if components isn't a hash" do
project.components = []
expect{project.validate_components}.to raise_error InvalidRecord
end
it "raises InvalidRecord if one of componentsц hasn't filename" do
project.components = {'foo' => {}}
expect{project.validate_components}.to raise_error InvalidRecord
end
end
end
describe '.fields' do
subject { described_class.fields }
it { should eq %w(deploy_envs type description) }
end
describe '#initialize' do
it 'sets @type to generic by default' do
expect(described_class.new.type).to eq 'generic'
end
it 'sets @archived to false by default' do
expect(described_class.new.archived).to eq false
end
it 'sets run_list to empty_array by default' do
expect(described_class.new.run_list).to eq []
end
describe 'deploy envs building' do
let(:params) { {'deploy_envs' => [ {'provider' => @env_provider, 'identifier' => 'foo'} ]} }
it 'builds envs array from given params' do
@env_provider = 'ec2'
expect(
described_class.new(params).deploy_envs
).to be_an_array_of(Devops::Model::DeployEnvEc2).and have_size(1)
end
it 'builds ec2 deploy envs from given params' do
@env_provider = 'ec2'
builded_env = described_class.new(params).deploy_envs.first
expect(builded_env).to be_a(Devops::Model::DeployEnvEc2)
expect(builded_env.identifier).to eq 'foo'
end
it 'build openstack deploy envs from given params' do
@env_provider = 'openstack'
builded_env = described_class.new(params).deploy_envs.first
expect(builded_env).to be_a(Devops::Model::DeployEnvOpenstack)
end
it 'build static deploy envs from given params' do
@env_provider = 'static'
builded_env = described_class.new(params).deploy_envs.first
expect(builded_env).to be_a(Devops::Model::DeployEnvStatic)
end
end
end
describe '#deploy_env' do
let(:project) { project = build(:project, with_deploy_env_identifiers: %w(foo bar)) }
it 'returns found env' do
expect(project.deploy_env('bar')).to be_an(Devops::Model::DeployEnvEc2)
end
it 'raises RecordNotFound if there is no such env' do
expect {
project.deploy_env('missing')
}.to raise_error RecordNotFound
end
end
describe '#add_deploy_env', stubbed_logger: true do
let(:env) {build(:deploy_env_ec2)}
subject { project.add_deploy_env(env) }
before do
allow(Devops::Db).to receive_message_chain('connector.add_deploy_env_to_project')
end
it 'inserts deploy env into mongo via connector' do
expect(
Devops::Db
).to receive_message_chain('connector.add_deploy_env_to_project').with(project.id, env)
subject
end
it 'creates chef role' do
expect(env).to receive(:create_role).with(project.id)
subject
end
it 'returns string' do
expect(subject).to be_a(String)
end
end
describe '#add_authorized_user' do
before do
allow(Devops::Db).to receive_message_chain('connector.set_project_deploy_env_field')
end
let(:env1) { build(:deploy_env_ec2, identifier: 'foo') }
let(:env2) { build(:deploy_env_ec2, identifier: 'bar') }
let(:project) { build(:project, deploy_envs: [env1, env2]) }
it 'returns nil if user is nil' do
expect(project.add_authorized_user(nil)).to be_nil
end
context "when env isn't given" do
context 'when user is a String' do
it 'adds given user to all envs' do
project.add_authorized_user('John')
expect(env1.users).to match_array(%w(root John))
expect(env2.users).to match_array(%w(root John))
end
end
context 'when user is an Array of strings' do
it 'adds given users to all envs' do
project.add_authorized_user(['John', 'Matz'])
expect(env1.users).to match_array(%w(root John Matz))
expect(env2.users).to match_array(%w(root John Matz))
end
end
end
context 'when env is given' do
context 'when user is a String' do
it 'adds given user to given env' do
project.add_authorized_user('John', 'bar')
expect(env1.users).to match_array(%w(root))
expect(env2.users).to match_array(%w(root John))
end
end
context 'when user is an Array of strings' do
it 'adds given users to all envs' do
project.add_authorized_user(['John', 'Matz'], 'bar')
expect(env1.users).to match_array(%w(root))
expect(env2.users).to match_array(%w(root John Matz))
end
end
end
end
describe '#remove_authorized_user' do
before do
allow(Devops::Db).to receive_message_chain('connector.set_project_deploy_env_field')
end
let(:env1) { build(:deploy_env_ec2, identifier: 'foo', users: %w(root John Matz)) }
let(:env2) { build(:deploy_env_ec2, identifier: 'bar', users: %w(root John Matz)) }
let(:project) { build(:project, deploy_envs: [env1, env2]) }
it 'returns nil if user is nil' do
expect(project.remove_authorized_user(nil)).to be_nil
end
context "when env isn't given" do
context 'when user is a String' do
it 'adds given user to all envs' do
project.remove_authorized_user('John')
expect(env1.users).to match_array(%w(root Matz))
expect(env2.users).to match_array(%w(root Matz))
end
end
context 'when user is an Array of strings' do
it 'adds given users to all envs' do
project.remove_authorized_user(['John', 'Matz'])
expect(env1.users).to match_array(%w(root))
expect(env2.users).to match_array(%w(root))
end
end
end
context 'when env is given' do
context 'when user is a String' do
it 'adds given user to given env' do
project.remove_authorized_user('John', 'bar')
expect(env1.users).to match_array(%w(root John Matz))
expect(env2.users).to match_array(%w(root Matz))
end
end
context 'when user is an Array of strings' do
it 'adds given users to all envs' do
project.remove_authorized_user(['John', 'Matz'], 'bar')
expect(env1.users).to match_array(%w(root John Matz))
expect(env2.users).to match_array(%w(root))
end
end
end
end
describe '#check_authorization' do
subject { project.check_authorization(@user || 'Matz', 'foo') }
it 'returns true for root user' do
@user = 'root'
expect(subject).to be true
end
it "returns false if env's users don't include given user" do
expect(subject).to be false
end
it "returns true if env's users include given user" do
project.deploy_env('foo').users = %w(root Matz)
expect(subject).to be true
end
it 'returns false if there is no such env' do
expect(project.check_authorization('root', 'wrong')).to be false
end
end
describe '#delete_deploy_env' do
it 'removes env', stubbed_connector: true do
allow(stubbed_connector).to receive(:remove_deploy_env_from_project)
expect(stubbed_connector).to receive(:remove_deploy_env_from_project).with(project.id, 'foo')
project.delete_deploy_env('foo')
expect(project.deploy_envs).to match_array []
end
end
describe '#to_hash' do
subject { project.to_hash }
it 'returns hash' do
expect(subject).to be_a(Hash)
end
it 'contains project id under name key' do
expect(subject['name']).to eq project.id
end
it 'contains deploy_envs converted to hashes' do
expect(subject['deploy_envs']).to be_an_array_of(Hash)
end
it 'also contains descriptions and run_list' do
expect(subject).to include('description', 'run_list')
end
it 'contains archived key if project is archived' do
project.archived = true
expect(subject).to include('archived')
end
it "doesn't contain archived if project isn't archived" do
expect(subject).not_to include('archived')
end
end
describe '#to_hash_list' do
it 'returns hash' do
expect(project.to_hash_list).to be_a(Hash)
end
end
describe '#deploy_info' do
subject { project.deploy_info(project.deploy_env('foo')) }
it 'returns hash' do
expect(subject).to be_a(Hash)
end
it 'includes use_json_file, project and project_info' do
expect(subject).to include('use_json_file', 'project', 'project_info')
expect(subject['project_info']).to be_a(Hash)
end
end
describe '#to_hash_without_id' do
subject { project.to_hash_without_id }
it 'returns a hash' do
expect(subject).to be_a(Hash)
end
it "doesn't include id or name" do
expect(subject).not_to include('id', 'name')
end
end
describe '#create', stubbed_connector: true do
before do
allow(stubbed_connector).to receive(:project_insert)
end
subject { project.create }
it 'run hooks' do
expect(project).to receive(:run_hook).with(:before_create).ordered
expect(project).to receive(:run_hook).with(:after_create).ordered
subject
end
it 'inserts record into DB' do
expect(stubbed_connector).to receive(:project_insert).with(project)
subject
end
it 'returns a hash' do
expect(subject).to be_a(Hash)
end
end
describe '#delete', stubbed_connector: true do
before do
allow(stubbed_connector).to receive(:project_delete)
end
subject { project.delete }
it 'run hooks' do
expect(project).to receive(:run_hook).with(:before_delete).ordered
expect(project).to receive(:run_hook).with(:after_delete).ordered
subject
end
it 'deletes record into DB' do
expect(stubbed_connector).to receive(:project_delete).with(project.id)
subject
end
it 'returns a hash' do
expect(subject).to be_a(Hash)
end
end
# maybe it worth to move components functionality to devops-nibr?
# describe '#validate_components' do
# it "raises InvalidRecord if one of component doesn't include filename" do
# project.components = {'name' => {}}
# expect{project.validate_components}.to raise_error(InvalidRecord)
# end
# end
describe '.create_roles_response' do
it 'returns string' do
expect(described_class.create_roles_response('string')).to be_a(String)
hash = {new: %w(a), exist: %w(b), error: %w(c)}
expect(described_class.create_roles_response(hash)).to be_a(String)
end
end
end