chartmogul-ruby 1.7.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +44 -0
  3. data/.rspec +0 -0
  4. data/2.0-Upgrade.md +9 -0
  5. data/README.md +8 -2
  6. data/changelog.md +14 -0
  7. data/chartmogul-ruby.gemspec +1 -1
  8. data/fixtures/vcr_cassettes/ChartMogul_Customer/API_Interactions/correctly_interracts_with_the_API.yml +67 -119
  9. data/fixtures/vcr_cassettes/ChartMogul_Metrics_ActivitiesExport/get_activities_export.yml +43 -0
  10. data/fixtures/vcr_cassettes/ChartMogul_Metrics_ActivitiesExport/post_activities_export.yml +83 -0
  11. data/fixtures/vcr_cassettes/ChartMogul_Metrics_Activity.yml +37 -0
  12. data/fixtures/vcr_cassettes/ChartMogul_Metrics_Activity/behaves_like_PageableWithAnchor/should_be_pageable.yml +44 -0
  13. data/fixtures/vcr_cassettes/ChartMogul_Metrics_Activity/should_have_Activity_entries.yml +17 -14
  14. data/fixtures/vcr_cassettes/{ChartMogul_Metrics_Activity → ChartMogul_Metrics_Customers_Activity}/behaves_like_Pageable/should_be_pageable.yml +0 -0
  15. data/fixtures/vcr_cassettes/ChartMogul_Metrics_Customers_Activity/should_have_Activity_entries.yml +41 -0
  16. data/fixtures/vcr_cassettes/{ChartMogul_Metrics_Subscription → ChartMogul_Metrics_Customers_Subscription}/behaves_like_Pageable/should_be_pageable.yml +0 -0
  17. data/fixtures/vcr_cassettes/{ChartMogul_Metrics_Subscription → ChartMogul_Metrics_Customers_Subscription}/should_have_Subscription_entries.yml +0 -0
  18. data/lib/chartmogul.rb +10 -3
  19. data/lib/chartmogul/api/actions/all.rb +1 -1
  20. data/lib/chartmogul/api/actions/create.rb +2 -2
  21. data/lib/chartmogul/api/actions/custom.rb +1 -1
  22. data/lib/chartmogul/api/actions/retrieve.rb +2 -1
  23. data/lib/chartmogul/api/actions/update.rb +2 -2
  24. data/lib/chartmogul/api_resource.rb +8 -4
  25. data/lib/chartmogul/concerns/pageable_with_anchor.rb +14 -0
  26. data/lib/chartmogul/config_attributes.rb +17 -1
  27. data/lib/chartmogul/customer.rb +2 -2
  28. data/lib/chartmogul/metrics/activities_export.rb +38 -0
  29. data/lib/chartmogul/metrics/activity.rb +12 -8
  30. data/lib/chartmogul/metrics/customers/activity.rb +38 -0
  31. data/lib/chartmogul/metrics/customers/subscription.rb +41 -0
  32. data/lib/chartmogul/utils/hash_snake_caser.rb +9 -2
  33. data/lib/chartmogul/utils/json_parser.rb +2 -4
  34. data/lib/chartmogul/version.rb +1 -1
  35. data/pre-commit.example +0 -0
  36. metadata +18 -9
  37. data/.travis.yml +0 -25
  38. data/lib/chartmogul/metrics/subscription.rb +0 -39
