drip-ruby 3.2.0 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -1
  3. data/.rubocop_todo.yml +17 -9
  4. data/.travis.yml +1 -1
  5. data/CHANGELOG.md +20 -1
  6. data/Gemfile +10 -0
  7. data/drip-ruby.gemspec +3 -11
  8. data/lib/drip/client.rb +44 -66
  9. data/lib/drip/client/accounts.rb +2 -2
  10. data/lib/drip/client/broadcasts.rb +2 -2
  11. data/lib/drip/client/campaign_subscriptions.rb +1 -1
  12. data/lib/drip/client/campaigns.rb +5 -5
  13. data/lib/drip/client/configuration.rb +28 -0
  14. data/lib/drip/client/conversions.rb +2 -2
  15. data/lib/drip/client/custom_fields.rb +1 -1
  16. data/lib/drip/client/events.rb +4 -4
  17. data/lib/drip/client/forms.rb +2 -2
  18. data/lib/drip/client/http_client.rb +64 -0
  19. data/lib/drip/client/orders.rb +3 -3
  20. data/lib/drip/client/shopper_activity.rb +78 -0
  21. data/lib/drip/client/subscribers.rb +13 -13
  22. data/lib/drip/client/tags.rb +3 -3
  23. data/lib/drip/client/webhooks.rb +5 -5
  24. data/lib/drip/client/workflow_triggers.rb +3 -3
  25. data/lib/drip/client/workflows.rb +6 -6
  26. data/lib/drip/request.rb +31 -0
  27. data/lib/drip/response.rb +13 -13
  28. data/lib/drip/version.rb +1 -1
  29. data/test/drip/client/configuration_test.rb +122 -0
  30. data/test/drip/client/http_client_test.rb +96 -0
  31. data/test/drip/client/shopper_activity_test.rb +175 -0
  32. data/test/drip/client_test.rb +32 -97
  33. data/test/drip/collection_test.rb +14 -0
  34. data/test/drip/collections/account_test.rb +8 -0
  35. data/test/drip/collections/broadcasts_test.rb +8 -0
  36. data/test/drip/collections/campaign_subscriptions_test.rb +8 -0
  37. data/test/drip/collections/campaigns_test.rb +8 -0
  38. data/test/drip/collections/errors_test.rb +8 -0
  39. data/test/drip/collections/orders_test.rb +8 -0
  40. data/test/drip/collections/purchases_test.rb +8 -0
  41. data/test/drip/collections/tags_test.rb +8 -0
  42. data/test/drip/collections/webhooks_test.rb +8 -0
  43. data/test/drip/collections/workflow_triggers_test.rb +8 -0
  44. data/test/drip/collections/workflows_test.rb +8 -0
  45. data/test/drip/request_test.rb +58 -0
  46. data/test/drip/resource_test.rb +12 -0
  47. data/test/drip/resources/tag_test.rb +13 -0
  48. data/test/drip/response_test.rb +33 -0
  49. data/test/test_helper.rb +3 -0
  50. metadata +42 -104
@@ -0,0 +1,31 @@
1
+ require "net/http"
2
+
3
+ module Drip
4
+ class Request
5
+ attr_reader :http_verb, :url, :options, :content_type
6
+
7
+ VERB_CLASS_MAPPING = {
8
+ get: Net::HTTP::Get,
9
+ post: Net::HTTP::Post,
10
+ put: Net::HTTP::Put,
11
+ delete: Net::HTTP::Delete
12
+ }.freeze
13
+
14
+ def initialize(http_verb, url, options = {}, content_type = nil)
15
+ @http_verb = http_verb
16
+ @url = url
17
+ @options = options
18
+ @content_type = content_type
19
+ end
20
+
21
+ def verb_klass
22
+ VERB_CLASS_MAPPING[http_verb]
23
+ end
24
+
25
+ def body
26
+ return if http_verb == :get
27
+
28
+ options.to_json
29
+ end
30
+ end
31
+ end
@@ -44,20 +44,20 @@ module Drip
44
44
  end
45
45
 
46
46
  def parse_members
