retentiongrid 0.0.5 → 0.1.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.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/lib/retentiongrid.rb +1 -0
- data/lib/retentiongrid/customer.rb +6 -26
- data/lib/retentiongrid/line_item.rb +1 -1
- data/lib/retentiongrid/order.rb +7 -23
- data/lib/retentiongrid/product.rb +49 -3
- data/lib/retentiongrid/resource.rb +42 -0
- data/lib/retentiongrid/version.rb +1 -1
- data/spec/factories/products.rb +19 -0
- data/spec/integration/product_spec.rb +104 -0
- data/spec/models/customer_spec.rb +1 -1
- data/spec/models/product_spec.rb +13 -0
- metadata +9 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 139d14d9aa302cb690c454fa2c470945ccd0a84e
|
|
4
|
+
data.tar.gz: 3bf5cef73bdc80f5e5cd1aacff0afd0d5a7939f4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ffdf894f4a511a2f3e99545f4f0f4e258f2c92c2c8c8155ad951b13b4a970061a77472884c6b16db3aa45cd3a3e1f54d25b9d706a9a3569eb38966bf4e0ced3e
|
|
7
|
+
data.tar.gz: 7168575e837a34e38070fc8732032206991c98123b1bb137a09fea2fa7506750cdceaabd8ad1cb06b6a17e4614e88528c52648b1ddb34e07013363af7bcd0428
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Retentiongrid
|
|
2
2
|
|
|
3
3
|
[](http://badge.fury.io/rb/retentiongrid)
|
|
4
4
|
[](https://travis-ci.org/christoph-buente/retentiongrid)
|
|
@@ -18,7 +18,7 @@ Add this line to your application's Gemfile:
|
|
|
18
18
|
|
|
19
19
|
And then execute:
|
|
20
20
|
|
|
21
|
-
$ bundle
|
|
21
|
+
$ bundle install
|
|
22
22
|
|
|
23
23
|
Or install it yourself as:
|
|
24
24
|
|
data/lib/retentiongrid.rb
CHANGED
|
@@ -8,9 +8,11 @@ module Retentiongrid
|
|
|
8
8
|
# To get a order from the API:
|
|
9
9
|
# customer = Retentiongrid::Customer.find('C123')
|
|
10
10
|
#
|
|
11
|
-
class Customer
|
|
11
|
+
class Customer < Resource
|
|
12
12
|
include ActiveModel::Validations
|
|
13
13
|
|
|
14
|
+
BASE_PATH = '/customers'
|
|
15
|
+
|
|
14
16
|
# The set of attributes defined by the API documentation
|
|
15
17
|
ATTRIBUTES_NAMES = [ :customer_id, :full_name, :first_name, :email,
|
|
16
18
|
:country, :state, :city, :postal_code, :tags,
|
|
@@ -22,12 +24,6 @@ module Retentiongrid
|
|
|
22
24
|
|
|
23
25
|
validates :customer_id, :full_name, presence: true
|
|
24
26
|
|
|
25
|
-
def initialize(attribs={})
|
|
26
|
-
attribs.each do |attrib, value|
|
|
27
|
-
self.send("#{attrib}=", value)
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
27
|
# API Stuff here
|
|
32
28
|
|
|
33
29
|
# Find a customer with given id
|
|
@@ -35,42 +31,26 @@ module Retentiongrid
|
|
|
35
31
|
# @return [Customer] if found any
|
|
36
32
|
def self.find(customer_id)
|
|
37
33
|
begin
|
|
38
|
-
result = Api.get("
|
|
34
|
+
result = Api.get("#{BASE_PATH}/#{customer_id}")
|
|
39
35
|
new(result.parsed_response["rg_customer"])
|
|
40
36
|
rescue NotFound
|
|
41
37
|
nil
|
|
42
38
|
end
|
|
43
39
|
end
|
|
44
40
|
|
|
45
|
-
# Create or update a customer with given id
|
|
46
|
-
# @return [Boolean] successfully created or updated?
|
|
47
|
-
def save
|
|
48
|
-
!!(save!) rescue false
|
|
49
|
-
end
|
|
50
|
-
|
|
51
41
|
# Create or update a customer with given id
|
|
52
42
|
# @return [Customer] if successfully created or updated
|
|
53
43
|
# @raise [Httparty::Error] for all sorts of HTTP statuses.
|
|
54
44
|
def save!
|
|
55
|
-
result = Api.post("
|
|
45
|
+
result = Api.post("#{BASE_PATH}/#{customer_id}", body: attributes.to_json)
|
|
56
46
|
Customer.new(result.parsed_response["rg_customer"])
|
|
57
47
|
end
|
|
58
48
|
|
|
59
49
|
# Delete this customer at retention grid
|
|
60
50
|
# @return [Boolean] successfully deleted?
|
|
61
51
|
def destroy
|
|
62
|
-
Api.delete("
|
|
52
|
+
Api.delete("#{BASE_PATH}/#{customer_id}")
|
|
63
53
|
true
|
|
64
54
|
end
|
|
65
|
-
|
|
66
|
-
# Return all attributes as a hash
|
|
67
|
-
# @return [Hash]
|
|
68
|
-
def attributes
|
|
69
|
-
ATTRIBUTES_NAMES.inject({}) do |attribs, attrib_name|
|
|
70
|
-
value = self.send(attrib_name)
|
|
71
|
-
attribs[attrib_name] = value unless value.nil?
|
|
72
|
-
attribs
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
55
|
end
|
|
76
56
|
end
|
data/lib/retentiongrid/order.rb
CHANGED
|
@@ -7,9 +7,11 @@ module Retentiongrid
|
|
|
7
7
|
# To get a order from the API:
|
|
8
8
|
# order = Retentiongrid::Order.find('A123')
|
|
9
9
|
#
|
|
10
|
-
class Order
|
|
10
|
+
class Order < Resource
|
|
11
11
|
include ActiveModel::Validations
|
|
12
12
|
|
|
13
|
+
BASE_PATH = '/orders'
|
|
14
|
+
|
|
13
15
|
# The set of attributes defined by the API documentation
|
|
14
16
|
ATTRIBUTES_NAMES = [ :order_id, :customer_id, :status, :total_price, :total_discounts,
|
|
15
17
|
:currency, :canceled_shipped, :canceled_shop_fault, :order_created_at
|
|
@@ -24,9 +26,7 @@ module Retentiongrid
|
|
|
24
26
|
validates :order_id, :customer_id, :currency, :total_price, :order_created_at, presence: true
|
|
25
27
|
|
|
26
28
|
def initialize(attribs={})
|
|
27
|
-
|
|
28
|
-
self.send("#{attrib}=", value)
|
|
29
|
-
end
|
|
29
|
+
super
|
|
30
30
|
@order_created_at = Time.parse(order_created_at) unless order_created_at.nil?
|
|
31
31
|
end
|
|
32
32
|
|
|
@@ -44,42 +44,26 @@ module Retentiongrid
|
|
|
44
44
|
# @return [Order] if found any
|
|
45
45
|
def self.find(order_id)
|
|
46
46
|
begin
|
|
47
|
-
result = Api.get("
|
|
47
|
+
result = Api.get("#{BASE_PATH}/#{order_id}")
|
|
48
48
|
new(result.parsed_response["rg_order"])
|
|
49
49
|
rescue NotFound
|
|
50
50
|
nil
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
# Create or update an order with given id
|
|
55
|
-
# @return [Boolean] successfully created or updated?
|
|
56
|
-
def save
|
|
57
|
-
!!(save!) rescue false
|
|
58
|
-
end
|
|
59
|
-
|
|
60
54
|
# Create or update an order with given id
|
|
61
55
|
# @return [Order] if successfully created or updated
|
|
62
56
|
# @raise [Httparty::Error] for all sorts of HTTP statuses.
|
|
63
57
|
def save!
|
|
64
|
-
result = Api.post("
|
|
58
|
+
result = Api.post("#{BASE_PATH}/#{order_id}", { body: attributes.to_json })
|
|
65
59
|
Order.new(result.parsed_response["rg_order"])
|
|
66
60
|
end
|
|
67
61
|
|
|
68
62
|
# Delete this order at retention grid
|
|
69
63
|
# @return [Boolean] successfully deleted?
|
|
70
64
|
def destroy
|
|
71
|
-
Api.delete("
|
|
65
|
+
Api.delete("#{BASE_PATH}/#{order_id}")
|
|
72
66
|
true
|
|
73
67
|
end
|
|
74
|
-
|
|
75
|
-
# Return all attributes as a hash
|
|
76
|
-
# @return [Hash]
|
|
77
|
-
def attributes
|
|
78
|
-
ATTRIBUTES_NAMES.inject({}) do |attribs, attrib_name|
|
|
79
|
-
value = self.send(attrib_name)
|
|
80
|
-
attribs[attrib_name] = value unless value.nil?
|
|
81
|
-
attribs
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
68
|
end
|
|
85
69
|
end
|
|
@@ -1,8 +1,54 @@
|
|
|
1
1
|
module Retentiongrid
|
|
2
|
-
class Product
|
|
2
|
+
class Product < Resource
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
BASE_PATH = '/products'
|
|
5
|
+
|
|
6
|
+
# The set of attributes defined by the API documentation
|
|
7
|
+
ATTRIBUTES_NAMES = [ :product_id, :available, :metadata,
|
|
8
|
+
:title, :image_url, :currency, :price,
|
|
9
|
+
:sale_price, :cost_price, :product_url,
|
|
10
|
+
:product_created_at, :product_updated_at
|
|
11
|
+
].freeze
|
|
12
|
+
|
|
13
|
+
ATTRIBUTES_NAMES.each do |attrib|
|
|
14
|
+
attr_accessor attrib
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def initialize(attribs={})
|
|
18
|
+
super
|
|
19
|
+
@product_created_at = Time.parse(product_created_at) unless product_created_at.nil?
|
|
20
|
+
@product_updated_at = Time.parse(product_updated_at) unless product_updated_at.nil?
|
|
6
21
|
end
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# API Stuff here
|
|
25
|
+
|
|
26
|
+
# Find a product with given id
|
|
27
|
+
# @param [Fixnum] product_id the prodct id to be found
|
|
28
|
+
# @return [Product] if found any
|
|
29
|
+
def self.find(product_id)
|
|
30
|
+
begin
|
|
31
|
+
result = Api.get("#{BASE_PATH}/#{product_id}")
|
|
32
|
+
new(result.parsed_response["rg_product"])
|
|
33
|
+
rescue NotFound
|
|
34
|
+
nil
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Create or update a product with given id
|
|
39
|
+
# @return [Product] if successfully created or updated
|
|
40
|
+
# @raise [Httparty::Error] for all sorts of HTTP statuses.
|
|
41
|
+
def save!
|
|
42
|
+
result = Api.post("#{BASE_PATH}/#{product_id}", body: attributes.to_json)
|
|
43
|
+
Product.new(result.parsed_response["rg_product"])
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Delete this product at retention grid
|
|
47
|
+
# @return [Boolean] successfully deleted?
|
|
48
|
+
def destroy
|
|
49
|
+
Api.delete("#{BASE_PATH}/#{product_id}")
|
|
50
|
+
true
|
|
51
|
+
end
|
|
52
|
+
|
|
7
53
|
end
|
|
8
54
|
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Retentiongrid
|
|
2
|
+
|
|
3
|
+
# Retentiongrid Resource
|
|
4
|
+
# Base class for all API resources.
|
|
5
|
+
#
|
|
6
|
+
class Resource
|
|
7
|
+
include ActiveModel::Validations
|
|
8
|
+
|
|
9
|
+
ATTRIBUTES_NAMES = []
|
|
10
|
+
|
|
11
|
+
ATTRIBUTES_NAMES.each do |attrib|
|
|
12
|
+
attr_accessor attrib
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.base_path
|
|
16
|
+
'/'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def initialize(attribs={})
|
|
20
|
+
attribs.each do |attrib, value|
|
|
21
|
+
self.send("#{attrib}=", value)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Create or update a product with given id
|
|
26
|
+
# @return [Boolean] successfully created or updated?
|
|
27
|
+
def save
|
|
28
|
+
!!(save!) rescue false
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Return all attributes as a hash
|
|
32
|
+
# @return [Hash]
|
|
33
|
+
def attributes
|
|
34
|
+
ATTRIBUTES_NAMES.inject({}) do |attribs, attrib_name|
|
|
35
|
+
value = self.send(attrib_name)
|
|
36
|
+
attribs[attrib_name] = value unless value.nil?
|
|
37
|
+
attribs
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
FactoryGirl.define do
|
|
2
|
+
|
|
3
|
+
sequence :product_id do |n|
|
|
4
|
+
n
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
factory :product do
|
|
8
|
+
product_id
|
|
9
|
+
title "A fancy product"
|
|
10
|
+
currency 'EUR'
|
|
11
|
+
price 31.50
|
|
12
|
+
sale_price 30.00
|
|
13
|
+
cost_price 23.00
|
|
14
|
+
available true
|
|
15
|
+
image_url 'http://example.com/images/1.png'
|
|
16
|
+
product_updated_at { Time.now - 86400 }
|
|
17
|
+
product_created_at { Time.now - 161024 }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
include Retentiongrid
|
|
3
|
+
RSpec.describe Product do
|
|
4
|
+
|
|
5
|
+
before do
|
|
6
|
+
WebMock.disable_net_connect!
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def valid_order
|
|
10
|
+
<<-EOF
|
|
11
|
+
{ "rg_product":
|
|
12
|
+
{ "product_id": "123",
|
|
13
|
+
"product_created_at": "2014-03-11 13:35:10",
|
|
14
|
+
"available": true,
|
|
15
|
+
"metadata": "",
|
|
16
|
+
"product_updated_at": "2014-03-12 13:35:10",
|
|
17
|
+
"title": "An awesome product",
|
|
18
|
+
"image_url": "http://example.com/images/large.png",
|
|
19
|
+
"currency": "EUR",
|
|
20
|
+
"price": 169.00,
|
|
21
|
+
"sale_price": 169.00,
|
|
22
|
+
"cost_price": 99.00,
|
|
23
|
+
"product_url": "http://example.com/products/aweseome"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
EOF
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
let(:api) { Api.new }
|
|
30
|
+
|
|
31
|
+
context '#find' do
|
|
32
|
+
|
|
33
|
+
subject do
|
|
34
|
+
stub_request(:get, "http://retentiongrid.apiary-mock.com/products/123").
|
|
35
|
+
to_return(:status => 200, :body => valid_order, :headers => {'Content-Type' => 'application/json'})
|
|
36
|
+
Product.find('123')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "should build a Product from API response" do
|
|
40
|
+
expect(subject.class).to eql Retentiongrid::Product
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should parse product_id correctly" do
|
|
44
|
+
expect(subject.product_id).to eql '123'
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "should parse available correctly" do
|
|
48
|
+
expect(subject.available).to eql true
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should parse title correctly" do
|
|
52
|
+
expect(subject.title).to eql 'An awesome product'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "should parse price correctly" do
|
|
56
|
+
expect(subject.price).to eql 169.0
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should parse sale_price correctly" do
|
|
60
|
+
expect(subject.sale_price).to eql 169.0
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should parse cost_price correctly" do
|
|
64
|
+
expect(subject.cost_price).to eql 99.0
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "should parse currency correctly" do
|
|
68
|
+
expect(subject.currency).to eql "EUR"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should parse product_created_at correctly" do
|
|
72
|
+
expect(subject.product_created_at).to eql Time.parse("2014-03-11 13:35:10")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "should parse product_updated_at correctly" do
|
|
76
|
+
expect(subject.product_updated_at).to eql Time.parse("2014-03-12 13:35:10")
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
context '#create' do
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
context '#delete' do
|
|
85
|
+
|
|
86
|
+
let :product do
|
|
87
|
+
FactoryGirl.build(:product)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
subject do
|
|
91
|
+
FactoryGirl.build(:product)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
before :each do
|
|
95
|
+
stub_request(:delete, "http://retentiongrid.apiary-mock.com/products/#{subject.product_id}").to_return(:status => 204, :body => '')
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "should send delete to API" do
|
|
99
|
+
expect(subject.destroy).to eql true
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: retentiongrid
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Christoph Bünte
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-
|
|
11
|
+
date: 2014-09-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: httparty
|
|
@@ -172,15 +172,19 @@ files:
|
|
|
172
172
|
- lib/retentiongrid/line_item.rb
|
|
173
173
|
- lib/retentiongrid/order.rb
|
|
174
174
|
- lib/retentiongrid/product.rb
|
|
175
|
+
- lib/retentiongrid/resource.rb
|
|
175
176
|
- lib/retentiongrid/version.rb
|
|
176
177
|
- log/.gitkeep
|
|
177
178
|
- retentiongrid.gemspec
|
|
178
179
|
- spec/factories/customers.rb
|
|
179
180
|
- spec/factories/orders.rb
|
|
181
|
+
- spec/factories/products.rb
|
|
180
182
|
- spec/integration/customer_spec.rb
|
|
181
183
|
- spec/integration/order_spec.rb
|
|
184
|
+
- spec/integration/product_spec.rb
|
|
182
185
|
- spec/models/customer_spec.rb
|
|
183
186
|
- spec/models/order_spec.rb
|
|
187
|
+
- spec/models/product_spec.rb
|
|
184
188
|
- spec/spec_helper.rb
|
|
185
189
|
homepage: http://retentiongrid.com/
|
|
186
190
|
licenses:
|
|
@@ -209,9 +213,12 @@ summary: A ruby client for retentiongrid.com API.
|
|
|
209
213
|
test_files:
|
|
210
214
|
- spec/factories/customers.rb
|
|
211
215
|
- spec/factories/orders.rb
|
|
216
|
+
- spec/factories/products.rb
|
|
212
217
|
- spec/integration/customer_spec.rb
|
|
213
218
|
- spec/integration/order_spec.rb
|
|
219
|
+
- spec/integration/product_spec.rb
|
|
214
220
|
- spec/models/customer_spec.rb
|
|
215
221
|
- spec/models/order_spec.rb
|
|
222
|
+
- spec/models/product_spec.rb
|
|
216
223
|
- spec/spec_helper.rb
|
|
217
224
|
has_rdoc:
|