175 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
		
		
			
		
	
	
			175 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
|   | require 'db/mongo/models/stack/stack_ec2' | ||
|  | 
 | ||
|  | RSpec.describe Devops::Model::StackEc2, type: :model do | ||
|  |   let(:stack) { build(:stack_ec2) } | ||
|  | 
 | ||
|  |   before do | ||
|  |     allow(Provider::ProviderFactory).to receive(:providers).and_return(%w(ec2)) | ||
|  |   end | ||
|  | 
 | ||
|  |   it 'is valid with factory attrs' do | ||
|  |     expect(build(:stack_ec2)).to be_valid | ||
|  |   end | ||
|  | 
 | ||
|  |   describe 'validation rules:' do | ||
|  |     include_examples 'field type validation', :id, :not_nil, :non_empty_string, :field_validator | ||
|  |     include_examples 'field type validation', :project, :not_nil, :non_empty_string, :field_validator | ||
|  |     include_examples 'field type validation', :deploy_env, :not_nil, :non_empty_string, :field_validator | ||
|  |     include_examples 'field type validation', :stack_template, :not_nil, :non_empty_string, :field_validator | ||
|  |     include_examples 'field type validation', :name, :maybe_nil, :non_empty_string, :field_validator | ||
|  |     include_examples 'field type validation', :owner, :not_nil, :non_empty_string, :field_validator | ||
|  |     include_examples 'field type validation', :run_list, :maybe_nil, :maybe_empty_array, :run_list, :field_validator | ||
|  | 
 | ||
|  |     it 'validates provider' do | ||
|  |       stack.provider = nil | ||
|  |       expect(stack).not_to be_valid | ||
|  | 
 | ||
|  |       stack.provider = '' | ||
|  |       expect(stack).not_to be_valid | ||
|  |     end | ||
|  |   end | ||
|  | 
 | ||
|  |   describe '#to_hash_without_id' do | ||
|  |     it 'returns hash with several fields' do | ||
|  |       expect(stack.to_hash_without_id.keys).to include('provider', :project, :deploy_env, :stack_template, :name, :owner, :run_list) | ||
|  |     end | ||
|  |   end | ||
|  | 
 | ||
|  |   describe '#initialize' do | ||
|  |     it 'sets provider to ec2 even if given attrs don\'t contain it' do | ||
|  |       expect(described_class.new.provider).to eq 'ec2' | ||
|  |     end | ||
|  | 
 | ||
|  |     it 'sets run_list to empty array if it\'s blank' do | ||
|  |       expect(described_class.new.run_list).to eq [] | ||
|  |     end | ||
|  |   end | ||
|  | 
 | ||
|  |   describe '#bson_safe_details' do | ||
|  |     it 'stringify value of CreationTime key' do | ||
|  |       stack.details = {'CreationTime' => Time.now} | ||
|  |       expect(stack.bson_safe_details['CreationTime']).to be_a(String) | ||
|  |     end | ||
|  |   end | ||
|  | 
 | ||
|  |   describe '#create_stack_in_cloud!' do | ||
|  |     it 'calls create_stack method of provider instance' do | ||
|  |       expect(stack).to receive_message_chain('provider_instance.create_stack') | ||
|  |       stack.create_stack_in_cloud!('') | ||
|  |     end | ||
|  | 
 | ||
|  |     it 'raises InvalidRecord if stack with such name already exists in cloud' do | ||
|  |       allow(stack).to receive_message_chain('provider_instance.create_stack').and_raise(ProviderErrors::NameConflict) | ||
|  |       expect { stack.create_stack_in_cloud!('') }.to raise_error(InvalidRecord) | ||
|  |     end | ||
|  |   end | ||
|  | 
 | ||
|  |   describe '#delete_stack_in_cloud!' do | ||
|  |     it 'calls delete_stack method of provider instance' do | ||
|  |       expect(stack).to receive_message_chain('provider_instance.delete_stack').with(stack) | ||
|  |       stack.delete_stack_in_cloud! | ||
|  |     end | ||
|  |   end | ||
|  | 
 | ||
|  |   describe '#template_body' do | ||
|  |     it 'is a String' do | ||
|  |       allow(Devops::Db).to receive_message_chain('connector.stack_template.template_body') {'body'} | ||
|  |       expect(stack.template_body).to be_a(String) | ||
|  |     end | ||
|  |   end | ||
|  | 
 | ||
|  | 
 | ||
