magento 0.26.1 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,116 @@
1
+ RSpec.describe Magento::RecordCollection do
2
+ subject { Magento::RecordCollection.new(items: []) }
3
+
4
+ describe 'read only attributes' do
5
+ it { is_expected.to respond_to(:items) }
6
+ it { is_expected.to respond_to(:search_criteria) }
7
+ it { is_expected.to respond_to(:total_count) }
8
+ it { is_expected.not_to respond_to(:items=) }
9
+ it { is_expected.not_to respond_to(:search_criteria=) }
10
+ it { is_expected.not_to respond_to(:total_count=) }
11
+ end
12
+
13
+ describe '#last_page?' do
14
+ it do
15
+ subject = create_subject_with_pagination(total_count: 60, current_page: 6, page_size: 10)
16
+ expect(subject.last_page?).to be true
17
+ end
18
+
19
+ it do
20
+ subject = create_subject_with_pagination(total_count: 60, current_page: 5, page_size: 10)
21
+ expect(subject.last_page?).to be false
22
+ end
23
+ end
24
+
25
+ describe '#next_page' do
26
+ it 'returns next page number' do
27
+ subject = create_subject_with_pagination(current_page: 5, total_count: 60, page_size: 10)
28
+ expect(subject.next_page).to be 6
29
+ end
30
+
31
+ it 'returns nil when current page is the last' do
32
+ subject = create_subject_with_pagination(current_page: 6, total_count: 60, page_size: 10)
33
+ expect(subject.next_page).to be nil
34
+ end
35
+ end
36
+
37
+ describe '.from_magento_response' do
38
+ let(:response) do
39
+ {
40
+ 'items' => [
41
+ { 'id' => 1, 'name' => 'Product one' },
42
+ { 'id' => 2, 'name' => 'Product two' }
43
+ ],
44
+ 'total_count' => 12,
45
+ 'search_criteria' => { 'current_page' => 2, 'page_size' => 10 }
46
+ }
47
+ end
48
+
49
+ it 'create RecordCollection instance from magento response' do
50
+ records = Magento::RecordCollection.from_magento_response(response, model: Magento::Product)
51
+
52
+ expect(records).to all be_a_instance_of(Magento::Product)
53
+ expect(records.size).to eql(2)
54
+ expect(records.total_count).to eql(12)
55
+ end
56
+
57
+ it 'allows specify the iterable field' do
58
+ response['data'] = response.delete 'items'
59
+
60
+ records = Magento::RecordCollection.from_magento_response(
61
+ response,
62
+ model: Magento::Product,
63
+ iterable_field: 'data'
64
+ )
65
+
66
+ expect(records.size).to eql(2)
67
+ expect(records).to all be_a_instance_of(Magento::Product)
68
+ end
69
+ end
70
+
71
+ describe 'delegated methods' do
72
+ let(:methods) do
73
+ %i[
74
+ count
75
+ length
76
+ size
77
+ first
78
+ last
79
+ []
80
+ find
81
+ each
82
+ each_with_index
83
+ sample
84
+ map
85
+ select
86
+ filter
87
+ reject
88
+ collect
89
+ take
90
+ take_while
91
+ sort
92
+ sort_by
93
+ reverse_each
94
+ reverse
95
+ all?
96
+ any?
97
+ none?
98
+ one?
99
+ empty?
100
+ ]
101
+ end
102
+
103
+ it 'from #items' do
104
+ methods.each do |method|
105
+ expect(subject).to respond_to(method)
106
+ expect(subject.items).to receive(method)
107
+ subject.send(method)
108
+ end
109
+ end
110
+ end
111
+
112
+ def create_subject_with_pagination(total_count:, current_page:, page_size:)
113
+ search_criteria = double(:search_criteria, current_page: current_page, page_size: page_size)
114
+ Magento::RecordCollection.new(items: [], total_count: total_count, search_criteria: search_criteria)
115
+ end
116
+ end
@@ -0,0 +1,141 @@
1
+ RSpec.describe Magento::Request do
2
+ let(:config) do
3
+ double('Magento::Configuration',
4
+ url: 'https://site.com.br',
5
+ token: 'magento-token',
6
+ store: 'magento-store',
7
+ timeout: 30,
8
+ open_timeout: 5
9
+ )
10
+ end
11
+
12
+ subject { Magento::Request.new(config: config) }
13
+
14
+ let(:response) do
15
+ double('Response', parse: {}, status: double(:status, success?: true))
16
+ end
17
+
18
+ describe '#get' do
19
+ it 'calls HTTP.get with url' do
20
+ expect_any_instance_of(HTTP::Client).to receive(:get)
21
+ .with('https://site.com.br/rest/magento-store/V1/products')
22
+ .and_return(response)
23
+
24
+ subject.get('products')
25
+ end
26
+ end
27
+
28
+ describe '#put' do
29
+ it 'calls HTTP.put with url and body' do
30
+ body = { product: { price: 22.50 } }
31
+
32
+ expect_any_instance_of(HTTP::Client).to receive(:put)
33
+ .with('https://site.com.br/rest/magento-store/V1/products', { json: body })
34
+ .and_return(response)
35
+
36
+ subject.put('products', body)
37
+ end
38
+ end
39
+
40
+ describe '#post' do
41
+ it 'calls HTTP.post with url and body' do
42
+ body = { product: { name: 'Some name', price: 22.50 } }
43
+
44
+ expect_any_instance_of(HTTP::Client).to receive(:post)
45
+ .with('https://site.com.br/rest/magento-store/V1/products', { json: body })
46
+ .and_return(response)
47
+
48
+ subject.post('products', body)
49
+ end
50
+ end
51
+
52
+ describe '#delete' do
53
+ it 'calls HTTP.selete with url' do
54
+ expect_any_instance_of(HTTP::Client).to receive(:delete)
55
+ .with('https://site.com.br/rest/magento-store/V1/products/22')
56
+ .and_return(response)
57
+
58
+ subject.delete('products/22')
59
+ end
60
+ end
61
+
62
+ context 'private method' do
63
+ describe '#http_auth' do
64
+ it 'calls HTTP.auth with token and returns HTTP::Client' do
65
+ expect(HTTP).to receive(:auth).with("Bearer #{config.token}").and_return(HTTP)
66
+ result = subject.send(:http_auth)
67
+ expect(result).to be_a(HTTP::Client)
68
+ end
69
+ end
70
+
71
+ describe '#base_url' do
72
+ it do
73
+ base_url = "https://site.com.br/rest/magento-store/V1"
74
+ expect(subject.send(:base_url)).to eql(base_url)
75
+ end
76
+ end
77
+
78
+ describe '#url' do
79
+ it 'returns base_url + resource' do
80
+ url = "https://site.com.br/rest/magento-store/V1/products"
81
+ expect(subject.send(:url, 'products')).to eql(url)
82
+ end
83
+ end
84
+
85
+ describe '#handle_error' do
86
+ context 'when success' do
87
+ it 'does nothing' do
88
+ subject.send(:handle_error, response)
89
+ end
90
+ end
91
+
92
+ context 'when status not found' do
93
+ it 'reises Magento::NotFound error' do
94
+ allow(response).to receive(:status).and_return(
95
+ double(:status, success?: false, not_found?: true, code: 404)
96
+ )
97
+
98
+ expect { subject.send(:handle_error, response) }.to raise_error(Magento::NotFound)
99
+ end
100
+ end
101
+
102
+ context 'when other status' do
103
+ it 'reises Magento::MagentoError' do
104
+ allow(response).to receive(:status).and_return(
105
+ double(:status, success?: false, not_found?: false, code: 422)
106
+ )
107
+
108
+ expect { subject.send(:handle_error, response) }.to raise_error(Magento::MagentoError)
109
+ end
110
+ end
111
+ end
112
+
113
+ describe '#save_request' do
114
+ it 'save on instance variable' do
115
+ body = { quantity: 200, category_ids: [1,3,4] }
116
+
117
+ subject.send(:save_request, :post, 'https:someurl.com.br', body)
118
+
119
+ expect(subject.instance_variable_get(:@request)).to eql({
120
+ body: body,
121
+ method: :post,
122
+ url: 'https:someurl.com.br',
123
+ })
124
+ end
125
+
126
+ context 'when body has media_gallery_entries' do
127
+ it 'removes media_gallery_entries attribute from body' do
128
+ body = { product: { name: 'Name', price: 99.90, media_gallery_entries: {} } }
129
+
130
+ subject.send(:save_request, :post, 'https:someurl.com.br', body)
131
+
132
+ expect(subject.instance_variable_get(:@request)).to eql({
133
+ body: { name: 'Name', price: 99.90 },
134
+ method: :post,
135
+ url: 'https:someurl.com.br',
136
+ })
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
@@ -1,38 +1,37 @@
1
- class RequestMock
2
- attr_reader :path
3
-
4
- def post(path)
5
- @path = path
6
- OpenStruct.new(success?: true, parse: true)
7
- end
8
- end
9
-
10
1
  RSpec.describe Magento::Order do
