summaryrefslogtreecommitdiff
path: root/qa/spec/factory
diff options
context:
space:
mode:
Diffstat (limited to 'qa/spec/factory')
-rw-r--r--qa/spec/factory/api_fabricator_spec.rb61
-rw-r--r--qa/spec/factory/base_spec.rb205
-rw-r--r--qa/spec/factory/product_spec.rb60
3 files changed, 113 insertions, 213 deletions
diff --git a/qa/spec/factory/api_fabricator_spec.rb b/qa/spec/factory/api_fabricator_spec.rb
index 3fda5407549..8f8c29dd92d 100644
--- a/qa/spec/factory/api_fabricator_spec.rb
+++ b/qa/spec/factory/api_fabricator_spec.rb
@@ -27,26 +27,12 @@ describe QA::Factory::ApiFabricator do
end
end
- subject { factory.tap { |f| f.include(described_class) }.new }
-
- describe '#api_support?' do
- context 'when factory does not respond to api_get_path, api_post_path, and api_post_body' do
- let(:factory) { factory_without_api_support }
-
- it 'returns false' do
- expect(subject).not_to be_api_support
- end
- end
-
- context 'when factory responds to api_get_path, api_post_path, and api_post_body' do
- let(:factory) { factory_with_api_support }
-
- it 'returns true' do
- expect(subject).to be_api_support
- end
- end
+ before do
+ allow(subject).to receive(:current_url).and_return('')
end
+ subject { factory.tap { |f| f.include(described_class) }.new }
+
describe '#fabricate_via_api!' do
context 'when factory does not support fabrication via the API' do
let(:factory) { factory_without_api_support }
@@ -63,7 +49,7 @@ describe QA::Factory::ApiFabricator do
let(:api_request) { spy('Runtime::API::Request') }
let(:resource_web_url) { 'http://example.org/api/v4/foo' }
let(:resource) { { id: 1, name: 'John Doe', web_url: resource_web_url } }
- let(:raw_get) { double('Raw GET response', code: 200, body: resource.to_json) }
+ let(:raw_post) { double('Raw POST response', code: 201, body: resource.to_json) }
before do
stub_const('QA::Runtime::API::Client', api_client)
@@ -71,44 +57,15 @@ describe QA::Factory::ApiFabricator do
allow(api_client).to receive(:new).and_return(api_client_instance)
allow(api_request).to receive(:new).and_return(double(url: resource_web_url))
- allow(subject).to receive(:get).with(resource_web_url).and_return(raw_get)
- end
-
- context 'when resource already exists' do
- it 'returns the resource URL' do
- expect(api_request).to receive(:new).with(api_client_instance, subject.api_get_path).and_return(double(url: resource_web_url))
- expect(subject).to receive(:get).with(resource_web_url).and_return(raw_get)
-
- expect(subject.fabricate_via_api!).to eq(resource_web_url)
- end
-
- it 'populates api_resource with the resource' do
- subject.fabricate_via_api!
-
- expect(subject.api_resource).to eq(resource)
- end
-
- context 'when the resource does not expose a `web_url` property' do
- let(:resource) { { id: 1, name: 'John Doe' } }
-
- it 'raises a ResourceFabricationFailedError exception' do
- expect { subject.fabricate_via_api! }.to raise_error(described_class::ResourceURLMissingError, "API resource for FooBarFactory does not expose a `web_url` property: `#{resource}`.")
- expect(subject.api_resource).to eq(resource)
- end
- end
end
context 'when the resource does not exist' do
- let(:raw_get) { double('Raw GET response', code: 404, body: { error: "404 not found." }.to_json) }
- let(:raw_post) { double('Raw POST response', code: 201, body: resource.to_json) }
-
before do
allow(subject).to receive(:post).with(resource_web_url, subject.api_post_body).and_return(raw_post)
end
it 'returns the resource URL' do
- expect(api_request).to receive(:new).with(api_client_instance, subject.api_get_path).and_return(double(url: resource_web_url))
- expect(subject).to receive(:get).with(resource_web_url).and_return(raw_get)
+ expect(api_request).to receive(:new).with(api_client_instance, subject.api_post_path).and_return(double(url: resource_web_url))
expect(subject).to receive(:post).with(resource_web_url, subject.api_post_body).and_return(raw_post)
expect(subject.fabricate_via_api!).to eq(resource_web_url)
@@ -125,11 +82,10 @@ describe QA::Factory::ApiFabricator do
let(:raw_post) { double('Raw POST response', code: 400, body: post_response.to_json) }
it 'raises a ResourceFabricationFailedError exception' do
- expect(api_request).to receive(:new).with(api_client_instance, subject.api_get_path).and_return(double(url: resource_web_url))
- expect(subject).to receive(:get).with(resource_web_url).and_return(raw_get)
+ expect(api_request).to receive(:new).with(api_client_instance, subject.api_post_path).and_return(double(url: resource_web_url))
expect(subject).to receive(:post).with(resource_web_url, subject.api_post_body).and_return(raw_post)
- expect { subject.fabricate_via_api! }.to raise_error(described_class::ResourceFabricationFailedError, "Fabrication of FooBarFactory using the API failed (400) with `#{post_response}`.")
+ expect { subject.fabricate_via_api! }.to raise_error(described_class::ResourceFabricationFailedError, "Fabrication of FooBarFactory using the API failed (400) with `#{raw_post}`.")
expect(subject.api_resource).to be_nil
end
end
@@ -165,6 +121,7 @@ describe QA::Factory::ApiFabricator do
let(:transformed_resource) { { existing: 'foo', new: 'foobar', web_url: resource_web_url } }
it 'transforms the resource' do
+ expect(subject).to receive(:post).with(resource_web_url, subject.api_post_body).and_return(raw_post)
expect(subject).to receive(:transform_api_resource).with(resource).and_return(transformed_resource)
subject.fabricate_via_api!
diff --git a/qa/spec/factory/base_spec.rb b/qa/spec/factory/base_spec.rb
index 0457d878270..b9cf60e4cc0 100644
--- a/qa/spec/factory/base_spec.rb
+++ b/qa/spec/factory/base_spec.rb
@@ -11,124 +11,107 @@ describe QA::Factory::Base do
subject { Class.new(described_class) }
before do
- allow(QA::Factory::Product).to receive(:new).with(product_location).and_return(product)
- allow(QA::Factory::Product).to receive(:populate!).and_return(product)
allow(subject).to receive(:current_url).and_return(product_location)
allow(subject).to receive(:new).and_return(factory)
+ allow(QA::Factory::Product).to receive(:populate!).with(factory, product_location).and_return(product)
end
end
- shared_examples 'API fabrication method' do |fabrication_method_called, actual_fabrication_method = nil|
+ shared_examples 'fabrication method' do |fabrication_method_called, actual_fabrication_method = nil|
let(:fabrication_method_used) { actual_fabrication_method || fabrication_method_called }
- include_context 'fabrication context'
+ it 'yields factory before calling factory method' do
+ allow(subject).to receive(:new).and_return(factory)
- it_behaves_like 'fabrication method', fabrication_method_called, actual_fabrication_method
+ expect(factory).to receive(:something!).ordered
+ expect(factory).to receive(fabrication_method_used).ordered.and_return(product_location)
- it 'instantiates the factory and calls factory method' do
- expect(subject).to receive(:new).and_return(factory)
+ subject.public_send(fabrication_method_called) do |factory|
+ factory.something!
+ end
+ end
- subject.public_send(fabrication_method_called)
+ it 'does not log the factory and build method when VERBOSE=false' do
+ stub_env('VERBOSE', 'false')
+ expect(factory).to receive(fabrication_method_used).and_return(product_location)
- expect(factory).to have_received(fabrication_method_used)
+ expect { subject.public_send(fabrication_method_called, 'something') }
+ .not_to output(/Resource #{factory.class.name} built via/)
+ .to_stdout
end
+ end
- it 'returns fabrication product' do
- result = subject.public_send(fabrication_method_called)
+ describe '.fabricate!' do
+ context 'when factory does not support fabrication via the API' do
+ before do
+ expect(described_class).to receive(:fabricate_via_api!).and_raise(NotImplementedError)
+ end
+
+ it 'calls .fabricate_via_browser_ui!' do
+ expect(described_class).to receive(:fabricate_via_browser_ui!)
- expect(result).to eq product
+ described_class.fabricate!
+ end
end
- it 'logs the factory and build method when VERBOSE=true' do
- stub_env('VERBOSE', 'true')
+ context 'when factory supports fabrication via the API' do
+ it 'calls .fabricate_via_browser_ui!' do
+ expect(described_class).to receive(:fabricate_via_api!)
- expect { subject.public_send(fabrication_method_called) }
- .to output(/Resource #{factory.class.name} built via do_fabricate_via_api/)
- .to_stdout
+ described_class.fabricate!
+ end
end
end
- shared_examples 'Browser UI fabrication method' do |fabrication_method_called, actual_fabrication_method = nil|
- let(:fabrication_method_used) { actual_fabrication_method || fabrication_method_called }
-
+ describe '.fabricate_via_api!' do
include_context 'fabrication context'
- it_behaves_like 'fabrication method', fabrication_method_called, actual_fabrication_method
-
- it 'instantiates the factory and calls factory method' do
- expect(subject).to receive(:new).and_return(factory)
-
- subject.public_send(fabrication_method_called, 'something')
+ it_behaves_like 'fabrication method', :fabricate_via_api!
- expect(factory).to have_received(fabrication_method_used).with('something')
- end
+ it 'instantiates the factory, calls factory method returns fabrication product' do
+ expect(factory).to receive(:fabricate_via_api!).and_return(product_location)
- it 'returns fabrication product' do
- result = subject.public_send(fabrication_method_called, 'something')
+ result = subject.fabricate_via_api!
- expect(result).to eq product
+ expect(result).to eq(product)
end
it 'logs the factory and build method when VERBOSE=true' do
stub_env('VERBOSE', 'true')
+ expect(factory).to receive(:fabricate_via_api!).and_return(product_location)
- expect { subject.public_send(fabrication_method_called, 'something') }
- .to output(/Resource #{factory.class.name} built via do_fabricate_via_browser_ui/)
+ expect { subject.fabricate_via_api! }
+ .to output(/Resource #{factory.class.name} built via api/)
.to_stdout
end
end
- shared_examples 'fabrication method' do |fabrication_method_called, actual_fabrication_method = nil|
- let(:fabrication_method_used) { actual_fabrication_method || fabrication_method_called }
-
+ describe '.fabricate_via_browser_ui!' do
include_context 'fabrication context'
- it 'yields factory before calling factory method' do
- allow(subject).to receive(:new).and_return(factory)
-
- subject.public_send(fabrication_method_called) do |factory|
- factory.something!
- end
+ it_behaves_like 'fabrication method', :fabricate_via_browser_ui!, :fabricate!
- expect(factory).to have_received(:something!).ordered
- expect(factory).to have_received(fabrication_method_used).ordered
- end
-
- it 'does not log the factory and build method when VERBOSE=false' do
- stub_env('VERBOSE', 'false')
+ it 'instantiates the factory and calls factory method' do
+ subject.fabricate_via_browser_ui!('something')
- expect { subject.public_send(fabrication_method_called, 'something') }
- .not_to output(/Resource #{factory.class.name} built via/)
- .to_stdout
+ expect(factory).to have_received(:fabricate!).with('something')
end
- end
- describe '.fabricate!' do
- context 'when factory does not support fabrication via the API' do
- before do
- allow(factory).to receive(:api_support?).and_return(false)
- end
+ it 'returns fabrication product' do
+ result = subject.fabricate_via_browser_ui!('something')
- it_behaves_like 'Browser UI fabrication method', :fabricate!
+ expect(result).to eq(product)
end
- context 'when factory supports fabrication via the API' do
- before do
- allow(factory).to receive(:api_support?).and_return(true)
- end
+ it 'logs the factory and build method when VERBOSE=true' do
+ stub_env('VERBOSE', 'true')
- it_behaves_like 'API fabrication method', :fabricate!, :fabricate_via_api!
+ expect { subject.fabricate_via_browser_ui!('something') }
+ .to output(/Resource #{factory.class.name} built via browser_ui/)
+ .to_stdout
end
end
- describe '.fabricate_via_api!' do
- it_behaves_like 'API fabrication method', :fabricate_via_api!
- end
-
- describe '.fabricate_via_browser_ui!' do
- it_behaves_like 'Browser UI fabrication method', :fabricate_via_browser_ui!, :fabricate!
- end
-
describe '.dependency' do
let(:dependency) { spy('dependency') }
@@ -168,8 +151,7 @@ describe QA::Factory::Base do
allow(subject).to receive(:new).and_return(instance)
allow(subject).to receive(:current_url).and_return(product_location)
allow(instance).to receive(:mydep).and_return(nil)
- allow(QA::Factory::Product).to receive(:new)
- allow(QA::Factory::Product).to receive(:populate!)
+ expect(QA::Factory::Product).to receive(:populate!)
end
it 'builds all dependencies first' do
@@ -181,79 +163,22 @@ describe QA::Factory::Base do
end
describe '.product' do
- context 'when the product is produced via the browser' do
- subject do
- Class.new(described_class) do
- def fabricate!
- "any"
- end
-
- # Defined only to be stubbed
- def self.find_page
- end
-
- product :token do
- find_page.do_something_on_page!
- 'resulting value'
- end
- end
- end
-
- it 'appends new product attribute' do
- expect(subject.attributes).to be_one
- expect(subject.attributes).to have_key(:token)
- end
-
- describe 'populating fabrication product with data' do
- let(:page) { spy('page') }
+ include_context 'fabrication context'
- before do
- allow(QA::Factory::Product).to receive(:new).and_return(product)
- allow(product).to receive(:page).and_return(page)
- allow(subject).to receive(:current_url).and_return(product_location)
- allow(subject).to receive(:find_page).and_return(page)
+ subject do
+ Class.new(described_class) do
+ def fabricate!
+ "any"
end
- it 'populates product after fabrication' do
- subject.fabricate!
-
- expect(product.token).to eq 'resulting value'
- expect(page).to have_received(:do_something_on_page!)
- end
+ product :token
end
end
- context 'when the product is producted via the API' do
- subject do
- Class.new(described_class) do
- def fabricate!
- "any"
- end
-
- product :token
- end
- end
-
- it 'appends new product attribute' do
- expect(subject.attributes).to be_one
- expect(subject.attributes).to have_key(:token)
- end
-
- describe 'populating fabrication product with data' do
- before do
- allow(subject).to receive(:new).and_return(factory)
- allow(factory).to receive(:class).and_return(subject)
- allow(factory).to receive(:api_support?).and_return(true)
- allow(factory).to receive(:api_resource).and_return({ token: 'resulting value' })
- allow(QA::Factory::Product).to receive(:new).and_return(product)
- end
-
- it 'populates product after fabrication' do
- subject.fabricate!
-
- expect(product.token).to eq 'resulting value'
- end
- end
+ it 'appends new product attribute' do
+ expect(subject.attributes).to be_one
+ expect(subject.attributes[0]).to be_a(QA::Factory::Product::Attribute)
+ expect(subject.attributes[0].name).to eq(:token)
end
end
end
diff --git a/qa/spec/factory/product_spec.rb b/qa/spec/factory/product_spec.rb
index 2f2d5568af7..43b1d93d769 100644
--- a/qa/spec/factory/product_spec.rb
+++ b/qa/spec/factory/product_spec.rb
@@ -1,51 +1,71 @@
describe QA::Factory::Product do
let(:factory) do
- QA::Factory::Base.new
+ Class.new(QA::Factory::Base) do
+ def foo
+ 'bar'
+ end
+ end.new
end
let(:product) { spy('product') }
let(:product_location) { 'http://product_location' }
- subject { described_class.new(product_location) }
+ subject { described_class.new(factory, product_location) }
describe '.populate!' do
before do
- allow(QA::Factory::Base).to receive(:attributes).and_return(attributes)
+ expect(factory.class).to receive(:attributes).and_return(attributes)
end
- context 'when the product is produced via the browser' do
+ context 'when the product attribute is populated via a block' do
let(:attributes) do
- { test: QA::Factory::Product::Attribute.new(:test, proc { 'returned' }) }
+ [QA::Factory::Product::Attribute.new(:test, proc { 'returned' })]
end
it 'returns a fabrication product and defines factory attributes as its methods' do
- expect(described_class).to receive(:new).with(product_location).and_return(product)
+ result = described_class.populate!(factory, product_location)
+
+ expect(result).to be_a(described_class)
+ expect(result.test).to eq('returned')
+ end
+ end
- result = described_class.populate!(factory, product_location) do |instance|
- instance.something = 'string'
- end
+ context 'when the product attribute is populated via the api' do
+ let(:attributes) do
+ [QA::Factory::Product::Attribute.new(:test)]
+ end
+
+ it 'returns a fabrication product and defines factory attributes as its methods' do
+ expect(factory).to receive(:api_resource).and_return({ test: 'returned' })
- expect(result).to be product
+ result = described_class.populate!(factory, product_location)
+
+ expect(result).to be_a(described_class)
expect(result.test).to eq('returned')
end
end
- context 'when the product is produced via the api' do
+ context 'when the product attribute is populated via a factory attribute' do
let(:attributes) do
- { test: QA::Factory::Product::Attribute.new(:test) }
+ [QA::Factory::Product::Attribute.new(:foo)]
end
it 'returns a fabrication product and defines factory attributes as its methods' do
- allow(factory).to receive(:api_resource).and_return({ test: 'returned' })
+ result = described_class.populate!(factory, product_location)
- expect(described_class).to receive(:new).with(product_location).and_return(product)
+ expect(result).to be_a(described_class)
+ expect(result.foo).to eq('bar')
+ end
+ end
- result = described_class.populate!(factory, product_location) do |instance|
- instance.something = 'string'
- end
+ context 'when the product attribute has no value' do
+ let(:attributes) do
+ [QA::Factory::Product::Attribute.new(:bar)]
+ end
- expect(result).to be product
- expect(result.test).to eq('returned')
+ it 'returns a fabrication product and defines factory attributes as its methods' do
+ expect { described_class.populate!(factory, product_location) }
+ .to raise_error(described_class::NoValueError, "No value was computed for product bar of factory #{factory.class.name}.")
end
end
end
@@ -53,8 +73,6 @@ describe QA::Factory::Product do
describe '.visit!' do
it 'makes it possible to visit fabrication product' do
allow_any_instance_of(described_class)
- .to receive(:current_url).and_return('some url')
- allow_any_instance_of(described_class)
.to receive(:visit).and_return('visited some url')
expect(subject.visit!).to eq 'visited some url'