@@ -0,0 +1,83 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.chartmogul.com/v1/activities_export
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"start-date":"2020-01-01T00:00:00Z","end-date":"2020-12-31T00:00:00Z","type":"new_biz"}'
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v1.0.1
12
+ Content-Type:
13
+ - application/json
14
+ Authorization:
15
+ - Basic hidden
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ server:
22
+ - nginx/1.10.1
23
+ date:
24
+ - Fri, 09 Jul 2021 14:37:32 GMT
25
+ content-type:
26
+ - application/json
27
+ transfer-encoding:
28
+ - chunked
29
+ connection:
30
+ - keep-alive
31
+ vary:
32
+ - Accept-Encoding, Accept-Encoding
33
+ status:
34
+ - 200 OK
35
+ access-control-allow-credentials:
36
+ - 'true'
37
+ body:
38
+ encoding: ASCII-8BIT
39
+ string: '{"id":"17042239-3674-4a61-b838-b6b307f28506","status":"pending","file_url":null,"params":{"kind":"activities","params":{"activity_type":"new_biz","start_date":"2020-01-01
40
+ 00:00:00 +0000","end_date":"2020-12-31 00:00:00 +0000"}},"expires_at":null,"created_at":"2021-07-09T14:37:32+00:00"}'
41
+ http_version:
42
+ recorded_at: Fri, 09 Jul 2021 14:37:32 GMT
43
+ - request:
44
+ method: get
45
+ uri: https://api.chartmogul.com/v1/activities_export/17042239-3674-4a61-b838-b6b307f28506
46
+ body:
47
+ encoding: US-ASCII
48
+ string: ''
49
+ headers:
50
+ User-Agent:
51
+ - Faraday v1.0.1
52
+ Content-Type:
53
+ - application/json
54
+ Authorization:
55
+ - Basic hidden
56
+ response:
57
+ status:
58
+ code: 200
59
+ message: OK
60
+ headers:
61
+ server:
62
+ - nginx/1.10.1
63
+ date:
64
+ - Fri, 09 Jul 2021 14:38:10 GMT
65
+ content-type:
66
+ - application/json
67
+ transfer-encoding:
68
+ - chunked
69
+ connection:
70
+ - keep-alive
71
+ vary:
72
+ - Accept-Encoding, Accept-Encoding
73
+ status:
74
+ - 200 OK
75
+ access-control-allow-credentials:
76
+ - 'true'
77
+ body:
78
+ encoding: ASCII-8BIT
79
+ string: '{"id":"17042239-3674-4a61-b838-b6b307f28506","status":"succeeded","file_url":"https://chartmogul-customer-export.s3.eu-west-1.amazonaws.com/activities-acme-corp-062ea48c-5d74-46dd-bd60-23206cdc241a.zip?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Credential=123%2Feu-west-1%2Fs3%2Faws4_request\u0026X-Amz-Date=20210709T135547Z\u0026X-Amz-Expires=604800\u0026X-Amz-SignedHeaders=host\u0026X-Amz-Signature=abc","params":{"kind":"activities","params":{"end_date":"2020-12-31
80
+ 00:00:00 +0000","start_date":"2020-01-01 00:00:00 +0000","activity_type":"new_biz"}},"expires_at":"2021-07-16T14:37:43+00:00","created_at":"2021-07-09T14:37:32+00:00"}'
81
+ http_version:
82
+ recorded_at: Fri, 09 Jul 2021 14:38:10 GMT
83
+ recorded_with: VCR 5.1.0
@@ -0,0 +1,37 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.chartmogul.com/v1/activities
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v1.0.1
12
+ Content-Type:
13
+ - application/json
14
+ Authorization:
15
+ - Basic hidden
16
+ response:
17
+ status:
18
+ code: 401
19
+ message: Unauthorized
20
+ headers:
21
+ server:
22
+ - nginx/1.10.1
23
+ date:
24
+ - Fri, 18 Jun 2021 10:37:37 GMT
25
+ content-type:
26
+ - application/json
27
+ transfer-encoding:
28
+ - chunked
29
+ connection:
30
+ - keep-alive
31
+ status:
32
+ - 401 Unauthorized
33
+ body:
34
+ encoding: UTF-8
35
+ string: '{"code":401,"message":"No valid API key provided","param":null}'
36
+ recorded_at: Fri, 18 Jun 2021 10:37:37 GMT
37
+ recorded_with: VCR 6.0.0
@@ -0,0 +1,44 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.chartmogul.com/v1/activities?per_page=2
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v1.0.1
12
+ Content-Type:
13
+ - application/json
14
+ Authorization:
15
+ - Basic hidden
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ server:
22
+ - nginx/1.10.1
23
+ date:
24
+ - Fri, 18 Jun 2021 11:59:07 GMT
25
+ content-type:
26
+ - application/json
27
+ transfer-encoding:
28
+ - chunked
29
+ connection:
30
+ - keep-alive
31
+ vary:
32
+ - Accept-Encoding, Accept-Encoding
33
+ status:
34
+ - 200 OK
35
+ access-control-allow-credentials:
36
+ - 'true'
37
+ body:
38
+ encoding: ASCII-8BIT
39
+ string: '{"entries":[{"description":"purchased the Basic1 plan","activity-mrr-movement":4478,"activity-mrr":4478,"activity-arr":53736,"date":"2016-08-01T06:28:25+00:00","type":"new_biz","currency":"EUR","subscription-external-id":"si_18dZuXAN0YShtow4jjqxxNnW","plan-external-id":"a3e832e1-1bd1-4889-8466-8efdbfbdd94b","customer-name":"Customer
40
+ for test@example.com","customer-uuid":"6456e930-8c8e-11eb-a506-0ff43d2cc026","customer-external-id":"cus_8vQm8XjeEOw75p","billing-connector-uuid":"decdeb4c-8c8d-11eb-a506-b3974867f58c","uuid":"2f545d5f-f241-458c-8e99-38c0e5a6e6ff"},{"description":"purchased
41
+ the Basic1 plan","activity-mrr-movement":4425,"activity-mrr":4425,"activity-arr":53100,"date":"2016-08-17T09:28:10+00:00","type":"new_biz","currency":"EUR","subscription-external-id":"si_18jQLGAN0YShtow4kFWpOMVX","plan-external-id":"a3e832e1-1bd1-4889-8466-8efdbfbdd94b","customer-name":"Customer
42
+ for test@example.com","customer-uuid":"63ad1285-8c8e-11eb-a506-47d6b1cc7553","customer-external-id":"cus_91TH9rjhhYCpai","billing-connector-uuid":"decdeb4c-8c8d-11eb-a506-b3974867f58c","uuid":"9d5ba7fd-e06d-4750-a8f6-2983f3a30fb2"}],"has_more":true,"per_page":2}'
43
+ recorded_at: Fri, 18 Jun 2021 11:59:07 GMT
44
+ recorded_with: VCR 6.0.0
@@ -2,13 +2,13 @@
2
2
  http_interactions:
3
3
  - request:
4
4
  method: get
5
- uri: https://api.chartmogul.com/v1/customers/cus_91af761e-9d0a-11e5-b514-1feab446feac/activities
5
+ uri: https://api.chartmogul.com/v1/activities?per_page=2
6
6
  body:
7
7
  encoding: US-ASCII
8
8
  string: ''
9
9
  headers:
10
10
  User-Agent:
11
- - Faraday v0.9.2
11
+ - Faraday v1.0.1
12
12
  Content-Type:
13
13
  - application/json
14
14
  Authorization:
@@ -16,26 +16,29 @@ http_interactions:
16
16
  response:
17
17
  status:
18
18
  code: 200
19
- message:
19
+ message: OK
20
20
  headers:
21
21
  server:
22
- - nginx/1.9.10
22
+ - nginx/1.10.1
23
23
  date:
24
- - Fri, 01 Jul 2016 14:47:49 GMT
24
+ - Fri, 18 Jun 2021 11:59:07 GMT
25
25
  content-type:
26
26
  - application/json
27
- content-length:
28
- - '278'
27
+ transfer-encoding:
28
+ - chunked
29
29
  connection:
30
- - close
30
+ - keep-alive
31
+ vary:
32
+ - Accept-Encoding, Accept-Encoding
31
33
  status:
32
34
  - 200 OK
33
35
  access-control-allow-credentials:
34
36
  - 'true'
35
37
  body:
36
- encoding: UTF-8
37
- string: '{"entries":[{"id":16664702,"description":"purchased the Yael Cohen
38
- plan","activity-mrr-movement":10871,"activity-mrr":10871,"activity-arr":130452,"date":"2015-04-16T13:38:29+00:00","type":"new_biz","currency":"USD","currency-sign":"$","subscription_external_id":"si_IJxVS1c1TjSB0s"}],"has_more":false,"per_page":200,"page":1}'
39
- http_version:
40
- recorded_at: Fri, 01 Jul 2016 14:47:49 GMT
41
- recorded_with: VCR 3.0.3
38
+ encoding: ASCII-8BIT
39
+ string: '{"entries":[{"description":"purchased the Basic1 plan","activity-mrr-movement":4478,"activity-mrr":4478,"activity-arr":53736,"date":"2016-08-01T06:28:25+00:00","type":"new_biz","currency":"EUR","subscription-external-id":"si_18dZuXAN0YShtow4jjqxxNnW","plan-external-id":"a3e832e1-1bd1-4889-8466-8efdbfbdd94b","customer-name":"Customer
40
+ for test@example.com","customer-uuid":"6456e930-8c8e-11eb-a506-0ff43d2cc026","customer-external-id":"cus_8vQm8XjeEOw75p","billing-connector-uuid":"decdeb4c-8c8d-11eb-a506-b3974867f58c","uuid":"2f545d5f-f241-458c-8e99-38c0e5a6e6ff"},{"description":"purchased
41
+ the Basic1 plan","activity-mrr-movement":4425,"activity-mrr":4425,"activity-arr":53100,"date":"2016-08-17T09:28:10+00:00","type":"new_biz","currency":"EUR","subscription-external-id":"si_18jQLGAN0YShtow4kFWpOMVX","plan-external-id":"a3e832e1-1bd1-4889-8466-8efdbfbdd94b","customer-name":"Customer
42
+ for test@example.com","customer-uuid":"63ad1285-8c8e-11eb-a506-47d6b1cc7553","customer-external-id":"cus_91TH9rjhhYCpai","billing-connector-uuid":"decdeb4c-8c8d-11eb-a506-b3974867f58c","uuid":"9d5ba7fd-e06d-4750-a8f6-2983f3a30fb2"}],"has_more":true,"per_page":2}'
43
+ recorded_at: Fri, 18 Jun 2021 11:59:07 GMT
44
+ recorded_with: VCR 6.0.0
@@ -0,0 +1,41 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.chartmogul.com/v1/customers/cus_91af761e-9d0a-11e5-b514-1feab446feac/activities
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.9.2
12
+ Content-Type:
13
+ - application/json
14
+ Authorization:
15
+ - Basic hidden
16
+ response:
17
+ status:
18
+ code: 200
19
+ message:
20
+ headers:
21
+ server:
22
+ - nginx/1.9.10
23
+ date:
24
+ - Fri, 01 Jul 2016 14:47:49 GMT
25
+ content-type:
26
+ - application/json
27
+ content-length:
28
+ - '278'
29
+ connection:
30
+ - close
31
+ status:
32
+ - 200 OK
33
+ access-control-allow-credentials:
34
+ - 'true'
35
+ body:
36
+ encoding: UTF-8
37
+ string: '{"entries":[{"id":16664702,"description":"purchased the Yael Cohen
38
+ plan","activity-mrr-movement":10871,"activity-mrr":10871,"activity-arr":130452,"date":"2015-04-16T13:38:29+00:00","type":"new_biz","currency":"USD","currency-sign":"$","subscription_external_id":"si_IJxVS1c1TjSB0s"}],"has_more":false,"per_page":200,"page":1}'
39
+ http_version:
40
+ recorded_at: Fri, 01 Jul 2016 14:47:49 GMT
41
+ recorded_with: VCR 3.0.3
data/lib/chartmogul.rb CHANGED
@@ -43,6 +43,7 @@ require 'chartmogul/concerns/entries'
43
43
  require 'chartmogul/concerns/summary'