11
- before { Magento.url = 'https://site.com' }
2
+ let(:magento_client) { request = Magento::Request.new }
12
3
 
13
- describe '.send_email' do
14
- it 'shuld request POST /orders/:id/emails' do
15
- request = RequestMock.new
16
- allow(Magento::Order).to receive(:request).and_return(request)
17
-
18
- order_id = 25
19
- result = Magento::Order.send_email(order_id)
20
-
21
- expect(request.path).to eql("orders/#{order_id}/emails")
22
- expect(result).to be true
23
- end
4
+ before do
5
+ allow(Magento::Order).to receive(:request).and_return(magento_client)
24
6
  end
25
7
 
26
- describe '#send_email' do
27
- it 'shuld request POST /orders/:id/emails' do
28
- request = RequestMock.new
29
- allow(Magento::Order).to receive(:request).and_return(request)
8
+ describe 'send_email' do
9
+ let(:order_id) { 11735 }
10
+ let(:response) { double('Response', parse: true, status: 200) }
11
+
12
+ describe 'class method' do
13
+ it 'should request POST /orders/:id/emails' do
14
+ expect(magento_client).to receive(:post)
15
+ .with("orders/#{order_id}/emails")
16
+ .and_return(response)
17
+
18
+ result = Magento::Order.send_email(order_id)
19
+ end
20
+
21
+ it 'should return true' do
22
+ VCR.use_cassette('order/send_email') do
23
+ expect(Magento::Order.send_email(order_id)).to be(true).or be(false)
24
+ end
25
+ end
26
+ end
30
27
 
