From 2825eee48e155cb44fc345c38cff2e57192254f4 Mon Sep 17 00:00:00 2001 From: Anton Chuchkalov Date: Mon, 7 Dec 2015 13:04:35 +0300 Subject: [PATCH 1/3] more specs --- devops-service/db/mongo/models/project.rb | 1 + devops-service/spec/models/project_spec.rb | 86 ++++++++++++++++++- .../spec/models/shared_models_context.rb | 7 ++ 3 files changed, 91 insertions(+), 3 deletions(-) diff --git a/devops-service/db/mongo/models/project.rb b/devops-service/db/mongo/models/project.rb index a4a4a23..36abbc2 100644 --- a/devops-service/db/mongo/models/project.rb +++ b/devops-service/db/mongo/models/project.rb @@ -146,6 +146,7 @@ module Devops h end + # TODO: why symbols here? def to_hash_list { name: self.id, diff --git a/devops-service/spec/models/project_spec.rb b/devops-service/spec/models/project_spec.rb index bed0128..9d259c1 100644 --- a/devops-service/spec/models/project_spec.rb +++ b/devops-service/spec/models/project_spec.rb @@ -235,9 +235,9 @@ RSpec.describe Devops::Model::Project, type: :model do end describe '#delete_deploy_env' do - it 'removes env' do - allow(Devops::Db).to receive_message_chain('connector.remove_deploy_env_from_project') - expect(Devops::Db).to receive_message_chain('connector.remove_deploy_env_from_project').with(project.id, 'foo') + 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 @@ -271,4 +271,84 @@ RSpec.describe Devops::Model::Project, type: :model do 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 + + # 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 + end \ No newline at end of file diff --git a/devops-service/spec/models/shared_models_context.rb b/devops-service/spec/models/shared_models_context.rb index fe5e754..a0f1fa6 100644 --- a/devops-service/spec/models/shared_models_context.rb +++ b/devops-service/spec/models/shared_models_context.rb @@ -19,3 +19,10 @@ RSpec.shared_context 'stubbed calls to logger', stub_logger: true do allow(DevopsLogger).to receive_message_chain('logger.error') end end + +RSpec.shared_context 'stubbed calls to connector', stubbed_connector: true do + let(:stubbed_connector) { double() } + before do + allow(Devops::Db).to receive(:connector) { stubbed_connector } + end +end \ No newline at end of file From a19ca959dfdad5eee95a955a39e1028490ee4cf3 Mon Sep 17 00:00:00 2001 From: Anton Chuchkalov Date: Tue, 8 Dec 2015 16:35:53 +0300 Subject: [PATCH 2/3] complete project specs --- devops-service/db/mongo/models/project.rb | 1 + devops-service/spec/models/project_spec.rb | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/devops-service/db/mongo/models/project.rb b/devops-service/db/mongo/models/project.rb index 36abbc2..c4edc04 100644 --- a/devops-service/db/mongo/models/project.rb +++ b/devops-service/db/mongo/models/project.rb @@ -208,6 +208,7 @@ module Devops Project.new p end + # maybe it worth to move components functionality to devops-nibr? #TODO: create validator def validate_components raise InvalidRecord.new "Components is not a hash" unless self.components.is_a?(Hash) diff --git a/devops-service/spec/models/project_spec.rb b/devops-service/spec/models/project_spec.rb index 9d259c1..f150081 100644 --- a/devops-service/spec/models/project_spec.rb +++ b/devops-service/spec/models/project_spec.rb @@ -344,6 +344,7 @@ RSpec.describe Devops::Model::Project, type: :model do 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' => {}} @@ -351,4 +352,12 @@ RSpec.describe Devops::Model::Project, type: :model do # 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 \ No newline at end of file From e70ff0b832b41f766ff8b966fc083a6fb932fb0e Mon Sep 17 00:00:00 2001 From: Anton Chuchkalov Date: Tue, 8 Dec 2015 16:36:16 +0300 Subject: [PATCH 3/3] add specs for provider accounts; find bug with providers --- .../openstack_provider_account.rb | 1 + .../spec/factories/provider_account.rb | 25 +++++++ .../ec2_provider_account_spec.rb | 71 +++++++++++++++++++ .../openstack_provider_account_spec.rb | 13 ++++ 4 files changed, 110 insertions(+) create mode 100644 devops-service/spec/factories/provider_account.rb create mode 100644 devops-service/spec/models/provider_account/ec2_provider_account_spec.rb create mode 100644 devops-service/spec/models/provider_account/openstack_provider_account_spec.rb diff --git a/devops-service/db/mongo/models/provider_accounts/openstack_provider_account.rb b/devops-service/db/mongo/models/provider_accounts/openstack_provider_account.rb index 9aa6ca2..ef723ac 100644 --- a/devops-service/db/mongo/models/provider_accounts/openstack_provider_account.rb +++ b/devops-service/db/mongo/models/provider_accounts/openstack_provider_account.rb @@ -17,6 +17,7 @@ module Devops def initialize a={} super(a) + self.provider = Provider::Openstack::PROVIDER self.username = a["username"] self.auth_url = a["auth_url"] self.tenant = a["tenant"] diff --git a/devops-service/spec/factories/provider_account.rb b/devops-service/spec/factories/provider_account.rb new file mode 100644 index 0000000..f239513 --- /dev/null +++ b/devops-service/spec/factories/provider_account.rb @@ -0,0 +1,25 @@ +require 'db/mongo/models/provider_accounts/ec2_provider_account' +require 'db/mongo/models/provider_accounts/openstack_provider_account' +require 'db/mongo/models/provider_accounts/static_provider_account' + +FactoryGirl.define do + factory :provider_account, class: Devops::Model::ProviderAccount do + account_name 'name' + description 'desc' + ssh_key 'user_key' + + + factory :static_provider_account, class: Devops::Model::StaticProviderAccount do + end + + factory :ec2_provider_account, class: Devops::Model::Ec2ProviderAccount do + provider 'ec2' + access_key_id 'access' + secret_access_key 'secret' + end + + factory :openstack_provider_account, class: Devops::Model::OpenstackProviderAccount do + provider 'openstack' + end + end +end \ No newline at end of file diff --git a/devops-service/spec/models/provider_account/ec2_provider_account_spec.rb b/devops-service/spec/models/provider_account/ec2_provider_account_spec.rb new file mode 100644 index 0000000..2d9c33f --- /dev/null +++ b/devops-service/spec/models/provider_account/ec2_provider_account_spec.rb @@ -0,0 +1,71 @@ +require 'spec_helper' +require_relative '../shared_models_context' + +RSpec.describe Devops::Model::Ec2ProviderAccount, type: :model do + let(:provider_account) { build(:ec2_provider_account) } + + + describe 'validation rules', stubbed_connector: true do + before do + allow(Provider::ProviderFactory).to receive(:providers).and_return(%w(ec2 openstack)) + allow(stubbed_connector).to receive(:key) + end + + it 'set validators' do + expect(provider_account).to respond_to(:validate_access_key_id!) + end + + it 'is valid with valid attrs' do + provider_account.validate! + expect(provider_account).to be_valid + end + + include_examples 'field type validation', :account_name, :not_nil, :non_empty_string + include_examples 'field type validation', :description, :maybe_nil, :non_empty_string + include_examples 'field type validation', :ssh_key, :not_nil, :non_empty_string + include_examples 'field type validation', :access_key_id, :not_nil, :non_empty_string + include_examples 'field type validation', :secret_access_key, :not_nil, :non_empty_string + + it "isn't valid if description length is more than 500" do + provider_account.description = 'a' * 501 + expect(provider_account).not_to be_valid + expect{ provider_account.validate_description! }.to raise_error InvalidRecord + end + + it "isn't valid if keys collection doesn't include given key" do + allow(stubbed_connector).to receive(:key) { raise RecordNotFound} + expect(provider_account).not_to be_valid + end + end + + describe '#initialize' do + it 'sets provider to ec2' do + expect(described_class.new.provider).to eq 'ec2' + end + end + + describe '#to_mongo_hash' do + it 'returns hash with several keys' do + expect( + provider_account.to_mongo_hash.keys + ).to include(*%w(availability_zone access_key_id secret_access_key _id description ssh_key provider)) + end + end + + describe '.build_from_bson' do + subject { described_class.build_from_bson('_id' => 'asd') } + + it 'returns an instance of Devops::Model::Ec2ProviderAccount' do + expect(subject).to be_an_instance_of(described_class) + expect(subject.account_name).to eq 'asd' + end + end + + describe '.account_fields' do + it 'returns hash with several keys' do + expect( + described_class.account_fields.keys + ).to include(*%i(availability_zone access_key_id secret_access_key description ssh_key account_name)) + end + end +end \ No newline at end of file diff --git a/devops-service/spec/models/provider_account/openstack_provider_account_spec.rb b/devops-service/spec/models/provider_account/openstack_provider_account_spec.rb new file mode 100644 index 0000000..18456eb --- /dev/null +++ b/devops-service/spec/models/provider_account/openstack_provider_account_spec.rb @@ -0,0 +1,13 @@ +require 'spec_helper' +require_relative '../shared_models_context' + +# не пытайся выделить в shared_specs, фигня выйдет +RSpec.describe Devops::Model::OpenstackProviderAccount, type: :model do + let(:provider_account) { build(:openstack_provider_account) } + + it "should not validate access_key_id" do + fields = described_class.field_validators.values.flatten.flatten.map{|t| t[:field]} + expect(fields).not_to include(:access_key_id, :secret_access_key) + end + +end \ No newline at end of file