|  |   describe '#sync_details!' do | ||
|  |     let(:stack_with_blank_info) { stack.details = nil; stack.events=nil; stack } | ||
|  |     let(:fresh_details) { {'StackStatus' => 'CREATE_COMPLETE'} } | ||
|  |     let(:fresh_events) { [] } | ||
|  |     subject { stack_with_blank_info.sync_details! } | ||
|  | 
 | ||
|  |     before do | ||
|  |       allow(stack_with_blank_info).to receive_message_chain('provider_instance.stack_details') {fresh_details} | ||
|  |       allow(stack_with_blank_info).to receive_message_chain('provider_instance.stack_events') {fresh_events} | ||
|  |     end | ||
|  | 
 | ||
|  |     it "get fresh stack details and stores it in @details" do | ||
|  |       expect(stack_with_blank_info).to receive_message_chain('provider_instance.stack_details') | ||
|  |       subject | ||
|  |       expect(stack_with_blank_info.details).to eq fresh_details | ||
|  |     end | ||
|  | 
 | ||
|  |     it "get fresh stack events and stores it in @events" do | ||
|  |       expect(stack_with_blank_info).to receive_message_chain('provider_instance.stack_events') | ||
|  |       subject | ||
|  |       expect(stack_with_blank_info.events).to eq fresh_events | ||
|  |     end | ||
|  | 
 | ||
|  |     it 'updates stack status' do | ||
|  |       subject | ||
|  |       expect(stack_with_blank_info.stack_status).to eq 'CREATE_COMPLETE' | ||
|  |     end | ||
|  |   end | ||
|  | 
 | ||
|  |   describe '#update_in_cloud!' do | ||
|  |     before { allow(stack).to receive_message_chain('provider_instance.update_stack') } | ||
|  | 
 | ||
|  |     it 'calls to method update_stack of provider instance' do | ||
|  |       expect(stack).to receive_message_chain('provider_instance.update_stack') | ||
|  |       stack.update_in_cloud!({}) | ||
|  |     end | ||
|  | 
 | ||
|  |     it 'filters params to include only Parameters, TemplateBody, TemplateURL and Capabilities' do | ||
|  |       permitted_keys = %w(Parameters TemplateBody TemplateURL Capabilities) | ||
|  |       permitted_hash = permitted_keys.inject({}) {|hash, key| hash[key] = 1; hash} | ||
|  |       unfiltered_hash = permitted_hash.merge('wrong' => 1) | ||
|  |       expect(stack).to receive_message_chain('provider_instance.update_stack').with(stack, permitted_hash) | ||
|  |       stack.update_in_cloud!(unfiltered_hash) | ||
|  |     end | ||
|  |   end | ||
|  | 
 | ||
|  |   describe '#change_stack_template!' do | ||
|  |     let(:new_template) { 'brand_new_template' } | ||
|  |     before do | ||
|  |       allow(stack).to receive(:template_body) | ||
|  |       allow(stack).to receive(:update_in_cloud!) | ||
|  |       allow(Devops::Db).to receive_message_chain('connector.stack_update') | ||
|  |     end | ||
|  | 
 | ||
|  |     it 'updates stack_template' do | ||
|  |       stack.change_stack_template!(new_template) | ||
|  |       expect(stack.stack_template).to eq new_template | ||
|  |     end | ||
|  |   end | ||
|  | 
 | ||
|  |   describe '.create' do | ||
|  |     subject { described_class.create({}, '') } | ||
|  | 
 | ||
|  |     before do | ||
|  |       allow_any_instance_of(described_class).to receive(:create_stack_in_cloud!) | ||
|  |       allow_any_instance_of(described_class).to receive(:sync_details!) | ||
|  |     end | ||
|  | 
 | ||
|  |     it "returns instance of #{described_class.name}" do | ||
|  |       expect(subject).to be_a(described_class) | ||
|  |     end | ||
|  | 
 | ||
|  |     it 'creates stack in AWS' do | ||
|  |       expect_any_instance_of(described_class).to receive(:create_stack_in_cloud!) | ||
|  |       subject | ||
|  |     end | ||
|  | 
 | ||
|  |     it 'synchronizes details' do | ||
|  |       expect_any_instance_of(described_class).to receive(:sync_details!) | ||
|  |       subject | ||
|  |     end | ||
|  |   end | ||
|  | 
 | ||
|  |   describe '.build_from_bson' do | ||
|  |     subject { described_class.build_from_bson('_id' => 'foo', 'name' => 'bar') } | ||
|  |     it "returns instance of #{described_class.name} with given parameters" do | ||
|  |       expect(subject.id).to eq 'foo' | ||
|  |       expect(subject.name).to eq 'bar' | ||
|  |     end | ||
|  |   end | ||
|  | 
 | ||
|  | end | ||
|  | 
 |