47
- if status == 429
48
- body
49
- else
50
- {}.tap do |members|
51
- if body.is_a?(Hash)
52
- body.each do |key, value|
53
- klass = if value.is_a?(Array)
54
- Drip::Collections.find_class(key)
55
- else
56
- Drip::Resources.find_class(key)
57
- end
47
+ return body unless success?
48
+ {}.tap do |members|
49
+ if body.is_a?(Hash)
50
+ body.each do |key, value|
51
+ klass = case value
52
+ when Array
53
+ Drip::Collections.find_class(key)
54
+ when String
55
+ String
56
+ else
57
+ Drip::Resources.find_class(key)
58
+ end
58
59
 
59
- members[key] = klass.new(value)
60
- end
60
+ members[key] = klass.new(value)
61
61
  end
62
62
  end
63
63
  end
@@ -1,3 +1,3 @@
1
1
  module Drip
2
- VERSION = "3.2.0".freeze
2
+ VERSION = "3.3.0".freeze
3
3
  end
@@ -0,0 +1,122 @@
1
+ require File.dirname(__FILE__) + '/../../test_helper.rb'
2
+ require "drip/client/configuration"
3
+
4
+ class Drip::Client::ConfigurationTest < Drip::TestCase
5
+ context "#initializer" do
6
+ context "with reasonable parameters" do
7
+ should "accept parameters" do
8
+ config = Drip::Client::Configuration.new(access_token: "123")
9
+ assert_equal "123", config.access_token
10
+ end
11
+ end
12
+
13
+ context "with one additional parameter" do
14
+ should "raise singular error" do
15
+ err = assert_raises(ArgumentError) { Drip::Client::Configuration.new(blahdeblah: "123") }
16
+ assert_equal "unknown keyword: blahdeblah", err.message
17
+ end
18
+
19
+ should "match core ruby behavior" do
20
+ def test_method(hello: "test"); end
21
+ err = assert_raises(ArgumentError) { test_method(blahdeblah: "123") }
22
+ assert_equal "unknown keyword: blahdeblah", err.message
23
+ end
24
+ end
25
+
26
+ context "with multiple additional parameters" do
27
+ should "raise plural error" do
28
+ err = assert_raises(ArgumentError) { Drip::Client::Configuration.new(blahdeblah: "123", blahdeblah1: "123") }
29
+ assert_equal "unknown keywords: blahdeblah, blahdeblah1", err.message
30
+ end
31
+
32
+ should "match core ruby behavior" do
33
+ def test_method(hello: "test"); end
34
+ err = assert_raises(ArgumentError) { test_method(blahdeblah: "123", blahdeblah1: "123") }
35
+ assert_equal "unknown keywords: blahdeblah, blahdeblah1", err.message
36
+ end
37
+ end
38
+ end
39
+
40
+ context "#url_prefix" do
41
+ should "have default url prefix" do
42
+ config = Drip::Client::Configuration.new
43
+ assert_equal "https://api.getdrip.com/", config.url_prefix
44
+ end
45
+
46
+ should "accept passed parameter" do
47
+ config = Drip::Client::Configuration.new(url_prefix: "https://www.example.com/")
48
+ assert_equal "https://www.example.com/", config.url_prefix
49
+ end
50
+
51
+ should "allow setter" do
52
+ config = Drip::Client::Configuration.new
53
+ config.url_prefix = "https://www.example.com/"
54
+ assert_equal "https://www.example.com/", config.url_prefix
55
+ end
56
+ end
57
+
58
+ context "#access_token" do
59
+ should "accept passed parameter" do
60
+ config = Drip::Client::Configuration.new(access_token: "blah")
61
+ assert_equal "blah", config.access_token
62
+ end
63
+
64
+ should "allow setter" do
65
+ config = Drip::Client::Configuration.new
66
+ config.access_token = "blah"
67
+ assert_equal "blah", config.access_token
68
+ end
69
+ end
70
+
71
+ context "#api_key" do
72
+ should "accept passed parameter" do
73
+ config = Drip::Client::Configuration.new(api_key: "blah")
74
+ assert_equal "blah", config.api_key
75
+ end
76
+
77
+ should "allow setter" do
78
+ config = Drip::Client::Configuration.new
79
+ config.api_key = "blah"
80
+ assert_equal "blah", config.api_key
81
+ end
82
+ end
83
+
84
+ context "#account_id" do
85
+ should "accept passed parameter" do
86
+ config = Drip::Client::Configuration.new(account_id: "1234567")
87
+ assert_equal "1234567", config.account_id
88
+ end
89
+
90
+ should "allow setter" do
91
+ config = Drip::Client::Configuration.new
92
+ config.account_id = "1234567"
93
+ assert_equal "1234567", config.account_id
94
+ end
95
+ end
96
+
97
+ context "#http_open_timeout" do
98
+ should "accept passed parameter" do
99
+ config = Drip::Client::Configuration.new(http_open_timeout: 12)
100
+ assert_equal 12, config.http_open_timeout
101
+ end
102
+
103
+ should "allow setter" do
104
+ config = Drip::Client::Configuration.new
105
+ config.http_open_timeout = 12
106
+ assert_equal 12, config.http_open_timeout
107
+ end
108
+ end
109
+
110
+ context "#http_timeout" do
111
+ should "accept passed parameter" do
112
+ config = Drip::Client::Configuration.new(http_timeout: 42)
113
+ assert_equal 42, config.http_timeout
114
+ end
115
+
116
+ should "allow setter" do
117
+ config = Drip::Client::Configuration.new
118
+ config.http_timeout = 42
119
+ assert_equal 42, config.http_timeout
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,96 @@
1
+ require File.dirname(__FILE__) + '/../../test_helper.rb'
2
+ require "drip/client/configuration"
3
+ require "drip/client/http_client"
4
+ require "drip/request"
5
+
6
+ class Drip::Client::HTTPClientTest < Drip::TestCase
7
+ context "given a personal api key" do
8
+ setup do
9
+ @key = "aaaa"
10
+ @config = Drip::Client::Configuration.new(api_key: @key)
11
+ @client = Drip::Client::HTTPClient.new(@config)
12
+ end
13
+
14
+ should "use Basic authentication" do
15
+ stub_request(:get, "https://api.getdrip.com/v2/testpath").
16
+ to_return(status: 200, body: "", headers: {})
17
+
18
+ @client.make_request(Drip::Request.new(:get, URI("https://api.getdrip.com/v2/testpath")))
19
+
20
+ header = "Basic #{Base64.encode64(@key + ':')}".strip
21
+ assert_requested :get, "https://api.getdrip.com/v2/testpath", headers: { 'Authorization' => header }
22
+ end
23
+ end
24
+
25
+ context "given a OAuth access token" do
26
+ setup do
27
+ @key = "aaaa"
28
+ @config = Drip::Client::Configuration.new(access_token: @key)
29
+ @client = Drip::Client::HTTPClient.new(@config)
30
+ end
31
+
32
+ should "use Bearer token authentication" do
33
+ stub_request(:get, "https://api.getdrip.com/v2/testpath").
34
+ to_return(status: 200, body: "", headers: {})
35
+ @client.make_request(Drip::Request.new(:get, URI("https://api.getdrip.com/v2/testpath")))
36
+ header = "Bearer #{@key}"
37
+ assert_requested :get, "https://api.getdrip.com/v2/testpath", headers: { 'Authorization' => header }
38
+ end
39
+ end
40
+
41
+ context "given a redirecting url" do
42
+ setup do
43
+ @config = Drip::Client::Configuration.new
44
+ @client = Drip::Client::HTTPClient.new(@config)
45
+ end
46
+
47
+ should "follow redirect" do
48
+ stub_request(:get, "https://api.getdrip.com/v2/testpath").
49
+ to_return(status: 301, body: "", headers: { "Location" => "https://api.example.com/mytestpath" })
50
+ stub_request(:get, "https://api.example.com/mytestpath").
51
+ to_return(status: 200, body: "{}")
52
+ response = @client.make_request(Drip::Request.new(:get, URI("https://api.getdrip.com/v2/testpath")))
53
+ assert_requested :get, "https://api.getdrip.com/v2/testpath"
54
+ assert_requested :get, "https://api.example.com/mytestpath"
55
+ assert_equal("{}", response.body)
56
+ end
57
+
58
+ should "not follow too many redirects" do
59
+ stub_request(:get, "https://api.getdrip.com/v2/accounts").
60
+ to_return(status: 301, body: "", headers: { "Location" => "https://api.example.com/mytestpath" })
61
+ stub_request(:get, "https://api.example.com/mytestpath").
62
+ to_return(status: 302, body: "", headers: { "Location" => "https://api.getdrip.com/v2/accounts" })
63
+ assert_raises(Drip::TooManyRedirectsError) { @client.make_request(Drip::Request.new(:get, URI("https://api.getdrip.com/v2/accounts"))) }
64
+ assert_requested :get, "https://api.getdrip.com/v2/accounts", times: 5
65
+ assert_requested :get, "https://api.example.com/mytestpath", times: 5
66
+ end
67
+ end
68
+
69
+ context "given a get request" do
70
+ setup do
71
+ @config = Drip::Client::Configuration.new(http_open_timeout: 20)
72
+ @client = Drip::Client::HTTPClient.new(@config)
73
+ @response = mock
74
+ @response.stubs(:code).returns('200')
75
+ @response.stubs(:body).returns('{}')
76
+
77
+ @http = mock
78
+ @http.expects(:request).returns(@response)
79
+
80
+ @request = mock
81
+ @request.stubs(:[]=)
82
+ @request.stubs(:basic_auth)
83
+ end
84
+
85
+ should "encode query and not set body" do
86
+ Net::HTTP::Get.expects(:new).returns(@request)
87
+ Net::HTTP.expects(:start).yields(@http).returns(@response)
88
+
89
+ @request.expects(:body=).with(nil)
90
+ URI.expects(:encode_www_form).once
91
+
92
+ response = @client.make_request(Drip::Request.new(:get, URI("https://api.getdrip.com/v2/testpath")))
93
+ assert_equal("{}", response.body)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,175 @@
1
+ require File.dirname(__FILE__) + '/../../test_helper.rb'
2
+
3
+ class Drip::Client::ShopperActivityTest < Drip::TestCase
4
+ def setup
5
+ @client = Drip::Client.new { |c| c.account_id = "12345" }
6
+ end
7
+
8
+ context "#create_cart_activity_event" do
9
+ setup do
10
+ @email = "drippy@drip.com"
11
+ @options = {
12
+ email: @email,
13
+ action: "created",
14
+ provider: "shopify",
15
+ cart_id: "abcdef",
16
+ cart_url: "https://www.example.com/mythingy",
17
+ amount: 4900,
18
+ tax: 100,
19
+ fees: 0,
20
+ discount: 0,
21
+ currency_code: "USD",
22
+ properties: {
23
+ "size" => "medium",
24
+ "color" => "red"
25
+ }
26
+ }
27
+ @response_status = 202
28
+ @response_body = "{}"
29
+
30
+ stub_request(:post, "https://api.getdrip.com/v3/12345/shopper_activity/cart").
31
+ with(headers: { "Content-Type" => "application/json" }).
32
+ to_return(status: @response_status, body: @response_body, headers: {})
33
+ end
34
+
35
+ should "send the right request" do
36
+ expected = Drip::Response.new(@response_status, JSON.parse(@response_body))
37
+ assert_equal expected, @client.create_cart_activity_event(@options)
38
+ end
39
+
40
+ should "return error when missing fields" do
41
+ @options.delete(:cart_id)
42
+ assert_raises(ArgumentError) { @client.create_cart_activity_event(@options) }
43
+ end
44
+ end
45
+
46
+ context "#create_order_activity_event" do
47
+ setup do
48
+ @email = "drippy@drip.com"
49
+ @options = {
50
+ email: @email,
51
+ action: "created",
52
+ provider: "shopify",
53
+ order_id: "abcdef",
54
+ amount: 4900,
55
+ tax: 100,
56
+ fees: 0,
57
+ discount: 0,
58
+ currency_code: "USD",
59
+ properties: {
60
+ "size" => "medium",
61
+ "color" => "red"
62
+ }
63
+ }
64
+ @response_status = 202
65
+ @response_body = "{}"
66
+
67
+ stub_request(:post, "https://api.getdrip.com/v3/12345/shopper_activity/order").
68
+ with(headers: { "Content-Type" => "application/json" }).
69
+ to_return(status: @response_status, body: @response_body, headers: {})
70
+ end
71
+
72
+ should "send the right request" do
73
+ expected = Drip::Response.new(@response_status, JSON.parse(@response_body))
74
+ assert_equal expected, @client.create_order_activity_event(@options)
75
+ end
76
+
77
+ should "return error when missing fields" do
78
+ @options.delete(:order_id)
79
+ assert_raises(ArgumentError) { @client.create_order_activity_event(@options) }
80
+ end
81
+ end
82
+
83
+ context "#create_order_activity_events" do
84
+ setup do
85
+ @records = [
86
+ {
87
+ email: "drippy@example.com",
88
+ action: "created",
89
+ provider: "shopify",
90
+ order_id: "abcdef",
91
+ amount: 4900,
92
+ tax: 100,
93
+ fees: 0,
94
+ discount: 0,
95
+ currency_code: "USD",
96
+ properties: {
97
+ "size" => "medium",
98
+ "color" => "red"
99
+ }
100
+ },
101
+ {
102
+ email: "drippy1@example.com",
103
+ action: "created",
104
+ provider: "shopify",
105
+ order_id: "fdsgs",
106
+ amount: 4900,
107
+ tax: 100,
108
+ fees: 0,
109
+ discount: 0,
110
+ currency_code: "USD",
111
+ properties: {
112
+ "size" => "medium",
113
+ "color" => "red"
114
+ }
115
+ }
116
+ ]
117
+ @response_status = 202
118
+ @response_body = "{}"
119
+
120
+ stub_request(:post, "https://api.getdrip.com/v3/12345/shopper_activity/order/batch").
121
+ with(headers: { "Content-Type" => "application/json" }).
122
+ to_return(status: @response_status, body: @response_body, headers: {})
123
+ end
124
+
125
+ should "send the right request" do
126
+ expected = Drip::Response.new(@response_status, JSON.parse(@response_body))
127
+ assert_equal expected, @client.create_order_activity_events(@records)
128
+ end
129
+
130
+ should "return error when missing fields" do
131
+ @records[1].delete(:order_id)
132
+ err = assert_raises(ArgumentError) { @client.create_order_activity_events(@records) }
133
+ assert_equal "order_id: parameter required in record 1", err.message
134
+ end
135
+ end
136
+
137
+ context "#create_product_activity_event" do
138
+ setup do
139
+ @email = "drippy@drip.com"
140
+ @options = {
141
+ provider: "my_custom_platform",
142
+ action: "created",
143
+ occurred_at: "2019-01-28T12:15:23Z",
144
+ product_id: "B01J4SWO1G",
145
+ product_variant_id: "B01J4SWO1G-CW-BOTT",
146
+ sku: "XHB-1234",
147
+ name: "The Coolest Water Bottle",
148
+ brand: "Drip",
149
+ categories: [
150
+ "Accessories"
151
+ ],
152
+ price: 11.16,
153
+ inventory: 42,
154
+ product_url: "https://mysuperstore.example.com/dp/B01J4SWO1G",
155
+ image_url: "https://www.getdrip.com/images/example_products/water_bottle.png"
156
+ }
157
+ @response_status = 202
158
+ @response_body = "{}"
159
+
160
+ stub_request(:post, "https://api.getdrip.com/v3/12345/shopper_activity/product").
161
+ with(headers: { "Content-Type" => "application/json" }).
162
+ to_return(status: @response_status, body: @response_body, headers: {})
163
+ end
164
+
165
+ should "send the right request" do
166
+ expected = Drip::Response.new(@response_status, JSON.parse(@response_body))
167
+ assert_equal expected, @client.create_product_activity_event(@options)
168
+ end
169
+
170
+ should "return error when missing fields" do
171
+ @options.delete(:product_id)
172
+ assert_raises(ArgumentError) { @client.create_product_activity_event(@options) }
173
+ end
174
+ end
175
+ end