31
- order = Magento::Order.build(id: 25)
32
- result = order.send_email
28
+ describe 'instance method' do
29
+ it 'shuld call the class method with order_id' do
30
+ expect(Magento::Order).to receive(:send_email).with(order_id)
33
31
 
34
- expect(request.path).to eql("orders/25/emails")
35
- expect(result).to be true
32
+ order = Magento::Order.build(id: order_id)
33
+ result = order.send_email
34
+ end
36
35
  end
37
36
  end
38
37
  end
@@ -1,4 +1,25 @@
1
1
  RSpec.describe Magento::Product do
2
+ let(:magento_client) { Magento::Request.new }
3
+
4
+ before { allow(Magento::Product).to receive(:request).and_return(magento_client) }
5
+
6
+ describe '.find' do
7
+ it 'request to /prducts/:sku' do
8
+ response = double('HTTP::Response', parse: {})
9
+
10
+ expect(magento_client).to receive(:get).with('products/1243').and_return(response)
11
+
12
+ Magento::Product.find('1243')
13
+ end
14
+
15
+ it 'returns a Magento::Product instance' do
16
+ VCR.use_cassette('product/find') do
17
+ product = Magento::Product.find('1243')
18
+ expect(product).to be_an_instance_of(Magento::Product)
19
+ end
20
+ end
21
+ end
22
+
2
23
  describe '#set_custom_attribute' do