44
44
  require 'chartmogul/concerns/pageable'
45
45
  require 'chartmogul/concerns/pageable2'
46
+ require 'chartmogul/concerns/pageable_with_anchor'
46
47
 
47
48
  require 'chartmogul/subscription'
48
49
  require 'chartmogul/invoice'
@@ -66,8 +67,10 @@ require 'chartmogul/metrics/mrr_churn_rate'
66
67
  require 'chartmogul/metrics/all_key_metrics'
67
68
  require 'chartmogul/metrics/base'
68
69
 
70
+ require 'chartmogul/metrics/customers/activity'
71
+ require 'chartmogul/metrics/customers/subscription'
69
72
  require 'chartmogul/metrics/activity'
70
- require 'chartmogul/metrics/subscription'
73
+ require 'chartmogul/metrics/activities_export'
71
74
 
72
75
  require 'chartmogul/enrichment/customer'
73
76
 
@@ -79,10 +82,14 @@ module ChartMogul
79
82
  class << self
80
83
  extend ConfigAttributes
81
84
 
85
+ def global_config
86
+ @global_config ||= ChartMogul::Configuration.new
87
+ end
82
88
 
89
+ # This configuration is thread-safe and fits multi-account async
90
+ # jobs processing use case.
83
91
  def config
84
- Thread.current[CONFIG_THREAD_KEY] = ChartMogul::Configuration.new if Thread.current[CONFIG_THREAD_KEY].nil?
85
- Thread.current[CONFIG_THREAD_KEY]
92
+ Thread.current[CONFIG_THREAD_KEY] ||= ChartMogul::Configuration.new
86
93
  end
87
94
 
88
95
  config_accessor :account_token
@@ -16,7 +16,7 @@ module ChartMogul
16
16
  end
17
17
  end
18
18
 
19
- json = ChartMogul::Utils::JSONParser.parse(resp.body, skip_case_conversion: skip_case_conversion)
19
+ json = ChartMogul::Utils::JSONParser.parse(resp.body, immutable_keys: immutable_keys)
20
20
  new_from_json(json)
21
21
  end
22
22
  end
@@ -15,7 +15,7 @@ module ChartMogul
15
15
  req.body = JSON.dump(serialize_for_write)
16
16
  end
17
17
  end
18
- json = ChartMogul::Utils::JSONParser.parse(resp.body, skip_case_conversion: self.class.skip_case_conversion)
18
+ json = ChartMogul::Utils::JSONParser.parse(resp.body, immutable_keys: self.class.immutable_keys)
19
19
 
20
20
  assign_all_attributes(json)
21
21
  end
@@ -30,7 +30,7 @@ module ChartMogul
30
30
  req.body = JSON.dump(resource.serialize_for_write)
31
31
  end
32
32
  end
33
- json = ChartMogul::Utils::JSONParser.parse(resp.body, skip_case_conversion: skip_case_conversion)
33
+ json = ChartMogul::Utils::JSONParser.parse(resp.body, immutable_keys: immutable_keys)
34
34
 
35
35
  new_from_json(json)
36
36
  end
@@ -25,7 +25,7 @@ module ChartMogul
25
25
  req.body = JSON.dump(body_data)
26
26
  end
27
27
  end
28
- ChartMogul::Utils::JSONParser.parse(resp.body, skip_case_conversion: skip_case_conversion)
28
+ ChartMogul::Utils::JSONParser.parse(resp.body, immutable_keys: immutable_keys)
29
29
  end
30
30
 
31
31
  def custom!(http_method, http_path, body_data = {})
@@ -15,7 +15,8 @@ module ChartMogul
15
15
  req.headers['Content-Type'] = 'application/json'
16
16
  end
17
17
  end
