magentwo 0.1.4 → 0.1.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +187 -3
- data/lib/adapter.rb +19 -8
- data/lib/connection.rb +34 -20
- data/lib/dataset.rb +94 -16
- data/lib/filter.rb +46 -3
- data/lib/magentwo.rb +50 -6
- data/lib/model/base.rb +39 -9
- data/lib/model/cart.rb +12 -0
- data/lib/model/category.rb +10 -0
- data/lib/model/coupon.rb +5 -1
- data/lib/model/order.rb +25 -0
- data/lib/model/product.rb +14 -0
- data/lib/model/sales_rule.rb +18 -0
- data/lib/model/stock_item.rb +12 -0
- data/magentwo.gemspec +1 -1
- data/spec/dataset_spec.rb +27 -2
- data/spec/product_spec.rb +79 -0
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20edcef61f1dd6dcb2d941e61c8c2ec307b3b34f5a8cc20a6bd4b7e5ac13fb78
|
4
|
+
data.tar.gz: 69d77fdbd17a9379a6f17427a3e2095b30aa8f4d36e8f4dc0cba6400767439e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0e08d0b6d433b7e3c8a67a0c1e31a1e15784facf810c3f959cf4c078feb38f3dfde82bc84d55cb3f8ee1fb815b2c87fcfb8273b2ec6bad2598a8f8683c6c2c3
|
7
|
+
data.tar.gz: 6068da51a75fa3cf357354341d9c8a8b27976321454ae44dc0a6e7294db97b57e737cc5f4dedb05f81691f587f33630cabe71265ae3c794e98687147a12839e0
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,188 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
This gem is under developement and nowhere near finished but feel free to play around with it.
|
2
|
+
I am grateful for any ideas and suggestions
|
3
3
|
|
4
|
-
|
4
|
+
# Magentwo
|
5
|
+
|
6
|
+
Ruby-Wrapper for the Magento 2 REST API
|
7
|
+
|
8
|
+
# How to install
|
9
|
+
|
10
|
+
To install the Gem directly use
|
11
|
+
|
12
|
+
```
|
13
|
+
gem install magentwo
|
14
|
+
```
|
15
|
+
|
16
|
+
or add the following line to your Gemfile
|
17
|
+
|
18
|
+
```
|
19
|
+
gem 'magentwo'
|
20
|
+
```
|
21
|
+
|
22
|
+
and call bundler
|
23
|
+
|
24
|
+
```
|
25
|
+
bundle
|
26
|
+
```
|
27
|
+
|
28
|
+
# How to connect to your magento 2 shop
|
29
|
+
|
30
|
+
When only using one connection simply type
|
31
|
+
|
32
|
+
```
|
33
|
+
Magentwo.connect "http://example.com", "user_name", "password"
|
34
|
+
```
|
35
|
+
|
36
|
+
or
|
37
|
+
|
38
|
+
```
|
39
|
+
Magentwo.connect_with_token "http://example.com", "my_secret_token"
|
40
|
+
```
|
41
|
+
|
42
|
+
When using multiple connections at once you can save the result of `Magentwo.connect` and use the `Magentwo.with` method
|
43
|
+
|
44
|
+
```
|
45
|
+
connection1 = Magentwo.connect "http://example1.com", "user_name", "password"
|
46
|
+
connection2 = Magentwo.connect_with_token "http://example2.com", "my_secret_token"
|
47
|
+
|
48
|
+
Magentwo.with (connection1) do
|
49
|
+
#do things in the context of connection1
|
50
|
+
end
|
51
|
+
Magentwo.with (connection2) do
|
52
|
+
#do things in the context of connection2
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
# How to use
|
57
|
+
|
58
|
+
In Magentwo you interact with the API using Models. These are named according the the REST-API specifications of Magento 2
|
59
|
+
The basic functionality is the same for all Models. For products some simple requests would look like this
|
60
|
+
|
61
|
+
```
|
62
|
+
Magentwo::Product.all #fetches all Products
|
63
|
+
Magentwo::Product.first #fetches the first product
|
64
|
+
Magentwo::Product.count #returns the number of available products
|
65
|
+
Magentwo::Product.fields #returns an array of productfields
|
66
|
+
```
|
67
|
+
|
68
|
+
# Filtering
|
69
|
+
|
70
|
+
You can filter requests to search for specific elements
|
71
|
+
Here are some examples
|
72
|
+
|
73
|
+
Look for all customers whose firstname is Foobar
|
74
|
+
|
75
|
+
```
|
76
|
+
Magentwo::Customer.filter(:firstname => "Foobar").all
|
77
|
+
```
|
78
|
+
|
79
|
+
Look for all customers whose id is not 42
|
80
|
+
|
81
|
+
```
|
82
|
+
Magentwo::Customer.exclude(:id => 42).all
|
83
|
+
```
|
84
|
+
|
85
|
+
You can also combine these
|
86
|
+
|
87
|
+
```
|
88
|
+
Magentwo::Customer.filter(:firstname => "Foobar").exclude(:id => 42).all
|
89
|
+
```
|
90
|
+
|
91
|
+
The `filter` and `exclude` methods can also be used to filter for a set. To Request all Customers whose firstname is either Foo or Bar you could write
|
92
|
+
|
93
|
+
```
|
94
|
+
Magentwo::Customer.filter(:firstname => ["Foo", "bar"]).all
|
95
|
+
```
|
96
|
+
|
97
|
+
Look for all Products whose name includes the word "Computer"
|
98
|
+
|
99
|
+
```
|
100
|
+
Magentwo::Product.like(:name => "%Computer%").all
|
101
|
+
```
|
102
|
+
|
103
|
+
Compare using `gt`, `gteq`, `lt` or `lteq`. These methods do not seem to work with dates, please use `from` and `to` when e.g. trying to fetch all Products that changed within a certain period.
|
104
|
+
|
105
|
+
```
|
106
|
+
Magentwo::Product.lt(:price => 42).all
|
107
|
+
Magentwo::Product.gt(:id => 1337).first
|
108
|
+
```
|
109
|
+
|
110
|
+
Compare using `from` and `to`, you may also use both to specify a range.
|
111
|
+
|
112
|
+
```
|
113
|
+
Magentwo::Product.from(:updated_at => Time.new(2019, 1, 1).all
|
114
|
+
Magentwo::Product.to(:created_at => Time.new(2019, 2, 1).all
|
115
|
+
```
|
116
|
+
|
117
|
+
All of these filter-functions can be chained as needed
|
118
|
+
|
119
|
+
# Select
|
120
|
+
|
121
|
+
If you know which fields you are interested in you can speed up the fetching process by only requesting these fields
|
122
|
+
|
123
|
+
```
|
124
|
+
Magentwo::Product.filter(...).select(:id, :sku).all
|
125
|
+
```
|
126
|
+
|
127
|
+
# Pagination
|
128
|
+
|
129
|
+
On default the pagesize is set to 20, you can change this with
|
130
|
+
|
131
|
+
```
|
132
|
+
Magentwo.default_page_size=42
|
133
|
+
```
|
134
|
+
|
135
|
+
The pagesize can also be set on the fly
|
136
|
+
To request page 2 with a pagesize of 100 simply write the following. The second paramter is optional
|
137
|
+
|
138
|
+
```
|
139
|
+
Magentwo::Product.exclude(:name => "foobar").page(2, 100).all
|
140
|
+
```
|
141
|
+
|
142
|
+
To iterate threw all the pages use `each_page`. Again the pagesize parameter is optional
|
143
|
+
|
144
|
+
```
|
145
|
+
Magentwo::Product.each_page(512) do |page|
|
146
|
+
p page
|
147
|
+
end
|
148
|
+
```
|
149
|
+
|
150
|
+
You may also want to fetch all pages of products that match a certain criteria
|
151
|
+
|
152
|
+
```
|
153
|
+
Magentwo::Product.from(:updated_at => my_last_sync_value).each_page(512) do |page|
|
154
|
+
p page
|
155
|
+
end
|
156
|
+
```
|
157
|
+
|
158
|
+
# Order
|
159
|
+
|
160
|
+
By default the results are ordered as Magento2 "thinks" its best. At any place you may add the `order_by` to sepcify this to your liking. If you skip the `ASC/DESC` argument, `ASC` will be set.
|
161
|
+
|
162
|
+
```
|
163
|
+
Magentwo::Product.order_by(:id, "ASC").all
|
164
|
+
Magentwo::Product.order_by(:id, "DESC").all
|
165
|
+
```
|
166
|
+
|
167
|
+
# Updates
|
168
|
+
|
169
|
+
To update Models back to Magento 2 use the `save` method
|
170
|
+
This switches the first and last name of the Customer Foo Bar
|
171
|
+
|
172
|
+
```
|
173
|
+
customer = Magentwo::Customer.filter(:first_name => "Foo", :last_name => "Bar").first
|
174
|
+
customer.firstname = "Bar"
|
175
|
+
customer.lastname = "Foo"
|
176
|
+
customer.save
|
177
|
+
```
|
178
|
+
|
179
|
+
# Delete
|
180
|
+
|
181
|
+
To delete a Model use the `delete` method
|
182
|
+
|
183
|
+
```
|
184
|
+
product = Magentwo::Product.first
|
185
|
+
product.delete
|
186
|
+
```
|
187
|
+
|
188
|
+
to be continued ...
|
data/lib/adapter.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Magentwo
|
2
2
|
class Adapter < Magentwo::Connection
|
3
|
-
|
3
|
+
DateTimeFields = %i(created_at updated_at change_status_at)
|
4
|
+
DateFields = %i(dob)
|
4
5
|
def call method, path, params
|
5
6
|
http_method, params = case method
|
6
7
|
when :put, :post, :delete then [method, params.to_json]
|
@@ -10,18 +11,21 @@ module Magentwo
|
|
10
11
|
end
|
11
12
|
|
12
13
|
response = self.send(http_method, path, params)
|
14
|
+
Magentwo.logger.debug "Response body: #{response.body}" unless response.is_a? TrueClass
|
13
15
|
|
14
16
|
parsed_response = case method
|
15
|
-
when :get_with_meta_data, :put, :post
|
17
|
+
when :get_with_meta_data, :put, :post then transform( parse( response))
|
16
18
|
when :get
|
17
19
|
parsed = parse(response)
|
18
|
-
if parsed
|
19
|
-
parsed[:items].map do |item|
|
20
|
+
if parsed.is_a?(Hash) && (parsed.has_key? :items)
|
21
|
+
(parsed[:items] || []).map do |item|
|
20
22
|
transform item
|
21
23
|
end
|
22
24
|
else
|
23
25
|
transform parsed
|
24
26
|
end
|
27
|
+
when :delete
|
28
|
+
response
|
25
29
|
else
|
26
30
|
raise ArgumentError, "unknown method type. Expected :get, :get_with_meta_data, :post, :put or :delete. #{method} #{path}"
|
27
31
|
end
|
@@ -33,18 +37,25 @@ module Magentwo
|
|
33
37
|
when "200"
|
34
38
|
JSON.parse response.body, :symbolize_names => true
|
35
39
|
else
|
36
|
-
puts "
|
40
|
+
puts "error #{response.code}: #{JSON.parse(response.body)}"
|
41
|
+
return nil
|
37
42
|
end
|
38
43
|
end
|
39
44
|
|
40
45
|
def transform item
|
41
|
-
|
46
|
+
if(item && item.is_a?(Hash))
|
47
|
+
date_transform item
|
48
|
+
else
|
49
|
+
item
|
50
|
+
end
|
42
51
|
end
|
43
52
|
|
44
53
|
def date_transform item
|
45
|
-
p "datetransform: #{item}"
|
46
54
|
DateFields.each do |date_field|
|
47
|
-
item[date_field] =
|
55
|
+
item[date_field] = Date.parse item[date_field] if item[date_field]
|
56
|
+
end
|
57
|
+
DateTimeFields.each do |datetime_field|
|
58
|
+
item[datetime_field] = (Time.parse "#{item[datetime_field]} UTC").getlocal if item[datetime_field]
|
48
59
|
end
|
49
60
|
item
|
50
61
|
end
|
data/lib/connection.rb
CHANGED
@@ -1,44 +1,58 @@
|
|
1
1
|
module Magentwo
|
2
2
|
class Connection
|
3
|
-
attr_accessor :host, :port, :user, :password, :token, :base_path
|
3
|
+
attr_accessor :host, :port, :user, :password, :token, :base_path, :scheme
|
4
4
|
|
5
|
-
def initialize
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
def initialize uri:, user:nil, password:nil, base_path:nil, token:nil
|
6
|
+
uri = URI(uri)
|
7
|
+
@host = uri.host
|
8
|
+
@port = uri.port
|
9
|
+
@scheme = uri.scheme
|
10
|
+
@base_path = base_path || "/rest/V1"
|
11
|
+
|
12
|
+
if (user && password)
|
13
|
+
@user = user
|
14
|
+
@password = password
|
15
|
+
request_token
|
16
|
+
elsif (token)
|
17
|
+
@token = token
|
9
18
|
else
|
10
|
-
|
11
|
-
@port = 80
|
19
|
+
raise ArgumentError, "expected user/password or token"
|
12
20
|
end
|
13
|
-
|
14
|
-
@password = password
|
15
|
-
@base_path = base_path || "/rest/default/V1"
|
16
|
-
request_token
|
21
|
+
|
17
22
|
end
|
18
23
|
|
19
24
|
def request_token
|
20
|
-
Net::HTTP.start(self.host,self.port) do |http|
|
21
|
-
|
25
|
+
Net::HTTP.start(self.host,self.port, :use_ssl => self.scheme == 'https') do |http|
|
26
|
+
url = "#{base_path}/integration/admin/token"
|
27
|
+
Magentwo.logger.info "POST #{url}"
|
28
|
+
req = Net::HTTP::Post.new(url)
|
22
29
|
req.body = {:username=> self.user, :password=> self.password}.to_json
|
23
30
|
req['Content-Type'] = "application/json"
|
24
31
|
req['Content-Length'] = req.body.length
|
25
|
-
|
32
|
+
response = http.request(req).body
|
33
|
+
@token = JSON.parse response
|
26
34
|
end
|
27
35
|
end
|
28
36
|
|
29
37
|
def delete path, data
|
30
|
-
Magentwo.logger.info "DELETE #{path}"
|
38
|
+
Magentwo.logger.info "DELETE #{host}/#{base_path}/#{path}"
|
31
39
|
Magentwo.logger.debug "DATA #{data}"
|
32
40
|
|
33
|
-
|
34
|
-
|
41
|
+
url = "#{base_path}/#{path}"
|
42
|
+
Net::HTTP.start(self.host,self.port, :use_ssl => self.scheme == 'https') do |http|
|
43
|
+
req = Net::HTTP::Delete.new(url)
|
44
|
+
req["Authorization"] = "Bearer #{self.token}"
|
45
|
+
req['Content-Type'] = "application/json"
|
46
|
+
req.body = data
|
47
|
+
http.request(req)
|
48
|
+
end
|
35
49
|
end
|
36
50
|
|
37
51
|
def put path, data
|
38
52
|
Magentwo.logger.info "PUT #{host}/#{base_path}/#{path}"
|
39
53
|
Magentwo.logger.debug "DATA #{data}"
|
40
54
|
url = "#{base_path}/#{path}"
|
41
|
-
Net::HTTP.start(self.host,self.port) do |http|
|
55
|
+
Net::HTTP.start(self.host,self.port, :use_ssl => self.scheme == 'https') do |http|
|
42
56
|
req = Net::HTTP::Put.new(url)
|
43
57
|
req["Authorization"] = "Bearer #{self.token}"
|
44
58
|
req['Content-Type'] = "application/json"
|
@@ -51,7 +65,7 @@ module Magentwo
|
|
51
65
|
Magentwo.logger.info "POST #{host}/#{path}"
|
52
66
|
Magentwo.logger.debug "DATA #{data}"
|
53
67
|
url = "#{base_path}/#{path}"
|
54
|
-
Net::HTTP.start(self.host,self.port) do |http|
|
68
|
+
Net::HTTP.start(self.host,self.port, :use_ssl => self.scheme == 'https') do |http|
|
55
69
|
req = Net::HTTP::Post.new(url)
|
56
70
|
req["Authorization"] = "Bearer #{self.token}"
|
57
71
|
req['Content-Type'] = "application/json"
|
@@ -64,7 +78,7 @@ module Magentwo
|
|
64
78
|
def get path, query
|
65
79
|
Magentwo.logger.info "GET #{host}#{base_path}/#{path}?#{query}"
|
66
80
|
url = "#{base_path}/#{path}?#{query}"
|
67
|
-
Net::HTTP.start(self.host,self.port) do |http|
|
81
|
+
Net::HTTP.start(self.host,self.port, :use_ssl => self.scheme == 'https') do |http|
|
68
82
|
req = Net::HTTP::Get.new(url)
|
69
83
|
req["Authorization"] = "Bearer #{self.token}"
|
70
84
|
req['Content-Type'] = "application/json"
|
data/lib/dataset.rb
CHANGED
@@ -7,7 +7,7 @@ module Magentwo
|
|
7
7
|
:filters => [],
|
8
8
|
:pagination => {
|
9
9
|
:current_page => Filter::CurrentPage.new(1),
|
10
|
-
:page_size => Filter::PageSize.new(
|
10
|
+
:page_size => Filter::PageSize.new(0)
|
11
11
|
},
|
12
12
|
:ordering => [],
|
13
13
|
:fields => nil
|
@@ -18,27 +18,44 @@ module Magentwo
|
|
18
18
|
# Filters
|
19
19
|
################
|
20
20
|
def filter hash_or_other, invert:false
|
21
|
-
|
21
|
+
filters = case hash_or_other
|
22
22
|
when Hash
|
23
23
|
raise ArgumentError, "empty hash supplied" if hash_or_other.empty?
|
24
|
-
key, value
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
24
|
+
hash_or_other.map do |key, value|
|
25
|
+
klass = case value
|
26
|
+
when Array
|
27
|
+
invert ? Filter::Nin : Filter::In
|
28
|
+
else
|
29
|
+
invert ? Filter::Neq : Filter::Eq
|
30
|
+
end
|
31
|
+
klass.new(key, value)
|
30
32
|
end
|
31
|
-
klass.new(key, value)
|
32
33
|
else
|
33
34
|
raise ArgumentError, "filter function expects Hash as input"
|
34
35
|
end
|
35
|
-
Dataset.new self.model, self.opts.merge(:filters => self.opts[:filters] +
|
36
|
+
Dataset.new self.model, self.opts.merge(:filters => self.opts[:filters] + filters)
|
36
37
|
end
|
37
38
|
|
38
39
|
def exclude args
|
39
40
|
filter args, invert:true
|
40
41
|
end
|
41
42
|
|
43
|
+
def gt args
|
44
|
+
Dataset.new self.model, self.opts.merge(:filters => self.opts[:filters] + [Filter::Gt.new(args.keys.first, args.values.first)])
|
45
|
+
end
|
46
|
+
|
47
|
+
def lt args
|
48
|
+
Dataset.new self.model, self.opts.merge(:filters => self.opts[:filters] + [Filter::Lt.new(args.keys.first, args.values.first)])
|
49
|
+
end
|
50
|
+
|
51
|
+
def gteq args
|
52
|
+
Dataset.new self.model, self.opts.merge(:filters => self.opts[:filters] + [Filter::Gteq.new(args.keys.first, args.values.first)])
|
53
|
+
end
|
54
|
+
|
55
|
+
def lteq args
|
56
|
+
Dataset.new self.model, self.opts.merge(:filters => self.opts[:filters] + [Filter::Lteq.new(args.keys.first, args.values.first)])
|
57
|
+
end
|
58
|
+
|
42
59
|
def select *fields
|
43
60
|
Dataset.new self.model, self.opts.merge(:fields => Filter::Fields.new(fields))
|
44
61
|
end
|
@@ -47,6 +64,14 @@ module Magentwo
|
|
47
64
|
Dataset.new self.model, self.opts.merge(:filters => self.opts[:filters] + [Filter::Like.new(args.keys.first, args.values.first)])
|
48
65
|
end
|
49
66
|
|
67
|
+
def from args
|
68
|
+
Dataset.new self.model, self.opts.merge(:filters => self.opts[:filters] + [Filter::From.new(args.keys.first, args.values.first)])
|
69
|
+
end
|
70
|
+
|
71
|
+
def to args
|
72
|
+
Dataset.new self.model, self.opts.merge(:filters => self.opts[:filters] + [Filter::To.new(args.keys.first, args.values.first)])
|
73
|
+
end
|
74
|
+
|
50
75
|
#################
|
51
76
|
# Pagination
|
52
77
|
################
|
@@ -84,30 +109,62 @@ module Magentwo
|
|
84
109
|
self.model.first self
|
85
110
|
end
|
86
111
|
|
87
|
-
def all
|
88
|
-
self.model.all self
|
112
|
+
def all meta_data:false
|
113
|
+
self.model.all self, :meta_data => meta_data
|
89
114
|
end
|
90
115
|
|
91
116
|
#################
|
92
117
|
# Transformation
|
93
118
|
################
|
119
|
+
def print_readable
|
120
|
+
ds = self
|
121
|
+
|
122
|
+
puts "*** Pagination ***"
|
123
|
+
puts ds.opts[:pagination][:current_page].to_s
|
124
|
+
puts ds.opts[:pagination][:page_size].to_s
|
125
|
+
|
126
|
+
puts "*** Filters ***"
|
127
|
+
ds.opts[:filters].each do |filter|
|
128
|
+
puts filter.to_s
|
129
|
+
end
|
130
|
+
|
131
|
+
puts "*** Ordering ***"
|
132
|
+
order_filters = ds.opts[:ordering]
|
133
|
+
if order_filters.size > 0
|
134
|
+
order_filters.each do |filter|
|
135
|
+
puts filter.to_s
|
136
|
+
end
|
137
|
+
else
|
138
|
+
puts "non specified"
|
139
|
+
end
|
140
|
+
|
141
|
+
puts "*** Fields ***"
|
142
|
+
if fields = ds.opts[:fields]&.fields
|
143
|
+
puts "Fetch only: #{fields}"
|
144
|
+
else
|
145
|
+
puts "Fetch everything"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
94
149
|
def to_query
|
150
|
+
self.validate
|
151
|
+
ds = self
|
95
152
|
[
|
96
|
-
|
153
|
+
ds.opts[:filters]
|
97
154
|
.each_with_index
|
98
155
|
.map { |opt, idx| opt.to_query(idx) }
|
99
156
|
.join("&"),
|
100
157
|
|
101
|
-
|
158
|
+
ds.opts[:pagination]
|
102
159
|
.map { |k, v| v.to_query}
|
103
160
|
.join("&"),
|
104
161
|
|
105
162
|
|
106
|
-
|
163
|
+
ds.opts[:ordering]
|
107
164
|
.map { |opt, idx| opt.to_query(idx) }
|
108
165
|
.join("&"),
|
109
166
|
|
110
|
-
|
167
|
+
ds.opts[:fields]? ds.opts[:fields].to_query() : ""
|
111
168
|
].reject(&:empty?)
|
112
169
|
.join("&")
|
113
170
|
end
|
@@ -124,5 +181,26 @@ module Magentwo
|
|
124
181
|
raise ArgumentError, "no block given" unless block_given?
|
125
182
|
self.model.all.each(&block)
|
126
183
|
end
|
184
|
+
|
185
|
+
def each_page page_size=Magentwo.default_page_size, &block
|
186
|
+
raise ArgumentError, "no block given" unless block_given?
|
187
|
+
|
188
|
+
received_element_count = page_size
|
189
|
+
current_page = 1
|
190
|
+
total_count = nil
|
191
|
+
until(total_count && current_page*page_size > (total_count + page_size)) do
|
192
|
+
page = self.page(current_page, page_size).all meta_data:true
|
193
|
+
total_count = page[:total_count] unless total_count
|
194
|
+
block.call(page[:items])
|
195
|
+
current_page += 1
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
#################
|
200
|
+
# Validation
|
201
|
+
################
|
202
|
+
def validate
|
203
|
+
true
|
204
|
+
end
|
127
205
|
end
|
128
206
|
end
|
data/lib/filter.rb
CHANGED
@@ -7,23 +7,31 @@ module Magentwo
|
|
7
7
|
@value = value
|
8
8
|
end
|
9
9
|
|
10
|
-
def to_query idx
|
10
|
+
def to_query idx, field:self.field, value:self.value
|
11
11
|
[
|
12
12
|
"searchCriteria[filter_groups][#{idx}][filters][0][field]=#{self.field}",
|
13
|
-
"searchCriteria[filter_groups][#{idx}][filters][0][value]=#{URI::encode(self.value)}",
|
13
|
+
"searchCriteria[filter_groups][#{idx}][filters][0][value]=#{URI::encode(self.value.to_s)}",
|
14
14
|
"searchCriteria[filter_groups][#{idx}][filters][0][condition_type]=#{self.class.name.split("::").last.downcase}"]
|
15
15
|
.join("&")
|
16
16
|
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
"#{self.field} #{self.class.name.split("::").last.downcase} #{self.value}"
|
20
|
+
end
|
17
21
|
end
|
18
22
|
|
19
23
|
class CompareArray < Compare
|
20
24
|
def to_query idx
|
21
25
|
[
|
22
26
|
"searchCriteria[filter_groups][#{idx}][filters][0][field]=#{self.field}",
|
23
|
-
"searchCriteria[filter_groups][#{idx}][filters][0][value]=#{URI::encode(self.value.join(","))}",
|
27
|
+
"searchCriteria[filter_groups][#{idx}][filters][0][value]=#{URI::encode(self.value.map(&:to_s).join(","))}",
|
24
28
|
"searchCriteria[filter_groups][#{idx}][filters][0][condition_type]=#{self.class.name.split("::").last.downcase}"]
|
25
29
|
.join("&")
|
26
30
|
end
|
31
|
+
|
32
|
+
def to_s
|
33
|
+
"#{self.field} #{self.class.name.split("::").last.downcase} #{self.value}"
|
34
|
+
end
|
27
35
|
end
|
28
36
|
|
29
37
|
class Simple
|
@@ -36,6 +44,10 @@ module Magentwo
|
|
36
44
|
def to_query idx=nil
|
37
45
|
"searchCriteria[#{key}]=#{value}"
|
38
46
|
end
|
47
|
+
|
48
|
+
def to_s
|
49
|
+
"#{self.key} == #{self.value}"
|
50
|
+
end
|
39
51
|
end
|
40
52
|
|
41
53
|
class Multi
|
@@ -49,6 +61,12 @@ module Magentwo
|
|
49
61
|
"searchCriteria[#{kvp[:key]}]=#{kvp[:value]}"
|
50
62
|
end.join("&")
|
51
63
|
end
|
64
|
+
|
65
|
+
def to_s
|
66
|
+
self.kvps.map do |kvp|
|
67
|
+
"#{kvp[:key]} = #{kvp[:value]}"
|
68
|
+
end.join("\n")
|
69
|
+
end
|
52
70
|
end
|
53
71
|
|
54
72
|
|
@@ -67,6 +85,31 @@ module Magentwo
|
|
67
85
|
class Like < Magentwo::Filter::Compare
|
68
86
|
end
|
69
87
|
|
88
|
+
class Gt < Magentwo::Filter::Compare
|
89
|
+
end
|
90
|
+
|
91
|
+
class Lt < Magentwo::Filter::Compare
|
92
|
+
end
|
93
|
+
|
94
|
+
class Gteq < Magentwo::Filter::Compare
|
95
|
+
end
|
96
|
+
|
97
|
+
class Lteq < Magentwo::Filter::Compare
|
98
|
+
end
|
99
|
+
|
100
|
+
class From < Magentwo::Filter::Compare
|
101
|
+
def to_query idx
|
102
|
+
value = case self.value
|
103
|
+
when Time then self.value.utc
|
104
|
+
else self.value
|
105
|
+
end
|
106
|
+
super idx, value:value
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class To < Magentwo::Filter::Compare
|
111
|
+
end
|
112
|
+
|
70
113
|
class PageSize < Magentwo::Filter::Simple
|
71
114
|
def initialize value
|
72
115
|
super(:page_size, value)
|
data/lib/magentwo.rb
CHANGED
@@ -1,12 +1,36 @@
|
|
1
1
|
require 'uri'
|
2
2
|
require 'net/http'
|
3
3
|
require 'json'
|
4
|
+
require 'time'
|
4
5
|
require 'logger'
|
5
6
|
|
6
7
|
module Magentwo
|
7
|
-
Models = %w(base product customer order coupon sales_rule)
|
8
|
-
|
9
|
-
|
8
|
+
Models = %w(base product customer order coupon sales_rule category cart stock_item)
|
9
|
+
@@mutex = Mutex.new
|
10
|
+
def self.connect host=nil, user_name=nil, password=nil
|
11
|
+
raise ArgumentError, "no host specified" unless host
|
12
|
+
raise ArgumentError, "no user_name specified" unless user_name
|
13
|
+
raise ArgumentError, "no password specified" unless password
|
14
|
+
Base.adapter = Adapter.new ({uri: host, user: user_name, password: password})
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.connect_with_token host=nil, token=nil
|
18
|
+
raise ArgumentError, "no host specified" unless host
|
19
|
+
raise ArgumentError, "no token specified" unless token
|
20
|
+
Base.adapter = Adapter.new ({token: token, uri: host})
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.with connection
|
24
|
+
raise ArgumentError, "no connection specified" unless connection
|
25
|
+
@@mutex.synchronize do
|
26
|
+
old_connection = Magentwo::Base.adapter
|
27
|
+
begin
|
28
|
+
Magentwo::Base.adapter = connection
|
29
|
+
yield
|
30
|
+
ensure
|
31
|
+
Magentwo::Base.adapter = old_connection
|
32
|
+
end
|
33
|
+
end
|
10
34
|
end
|
11
35
|
|
12
36
|
def self.logger= logger
|
@@ -14,7 +38,20 @@ module Magentwo
|
|
14
38
|
end
|
15
39
|
|
16
40
|
def self.logger
|
17
|
-
@@logger ||= Logger.new STDOUT, {:level => Logger::
|
41
|
+
@@logger ||= Logger.new STDOUT, {:level => Logger::INFO}
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.log_level= level
|
45
|
+
new_log_level = case level
|
46
|
+
when :debug then Logger::DEBUG
|
47
|
+
when :info then Logger::INFO
|
48
|
+
when :warn then Logger::WARN
|
49
|
+
when :error then Logger::ERROR
|
50
|
+
when :fatal then Logger::FATAL
|
51
|
+
else
|
52
|
+
raise ArgumentError, "invalid log_level"
|
53
|
+
end
|
54
|
+
self.logger= Logger.new STDOUT, {:level => new_log_level}
|
18
55
|
end
|
19
56
|
|
20
57
|
def self.default_page_size
|
@@ -25,7 +62,14 @@ module Magentwo
|
|
25
62
|
@@default_page_size = page_size
|
26
63
|
end
|
27
64
|
|
28
|
-
|
65
|
+
def self.models
|
66
|
+
Models.map do |model_file_name|
|
67
|
+
model_file_name
|
68
|
+
.split('_')
|
69
|
+
.map(&:capitalize)
|
70
|
+
.join
|
71
|
+
end
|
72
|
+
end
|
29
73
|
end
|
30
74
|
|
31
75
|
require_relative 'connection.rb'
|
@@ -35,5 +79,5 @@ require_relative 'dataset.rb'
|
|
35
79
|
require_relative 'util/validator.rb'
|
36
80
|
|
37
81
|
Magentwo::Models.each do |file_name|
|
38
|
-
|
82
|
+
require_relative("model/#{file_name}.rb")
|
39
83
|
end
|
data/lib/model/base.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
module Magentwo
|
2
2
|
class Base
|
3
|
-
DatasetMethods = %i(filter exclude select fields count fields info page order_by like)
|
4
|
-
|
5
|
-
attr_accessor :base_path
|
3
|
+
DatasetMethods = %i(filter exclude select fields count fields info page order_by like gt lt gteq lteq from to)
|
6
4
|
|
7
5
|
def initialize args
|
8
6
|
args.each do |key, value|
|
@@ -20,12 +18,14 @@ module Magentwo
|
|
20
18
|
|
21
19
|
def save
|
22
20
|
self.validate
|
23
|
-
|
21
|
+
self.check_presence self.class.unique_identifier
|
22
|
+
response = Magentwo::Base.call :put, "#{self.class.base_path}/#{self.send(self.class.unique_identifier)}", self
|
24
23
|
self.class.new response
|
25
24
|
end
|
26
25
|
|
27
26
|
def delete
|
28
|
-
|
27
|
+
self.check_presence self.class.unique_identifier
|
28
|
+
Magentwo::Base.call :delete, "#{self.class.base_path}/#{self.send(self.class.unique_identifier)}", nil
|
29
29
|
end
|
30
30
|
|
31
31
|
def validate
|
@@ -64,6 +64,15 @@ module Magentwo
|
|
64
64
|
class << self
|
65
65
|
attr_accessor :adapter
|
66
66
|
|
67
|
+
def [] unique_identifier_value
|
68
|
+
result = Magentwo::Base.get nil, path:"#{base_path}/#{unique_identifier_value}"
|
69
|
+
self.new result if result
|
70
|
+
end
|
71
|
+
|
72
|
+
def unique_identifier
|
73
|
+
:id
|
74
|
+
end
|
75
|
+
|
67
76
|
def lower_case_name
|
68
77
|
name = self.name.split(/::/).last
|
69
78
|
"#{name[0,1].downcase}#{name[1..-1]}"
|
@@ -77,15 +86,36 @@ module Magentwo
|
|
77
86
|
base_path
|
78
87
|
end
|
79
88
|
|
80
|
-
def all ds=self.dataset
|
81
|
-
self.get(ds.to_query)
|
89
|
+
def all ds=self.dataset, meta_data:false
|
90
|
+
response = self.get(ds.to_query, :meta_data => meta_data)
|
91
|
+
return [] if response.nil?
|
92
|
+
items = (meta_data ? response[:items] : response)
|
82
93
|
.map do |item|
|
83
94
|
self.new item
|
84
95
|
end
|
96
|
+
if meta_data
|
97
|
+
response[:items] = items
|
98
|
+
response
|
99
|
+
else
|
100
|
+
items
|
101
|
+
end
|
85
102
|
end
|
86
103
|
|
87
104
|
def first ds=self.dataset
|
88
|
-
|
105
|
+
response = self.get(ds.page(1, 1).to_query).first
|
106
|
+
self.new response if response
|
107
|
+
end
|
108
|
+
|
109
|
+
def each_page page_size=Magentwo.default_page_size, &block
|
110
|
+
self.dataset.each_page page_size, &block
|
111
|
+
end
|
112
|
+
|
113
|
+
def each &block
|
114
|
+
self.dataset.each &block
|
115
|
+
end
|
116
|
+
|
117
|
+
def map &block
|
118
|
+
self.dataset.map &block
|
89
119
|
end
|
90
120
|
|
91
121
|
def dataset
|
@@ -108,7 +138,7 @@ module Magentwo
|
|
108
138
|
end
|
109
139
|
|
110
140
|
def call method, path=self.base_path, params
|
111
|
-
|
141
|
+
Magentwo::Base.adapter.call(method, path, params)
|
112
142
|
end
|
113
143
|
|
114
144
|
end
|
data/lib/model/cart.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
module Magentwo
|
2
|
+
class Cart < Base
|
3
|
+
Attributes = %i(id created_at updated_at is_active is_virtual items_count items_qty customer billing_address reserved_order_id orig_order_id currency customer_is_guest customer_note_notify customer_tax_class_id store_id)
|
4
|
+
Attributes.each do |attr| attr_accessor attr end
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def get_path
|
8
|
+
"#{self.base_path}/search"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/model/coupon.rb
CHANGED
@@ -11,7 +11,7 @@ module Magentwo
|
|
11
11
|
def generate rule_id, quantity:1, length:16, format:(:alpha), delimiter:"-", delimiter_at_every:4
|
12
12
|
format = format.to_sym
|
13
13
|
Magentwo::Validator.one_of format, :num, :alpha, :alphanum
|
14
|
-
self.call :post, "
|
14
|
+
self.call :post, "#{base_path}/generate",
|
15
15
|
{
|
16
16
|
:couponSpec => {
|
17
17
|
:rule_id => rule_id,
|
@@ -23,6 +23,10 @@ module Magentwo
|
|
23
23
|
}
|
24
24
|
}
|
25
25
|
end
|
26
|
+
|
27
|
+
def unique_identifier
|
28
|
+
:coupon_id
|
29
|
+
end
|
26
30
|
end
|
27
31
|
|
28
32
|
end
|
data/lib/model/order.rb
CHANGED
@@ -1,5 +1,30 @@
|
|
1
1
|
module Magentwo
|
2
2
|
class Order < Base
|
3
|
+
Attributes = %i(base_currency_code base_discount_amount base_discount_invoiced base_grand_total base_discount_tax_compensation_amount base_discount_tax_compensation_invoiced base_shipping_amount base_shipping_discount_amount base_shipping_discount_tax_compensation_amnt base_shipping_incl_tax base_shipping_invoiced base_shipping_tax_amount base_subtotal base_subtotal_incl_tax base_subtotal_invoiced base_tax_amount base_tax_invoiced base_total_due base_total_invoiced base_total_invoiced_cost base_total_paid base_to_global_rate base_to_order_rate billing_address_id created_at customer_dob customer_email customer_firstname customer_gender customer_group_id customer_id customer_is_guest customer_lastname customer_note_notify discount_amount discount_invoiced entity_id global_currency_code grand_total discount_tax_compensation_amount discount_tax_compensation_invoiced increment_id is_virtual order_currency_code protect_code quote_id shipping_amount shipping_description shipping_discount_amount shipping_discount_tax_compensation_amount shipping_incl_tax shipping_invoiced shipping_tax_amount state status store_currency_code store_id store_name store_to_base_rate store_to_order_rate subtotal subtotal_incl_tax subtotal_invoiced tax_amount tax_invoiced total_due total_invoiced total_item_count total_paid total_qty_ordered updated_at weight items billing_address payment status_histories extension_attributes amount_refunded base_amount_refunded base_discount_amount base_discount_invoiced base_discount_tax_compensation_amount base_discount_tax_compensation_invoiced base_original_price base_price base_price_incl_tax base_row_invoiced base_row_total base_row_total_incl_tax base_tax_amount base_tax_invoiced created_at discount_amount discount_invoiced discount_percent free_shipping discount_tax_compensation_amount discount_tax_compensation_invoiced is_qty_decimal item_id name no_discount order_id original_price price price_incl_tax product_id product_type qty_canceled qty_invoiced qty_ordered qty_refunded qty_shipped row_invoiced row_total row_total_incl_tax row_weight sku store_id tax_amount tax_invoiced tax_percent updated_at weight)
|
4
|
+
Attributes.each do |attr| attr_accessor attr end
|
3
5
|
|
6
|
+
def products
|
7
|
+
product_skus = self.items.map do |item|
|
8
|
+
item[:sku]
|
9
|
+
end
|
10
|
+
Magentwo::Product.filter(:sku => product_skus).all
|
11
|
+
end
|
12
|
+
|
13
|
+
def customer
|
14
|
+
self.check_presence :customer_id
|
15
|
+
Magentwo::Customer[self.customer_id]
|
16
|
+
end
|
17
|
+
|
18
|
+
class << self
|
19
|
+
#this is necessary as the return type of magento2 is not consistent
|
20
|
+
def [] unique_identifier
|
21
|
+
self.filter(:entity_id => unique_identifier).first
|
22
|
+
end
|
23
|
+
|
24
|
+
def unique_identifier
|
25
|
+
Magentwo::Logger.error "orders do not contain id on default requests, therefore they cannot be targeted on the API"
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
end
|
4
29
|
end
|
5
30
|
end
|
data/lib/model/product.rb
CHANGED
@@ -2,5 +2,19 @@ module Magentwo
|
|
2
2
|
class Product < Base
|
3
3
|
Attributes = %i(id sku name attribute_set_id price status visibility type_id created_at updated_at extension_attributes product_links options media_gallery_entries tier_prices custom_attributes)
|
4
4
|
Attributes.each do |attr| attr_accessor attr end
|
5
|
+
|
6
|
+
def stocks
|
7
|
+
Magentwo::StockItem[self.sku]
|
8
|
+
end
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def types
|
12
|
+
Magentwo::Base.get nil, path:"#{base_path}/types"
|
13
|
+
end
|
14
|
+
|
15
|
+
def unique_identifier
|
16
|
+
:sku
|
17
|
+
end
|
18
|
+
end
|
5
19
|
end
|
6
20
|
end
|
data/lib/model/sales_rule.rb
CHANGED
@@ -3,10 +3,28 @@ module Magentwo
|
|
3
3
|
Attributes = %i(rule_id name store_labels description website_ids customer_group_ids uses_per_customer is_active condition action_condition stop_rules_processing is_advanced sort_order simple_action discount_amount discount_step apply_to_shipping times_used is_rss coupon_type use_auto_generation uses_per_coupon simple_free_shipping)
|
4
4
|
Attributes.each do |attr| attr_accessor attr end
|
5
5
|
|
6
|
+
def generate quantity:1, length:16, format:(:alpha), delimiter:"-", delimiter_at_every:4
|
7
|
+
self.check_presence :rule_id
|
8
|
+
Magentwo::Coupon.generate self.rule_id, quantity:quantity, length:length, format:format, delimiter:delimiter, delimiter_at_every:delimiter_at_every
|
9
|
+
end
|
10
|
+
|
11
|
+
def coupons
|
12
|
+
self.check_presence :rule_id
|
13
|
+
Magentwo::Coupon.filter(:rule_id => self.rule_id).all
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_json
|
17
|
+
Hash["rule", self.to_h].to_json
|
18
|
+
end
|
19
|
+
|
6
20
|
class << self
|
7
21
|
def get_path
|
8
22
|
"#{base_path}/search"
|
9
23
|
end
|
24
|
+
|
25
|
+
def unique_identifier
|
26
|
+
:rule_id
|
27
|
+
end
|
10
28
|
end
|
11
29
|
|
12
30
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Usage:
|
2
|
+
# Magentwo::StockItems['sku']
|
3
|
+
|
4
|
+
module Magentwo
|
5
|
+
class StockItem < Base
|
6
|
+
Attributes = %i(item_id product_id stock_id qty is_in_stock is_qty_decimal show_default_notification_message use_config_min_qty min_qty use_config_min_sale_qty min_sale_qty use_config_max_sale_qty max_sale_qty use_config_backorders backorders use_config_notify_stock_qty notify_stock_qty use_config_qty_increments qty_increments use_config_enable_qty_inc enable_qty_increments use_config_manage_stock manage_stock low_stock_date is_decimal_divided stock_status_changed_auto)
|
7
|
+
Attributes.each do |attr| attr_accessor attr end
|
8
|
+
|
9
|
+
class << self
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/magentwo.gemspec
CHANGED
data/spec/dataset_spec.rb
CHANGED
@@ -18,9 +18,9 @@ describe Magentwo::Dataset do
|
|
18
18
|
expect(dataset.opts[:pagination]).to have_key :current_page
|
19
19
|
expect(dataset.opts[:pagination]).to have_key :page_size
|
20
20
|
end
|
21
|
-
it "requests
|
21
|
+
it "requests all items on default" do
|
22
22
|
expect(initial_query).to include "searchCriteria[current_page]=1"
|
23
|
-
expect(initial_query).to include "searchCriteria[page_size]
|
23
|
+
expect(initial_query).to include "searchCriteria[page_size]=0"
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -37,6 +37,31 @@ describe Magentwo::Dataset do
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
+
context "multi filter" do
|
41
|
+
let(:multi_filter_ds) {dataset.filter(:name => "foobar").filter(:id => 42)}
|
42
|
+
let(:multi_filter_query) {multi_filter_ds.to_query}
|
43
|
+
let(:multi_filter_in_one_ds) {dataset.filter(:name => "foobar", :id => 42)}
|
44
|
+
let(:multi_filter_in_one_query) {multi_filter_in_one_ds.to_query}
|
45
|
+
it "contains filter with type Filter::Eq" do
|
46
|
+
expect(multi_filter_ds.opts[:filters]).to include Magentwo::Filter::Eq
|
47
|
+
end
|
48
|
+
it "contains two filters" do
|
49
|
+
expect(multi_filter_ds.opts[:filters].count).to eq 2
|
50
|
+
end
|
51
|
+
it "compute query" do
|
52
|
+
expect(multi_filter_query).to include "searchCriteria[filter_groups][0][filters][0][field]=name"
|
53
|
+
expect(multi_filter_query).to include "searchCriteria[filter_groups][0][filters][0][condition_type]=eq"
|
54
|
+
expect(multi_filter_query).to include "searchCriteria[filter_groups][0][filters][0][value]=foobar"
|
55
|
+
expect(multi_filter_query).to include "searchCriteria[filter_groups][1][filters][0][field]=id"
|
56
|
+
expect(multi_filter_query).to include "searchCriteria[filter_groups][1][filters][0][condition_type]=eq"
|
57
|
+
expect(multi_filter_query).to include "searchCriteria[filter_groups][1][filters][0][value]=42"
|
58
|
+
end
|
59
|
+
it "is the same for multiple keys in one filter" do
|
60
|
+
expect(multi_filter_ds.opts.count).to eq multi_filter_in_one_ds.opts.count
|
61
|
+
expect(multi_filter_query).to eq multi_filter_in_one_query
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
40
65
|
context "select" do
|
41
66
|
let(:name_select_ds) {dataset.select(:name)}
|
42
67
|
let(:name_select_query) {name_select_ds.to_query}
|
data/spec/product_spec.rb
CHANGED
@@ -1,4 +1,83 @@
|
|
1
1
|
require_relative '../lib/magentwo.rb'
|
2
2
|
|
3
3
|
describe Magentwo::Product do
|
4
|
+
before(:all) do
|
5
|
+
Magentwo.logger = Logger.new STDOUT, {:level => Logger::ERROR}
|
6
|
+
@original_count = Magentwo::Product.count
|
7
|
+
end
|
8
|
+
|
9
|
+
context "#dataset" do
|
10
|
+
let(:dataset) {Magentwo::Product.dataset}
|
11
|
+
it "returns dataset" do
|
12
|
+
expect(dataset).to be_a Magentwo::Dataset
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "#count" do
|
17
|
+
let(:count) {Magentwo::Product.count}
|
18
|
+
it "responds to :count" do
|
19
|
+
expect(Magentwo::Product).to respond_to :count
|
20
|
+
end
|
21
|
+
it "correct count" do
|
22
|
+
expect(count).to eq @original_count
|
23
|
+
end
|
24
|
+
it "count is integer" do
|
25
|
+
expect(count).to be_a Integer
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "#all" do
|
30
|
+
let(:products) {Magentwo::Product.all}
|
31
|
+
let(:ds) {Magentwo::Product.dataset}
|
32
|
+
|
33
|
+
it "responds to all" do
|
34
|
+
expect(Magentwo::Product).to respond_to :all
|
35
|
+
end
|
36
|
+
it "returns an array" do
|
37
|
+
expect(products).to be_a Array
|
38
|
+
end
|
39
|
+
it "requested all" do
|
40
|
+
expect(products.count).to eq @original_count
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "#fields" do
|
45
|
+
let(:fields) {Magentwo::Product.fields}
|
46
|
+
|
47
|
+
it "returns array of symbols" do
|
48
|
+
expect(fields).to be_a Array
|
49
|
+
fields.each do |field|
|
50
|
+
expect(field).to be_a Symbol
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "#first" do
|
56
|
+
let(:product) {Magentwo::Product.first}
|
57
|
+
|
58
|
+
it "returns a product" do
|
59
|
+
expect(product).to be_a Magentwo::Product
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "#types" do
|
64
|
+
let(:types) {Magentwo::Product.types}
|
65
|
+
|
66
|
+
it "returns array" do
|
67
|
+
expect(types).to be_a Array
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "#[]" do
|
72
|
+
let(:first_product) {Magentwo::Product.first}
|
73
|
+
let(:by_sku_product) {Magentwo::Product[first_product.sku]}
|
74
|
+
|
75
|
+
it "returns a product" do
|
76
|
+
expect(by_sku_product).to be_a Magentwo::Product
|
77
|
+
end
|
78
|
+
|
79
|
+
it "returns product by :sku" do
|
80
|
+
expect(first_product.sku).to eq by_sku_product.sku
|
81
|
+
end
|
82
|
+
end
|
4
83
|
end
|
metadata
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: magentwo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- André Mueß
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
date: 2019-01-17 00:00:00.000000000 Z
|
@@ -27,11 +27,14 @@ files:
|
|
27
27
|
- lib/filter.rb
|
28
28
|
- lib/magentwo.rb
|
29
29
|
- lib/model/base.rb
|
30
|
+
- lib/model/cart.rb
|
31
|
+
- lib/model/category.rb
|
30
32
|
- lib/model/coupon.rb
|
31
33
|
- lib/model/customer.rb
|
32
34
|
- lib/model/order.rb
|
33
35
|
- lib/model/product.rb
|
34
36
|
- lib/model/sales_rule.rb
|
37
|
+
- lib/model/stock_item.rb
|
35
38
|
- lib/util/validator.rb
|
36
39
|
- magentwo.gemspec
|
37
40
|
- spec/base_model_spec.rb
|
@@ -43,7 +46,7 @@ licenses:
|
|
43
46
|
- MIT
|
44
47
|
metadata:
|
45
48
|
source_code_uri: https://github.com/Arkad82x/magentwo
|
46
|
-
post_install_message:
|
49
|
+
post_install_message:
|
47
50
|
rdoc_options: []
|
48
51
|
require_paths:
|
49
52
|
- lib
|
@@ -58,8 +61,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
58
61
|
- !ruby/object:Gem::Version
|
59
62
|
version: '0'
|
60
63
|
requirements: []
|
61
|
-
rubygems_version: 3.
|
62
|
-
signing_key:
|
64
|
+
rubygems_version: 3.2.15
|
65
|
+
signing_key:
|
63
66
|
specification_version: 4
|
64
67
|
summary: Magento 2 API Wrapper
|
65
68
|
test_files: []
|