3
24
  let(:product) { Magento::Product.build(
4
25
  sku: 25,
data/spec/spec_helper.rb CHANGED
@@ -1,10 +1,11 @@
1
- require "bundler/setup"
1
+ require 'bundler/setup'
2
2
  require 'byebug'
3
- require "magento"
3
+ require 'magento'
4
+ require 'vcr'
4
5
 
5
6
  RSpec.configure do |config|
6
7
  # Enable flags like --only-failures and --next-failure
7
- config.example_status_persistence_file_path = ".rspec_status"
8
+ config.example_status_persistence_file_path = '.rspec_status'
8
9
 
9
10
  # Disable RSpec exposing methods globally on `Module` and `main`
10
11
  config.disable_monkey_patching!
@@ -13,3 +14,16 @@ RSpec.configure do |config|
13
14
  c.syntax = :expect
14
15
  end
15
16
  end
17
+
18
+ Magento.configure do |config|
19
+ config.url = 'https://dev.superbomemcasa.com.br'
20
+ end
21
+
22
+ VCR.configure do |c|
23
+ c.cassette_library_dir = 'spec/vcr_cassettes'
24
+ c.hook_into :webmock
25
+ c.configure_rspec_metadata!
26
+ c.filter_sensitive_data('<MAGENTO_URL>') { Magento.configuration.url }
27
+ c.filter_sensitive_data('<MAGENTO_DOMAIN>') { Magento.configuration.url.sub(/^http(s)?:\/\//, '') }
28
+ c.filter_sensitive_data('<MAGENTO_TOKEN>') { Magento.configuration.token }
29
+ end
@@ -0,0 +1,65 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: "<MAGENTO_URL>/rest/all/V1/orders/11735/emails"
6
+ body:
7
+ encoding: UTF-8
8
+ string: ''
9
+ headers:
10
+ Authorization:
11
+ - Bearer <MAGENTO_TOKEN>
12
+ Connection:
13
+ - close
14
+ Host:
15
+ - "<MAGENTO_DOMAIN>"
16
+ User-Agent:
17
+ - http.rb/4.4.1
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Date:
24
+ - Thu, 28 Jan 2021 02:19:28 GMT
25
+ Content-Type:
26
+ - application/json; charset=utf-8
27
+ Transfer-Encoding:
28
+ - chunked
29
+ Connection:
30
+ - close
31
+ Set-Cookie:
32
+ - PHPSESSID=2smb8fbfrh89ov5l6dsaog9ol3; expires=Thu, 28-Jan-2021 03:19:28 GMT;
33
+ Max-Age=3600; path=/; domain=<MAGENTO_DOMAIN>; secure; HttpOnly
34
+ - __cfduid=d6599c746d9235e60e31314f2c23603101611800368; expires=Sat, 27-Feb-21
35
+ 02:19:28 GMT; path=/; domain=.superbomemcasa.com.br; HttpOnly; SameSite=Lax;
36
+ Secure
37
+ Vary:
38
+ - Accept-Encoding
39
+ Expires:
40
+ - Thu, 19 Nov 1981 08:52:00 GMT
41
+ Cache-Control:
42
+ - no-store, no-cache, must-revalidate
43
+ Pragma:
44
+ - no-cache
45
+ X-Frame-Options:
46
+ - SAMEORIGIN
47
+ Cf-Cache-Status:
48
+ - DYNAMIC
49
+ Cf-Request-Id:
50
+ - 07e862ec7d0000f603b22c5000000001
51
+ Expect-Ct:
52
+ - max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
53
+ Report-To:
54
+ - '{"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report?s=LcpIGCN14P04w%2B12%2BJip%2BoqrTEEJHVD5vP3%2FqWTDV843xCQbwKwwisiq23jbvZ0fOkDmTOxTTgA804Jq1CCnW9d3I14x%2BUGjfoosFZuRXzpxNONKefOyryVm4KckyBHTJSF1EtaW"}]}'
55
+ Nel:
56
+ - '{"max_age":604800,"report_to":"cf-nel"}'
57
+ Server:
58
+ - cloudflare
59
+ Cf-Ray:
60
+ - 61873a8d9b69f603-GRU
61
+ body:
62
+ encoding: UTF-8
63
+ string: 'false'
64
+ recorded_at: Thu, 28 Jan 2021 02:19:28 GMT
65
+ recorded_with: VCR 6.0.0