18
- json = ChartMogul::Utils::JSONParser.parse(resp.body, skip_case_conversion: skip_case_conversion)
18
+
19
+ json = ChartMogul::Utils::JSONParser.parse(resp.body, immutable_keys: immutable_keys)
19
20
  new_from_json(json)
20
21
  end
21
22
  end
@@ -16,7 +16,7 @@ module ChartMogul
16
16
  end
17
17
  end
18
18
 
19
- json = ChartMogul::Utils::JSONParser.parse(resp.body, skip_case_conversion: self.class.skip_case_conversion)
19
+ json = ChartMogul::Utils::JSONParser.parse(resp.body, immutable_keys: self.class.immutable_keys)
20
20
 
21
21
  assign_all_attributes(json)
22
22
  end
@@ -31,7 +31,7 @@ module ChartMogul
31
31
  req.body = JSON.dump(resource.serialize_for_write)
32
32
  end
33
33
  end
34
- json = ChartMogul::Utils::JSONParser.parse(resp.body, skip_case_conversion: skip_case_conversion)
34
+ json = ChartMogul::Utils::JSONParser.parse(resp.body, immutable_keys: immutable_keys)
35
35
 
36
36
  new_from_json(json)
37
37
  end
@@ -17,7 +17,7 @@ module ChartMogul
17
17
  MAX_INTERVAL = 60
18
18
  THREAD_CONNECTION_KEY = 'chartmogul_ruby.api_resource.connection'
19
19
 
20
- class << self; attr_reader :resource_path, :resource_name, :resource_root_key, :skip_case_conversion end
20
+ class << self; attr_reader :resource_path, :resource_name, :resource_root_key end
21
21
 
22
22
  def self.set_resource_path(path)
23
23
  @resource_path = ChartMogul::ResourcePath.new(path)
@@ -31,9 +31,13 @@ module ChartMogul
31
31
  @resource_root_key = root_key
32
32
  end
33
33
 
34
- # When true, response hash keys won't be converted to snake case
35
- def self.set_skip_case_conversion(value)
36
- @skip_case_conversion = value
34
+ def self.immutable_keys
35
+ @immutable_keys ||= []
36
+ end
37
+
38
+ # When set with keys, nested hash keys of these immutable keys won't be converted to snake case
39
+ def self.set_immutable_keys(array)
40
+ @immutable_keys = array
37
41
  end
38
42
 
39
43
  def self.connection
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChartMogul
4
+ module Concerns
5
+ module PageableWithAnchor
6
+ def self.included(base)
7
+ base.instance_eval do
8
+ readonly_attr :has_more
9
+ readonly_attr :per_page
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -4,7 +4,7 @@ module ChartMogul
4
4
  module ConfigAttributes
5
5
  def config_accessor(attribute, default_value = nil)
6
6
  define_method(attribute) do
7
- attr = config.send(attribute) || default_value
7
+ attr = config.send(attribute) || global_config.send(attribute) || default_value
8
8
  if attr.nil?
9
9
  raise ConfigurationError, "Configuration for #{attribute} not set"
10
10
  end
@@ -12,9 +12,25 @@ module ChartMogul
12
12
  attr
13
13
  end
14
14
 
15
+ define_method("global_#{attribute}") do
16
+ attr = global_config.send(attribute) || default_value
17
+ if attr.nil?
18
+ raise ConfigurationError, "Global configuration for #{attribute} not set"
19
+ end
20
+
21
+ attr
22
+ end
23
+
15
24
  define_method("#{attribute}=") do |val|
16
25
  config.send("#{attribute}=", val)
17
26
  Thread.current[ChartMogul::APIResource::THREAD_CONNECTION_KEY] = nil
27
+ val
28
+ end
29
+
30
+ define_method("global_#{attribute}=") do |val|
31
+ global_config.send("#{attribute}=", val)
32
+ Thread.current[ChartMogul::APIResource::THREAD_CONNECTION_KEY] = nil
33
+ val
18
34
  end
19
35
  end
20
36
  end