intercom 4.2.1 → 4.2.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a680039a8ef799d52b227657866f60afa19bf4b292f9d70646c8f962eca11a0
4
- data.tar.gz: 40317d4521715f294bec48805ed9edf6f83406260b5c74bde5e9cf96cdf9cb8c
3
+ metadata.gz: 97caaa1c044ea1370944d335cfc0d6e004966d8f84ba547a83ca78daa2be3d11
4
+ data.tar.gz: dfd96074bef226daa006f2b4c18aa2b6b6ee5a582301ea18e783962a5a4bcab9
5
5
  SHA512:
6
- metadata.gz: df28a00dc009f9e7bd94fa497021312d4cbe005905eea6095d1efe1172f567d8f806a47750843e129cfae5af80db038aea355ba2f1a2b5122142893574d9d977
7
- data.tar.gz: d57709458d73737890f1933264f10b23c486a08840bd3a561c8971dbfef3d2ad88b4ddb2d393154b4127cd78196a39a56c93c0f08c747c74bd303c729d01fc5f
6
+ metadata.gz: dfec5a80b9442a047087608f564db3d9380ae106e4cffae99f11d9e1c33915e5a984957712ea7f09d213abd4cd968cee6d642d241d2a9ef7020a30a1ce953497
7
+ data.tar.gz: a7370a062eff270da20077fba81930af2cdfa92f9845583bdf498ee95bc18867672577d916bf57843bbf07ed16da5524e971e85e97827ee578efa53a753303a5
data/.circleci/config.yml CHANGED
@@ -1,35 +1,91 @@
1
- version: 2
1
+ version: 2.1
2
2
  jobs:
3
- "Test against Ruby 2.4":
3
+ test-ruby-2-4:
4
4
  docker:
5
5
  - image: circleci/ruby:2.4.9
6
6
  working_directory: ~/intercom-ruby
7
7
  steps:
8
8
  - checkout
9
+ - run:
10
+ name: Route Bundler through the Socket Firewall registry
11
+ command: |
12
+ set -euo pipefail
13
+ if [ -z "${SOCKET_GEM_URL:-}" ]; then
14
+ # CircleCI does not share context credentials with forked PRs, so a
15
+ # fork cannot be routed. Say so rather than failing the contributor.
16
+ if [ -n "${CIRCLE_PR_REPONAME:-}" ]; then
17
+ echo "Forked PR: no Socket Firewall credentials available, gems will come from rubygems.org."
18
+ exit 0
19
+ fi
20
+ echo "FATAL: SOCKET_GEM_URL is required (provided by the socket-firewall context)"
21
+ exit 1
22
+ fi
23
+ # Legacy two-argument form: these images ship Bundler 1.x, where
24
+ # `bundle config set --global` does not exist and silently no-ops.
25
+ bundle config mirror.https://rubygems.org "$SOCKET_GEM_URL"
26
+ bundle config mirror.https://rubygems.org | grep -q socket-firewall-registry \
27
+ || { echo "FAIL: bundler mirror not pointing at Socket Firewall"; exit 1; }
9
28
  - run: bundle install
10
29
  - run: bundle exec rake
11
- "Test against Ruby 2.5":
30
+ test-ruby-2-5:
12
31
  docker:
13
32
  - image: circleci/ruby:2.5.7
14
33
  working_directory: ~/intercom-ruby
15
34
  steps:
16
35
  - checkout
36
+ - run:
37
+ name: Route Bundler through the Socket Firewall registry
38
+ command: |
39
+ set -euo pipefail
40
+ if [ -z "${SOCKET_GEM_URL:-}" ]; then
41
+ if [ -n "${CIRCLE_PR_REPONAME:-}" ]; then
42
+ echo "Forked PR: no Socket Firewall credentials available, gems will come from rubygems.org."
43
+ exit 0
44
+ fi
45
+ echo "FATAL: SOCKET_GEM_URL is required (provided by the socket-firewall context)"
46
+ exit 1
47
+ fi
48
+ bundle config mirror.https://rubygems.org "$SOCKET_GEM_URL"
49
+ bundle config mirror.https://rubygems.org | grep -q socket-firewall-registry \
50
+ || { echo "FAIL: bundler mirror not pointing at Socket Firewall"; exit 1; }
17
51
  - run: bundle install
18
52
  - run: bundle exec rake
19
- "Test against Ruby 2.6":
53
+ test-ruby-2-6:
20
54
  docker:
21
55
  - image: circleci/ruby:2.6.5
22
56
  working_directory: ~/intercom-ruby
23
57
  steps:
24
58
  - checkout
59
+ - run:
60
+ name: Route Bundler through the Socket Firewall registry
61
+ command: |
62
+ set -euo pipefail
63
+ if [ -z "${SOCKET_GEM_URL:-}" ]; then
64
+ if [ -n "${CIRCLE_PR_REPONAME:-}" ]; then
65
+ echo "Forked PR: no Socket Firewall credentials available, gems will come from rubygems.org."
66
+ exit 0
67
+ fi
68
+ echo "FATAL: SOCKET_GEM_URL is required (provided by the socket-firewall context)"
69
+ exit 1
70
+ fi
71
+ bundle config mirror.https://rubygems.org "$SOCKET_GEM_URL"
72
+ bundle config mirror.https://rubygems.org | grep -q socket-firewall-registry \
73
+ || { echo "FAIL: bundler mirror not pointing at Socket Firewall"; exit 1; }
25
74
  - run: bundle install
26
75
  - run: bundle exec rake
27
76
 
28
77
  workflows:
29
- version: 2
30
78
  build_and_test:
31
79
  jobs:
32
- - "Test against Ruby 2.4"
33
- - "Test against Ruby 2.5"
34
- - "Test against Ruby 2.6"
35
-
80
+ - test-ruby-2-4:
81
+ name: "Test against Ruby 2.4"
82
+ context:
83
+ - socket-firewall
84
+ - test-ruby-2-5:
85
+ name: "Test against Ruby 2.5"
86
+ context:
87
+ - socket-firewall
88
+ - test-ruby-2-6:
89
+ name: "Test against Ruby 2.6"
90
+ context:
91
+ - socket-firewall
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source "http://rubygems.org"
1
+ source "https://rubygems.org"
2
2
 
3
3
  gem 'webmock'
4
4
  gemspec
data/README.md CHANGED
@@ -170,7 +170,7 @@ contact.remove_company(id: company.id)
170
170
  contact.companies.each {|c| p c.name}
171
171
 
172
172
  # attach a subscription_types on a contact
173
- contact.create_subscription_types(id: subscription_type.id)
173
+ contact.create_subscription_type(id: subscription_type.id)
174
174
 
175
175
  # List subscription_types for a contact
176
176
  contact.subscription_types.each {|n| p n.id}
data/changes.txt CHANGED
@@ -1,3 +1,10 @@
1
+ 4.2.3
2
+ - Fixed SyntaxError when reading articles with hyphenated locales
3
+
4
+ 4.2.2
5
+ - Fixed FlatStore to skip hash values when building API request payloads
6
+ - Removed hash validation on FlatStore reads to allow for custom objects
7
+
1
8
  4.1.3
2
9
  - Updated ReadMe with more errors.
3
10
  - Fixed issue where paginated requests could only be iterated through once.
data/intercom.gemspec CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency 'minitest', '~> 5.4'
22
22
  spec.add_development_dependency "m", "~> 1.5.0"
23
23
  spec.add_development_dependency 'rake', '~> 10.3'
24
- spec.add_development_dependency 'mocha', '~> 1.0'
24
+ spec.add_development_dependency 'mocha', '~> 2.0'
25
25
  spec.add_development_dependency "fakeweb", ["~> 1.3"]
26
26
  spec.add_development_dependency "pry"
27
27
 
@@ -17,39 +17,46 @@ module Intercom
17
17
  private
18
18
 
19
19
  def define_flat_store_based_accessors(attribute, value, object)
20
- object.instance_eval %Q"
21
- def #{attribute}=(value)
22
- mark_field_as_changed!(:#{attribute})
23
- @#{attribute} = Intercom::Lib::FlatStore.new(value)
20
+ ivar = ivar_name(attribute, object)
21
+ object.singleton_class.class_eval do
22
+ define_method("#{attribute}=") do |val|
23
+ mark_field_as_changed!(attribute.to_sym)
24
+ instance_variable_set(ivar, Intercom::Lib::FlatStore.new(val))
24
25
  end
25
- def #{attribute}
26
- @#{attribute}
27
- end
28
- "
26
+ define_method(attribute) { instance_variable_get(ivar) }
27
+ end
29
28
  end
30
29
 
31
30
  def define_date_based_accessors(attribute, value, object)
32
- object.instance_eval %Q"
33
- def #{attribute}=(value)
34
- mark_field_as_changed!(:#{attribute})
35
- @#{attribute} = value.nil? ? nil : value.to_i
31
+ ivar = ivar_name(attribute, object)
32
+ object.singleton_class.class_eval do
33
+ define_method("#{attribute}=") do |val|
34
+ mark_field_as_changed!(attribute.to_sym)
35
+ instance_variable_set(ivar, val.nil? ? nil : val.to_i)
36
36
  end
37
- def #{attribute}
38
- @#{attribute}.nil? ? nil : Time.at(@#{attribute})
37
+ define_method(attribute) do
38
+ time = instance_variable_get(ivar)
39
+ time.nil? ? nil : Time.at(time)
39
40
  end
40
- "
41
+ end
41
42
  end
42
43
 
43
44
  def define_standard_accessors(attribute, value, object)
44
- object.instance_eval %Q"
45
- def #{attribute}=(value)
46
- mark_field_as_changed!(:#{attribute})
47
- @#{attribute} = value
48
- end
49
- def #{attribute}
50
- @#{attribute}
51
- end
52
- "
45
+ ivar = ivar_name(attribute, object)
46
+ object.singleton_class.class_eval do
47
+ define_method("#{attribute}=") do |val|
48
+ mark_field_as_changed!(attribute.to_sym)
49
+ instance_variable_set(ivar, val)
50
+ end
51
+ define_method(attribute) { instance_variable_get(ivar) }
52
+ end
53
+ end
54
+
55
+ # Keys such as "pt-BR" are not valid identifiers, so normalise them for the ivar name.
56
+ def ivar_name(attribute, object)
57
+ ivar = "@#{attribute.to_s.gsub(/\W/, '_')}"
58
+ object.register_attribute_key(ivar, attribute) if ivar != "@#{attribute}"
59
+ ivar
53
60
  end
54
61
 
55
62
  end
@@ -2,7 +2,7 @@ module Intercom
2
2
  module Lib
3
3
 
4
4
  # Sub-class of {Hash} for storing custom data attributes.
5
- # Doesn't allow nested Hashes or Arrays. And requires {String} or {Symbol} keys.
5
+ # Doesn't allow Arrays. And requires {String} or {Symbol} keys.
6
6
  class FlatStore < Hash
7
7
 
8
8
  def initialize(attributes={})
@@ -21,9 +21,16 @@ module Intercom
21
21
  super(key.to_s)
22
22
  end
23
23
 
24
+ def to_submittable_hash
25
+ # Filter out Custom Object references when submitting to API
26
+ self.reject do |key, value|
27
+ value.is_a?(Hash)
28
+ end
29
+ end
30
+
24
31
  private
25
32
  def validate_key_and_value(key, value)
26
- raise ArgumentError.new("This does not support nested data structures (key: #{key}, value: #{value}") if value.is_a?(Array) || value.is_a?(Hash)
33
+ raise ArgumentError.new("This does not support nested data structures (key: #{key}, value: #{value}") if value.is_a?(Array)
27
34
  raise ArgumentError.new("Key must be String or Symbol: #{key}") unless key.is_a?(String) || key.is_a?(Symbol)
28
35
  end
29
36
  end
@@ -37,7 +37,7 @@ module Intercom
37
37
 
38
38
  def to_hash
39
39
  instance_variables_excluding_dirty_tracking_field.each_with_object({}) do |variable, hash|
40
- hash[variable.to_s.delete('@')] = instance_variable_get(variable)
40
+ hash[attribute_key(variable)] = instance_variable_get(variable)
41
41
  end
42
42
  end
43
43
 
@@ -46,10 +46,18 @@ module Intercom
46
46
  next if variable == :@client
47
47
 
48
48
  value = instance_variable_get(variable)
49
- hash[variable.to_s.delete('@')] = value.respond_to?(:to_json) ? value.to_json(*args) : value
49
+ hash[attribute_key(variable)] = value.respond_to?(:to_json) ? value.to_json(*args) : value
50
50
  end
51
51
  end
52
52
 
53
+ def register_attribute_key(ivar, attribute)
54
+ (@attribute_keys ||= {})[ivar.to_sym] = attribute.to_s
55
+ end
56
+
57
+ def attribute_key(variable)
58
+ (@attribute_keys || {}).fetch(variable, variable.to_s.delete('@'))
59
+ end
60
+
53
61
  def to_submittable_hash
54
62
  submittable_hash = {}
55
63
  to_hash.each do |attribute, value|
@@ -22,7 +22,7 @@ module Intercom
22
22
 
23
23
  def field_changed?(field_name)
24
24
  @changed_fields ||= Set.new
25
- field = instance_variable_get("@#{field_name}")
25
+ field = instance_variable_get("@#{field_name.to_s.gsub(/\W/, '_')}")
26
26
  if field.respond_to?(:field_changed?)
27
27
  field.to_hash.any? do |attribute, _|
28
28
  field.field_changed?(attribute)
@@ -33,7 +33,7 @@ module Intercom
33
33
  end
34
34
 
35
35
  def instance_variables_excluding_dirty_tracking_field
36
- instance_variables.reject{|var| var == :@changed_fields}
36
+ instance_variables.reject{|var| var == :@changed_fields || var == :@attribute_keys}
37
37
  end
38
38
  end
39
39
  end
@@ -1,3 +1,3 @@
1
1
  module Intercom #:nodoc:
2
- VERSION = "4.2.1"
2
+ VERSION = "4.2.3"
3
3
  end
data/spec/spec_helper.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'intercom'
4
4
  require 'minitest/autorun'
5
- require 'mocha/setup'
5
+ require 'mocha/minitest'
6
6
  require 'webmock'
7
7
  require 'time'
8
8
  require 'pry'
@@ -37,4 +37,22 @@ describe "Intercom::Article" do
37
37
  client.articles.delete(article)
38
38
  end
39
39
  end
40
- end
40
+
41
+ describe "Parsing an Article" do
42
+ it "handles hyphenated locale keys in translated content" do
43
+ article = Intercom::Article.from_api(
44
+ "id" => "1",
45
+ "type" => "article",
46
+ "translated_content" => {
47
+ "type" => "article_translated_content",
48
+ "fr" => { "type" => "article_content", "title" => "Bonjour" },
49
+ "pt-BR" => { "type" => "article_content", "title" => "Ola" }
50
+ }
51
+ )
52
+ _(article.translated_content.fr.title).must_equal "Bonjour"
53
+ _(article.translated_content.public_send("pt-BR").title).must_equal "Ola"
54
+ article.translated_content.public_send("pt-BR").title = "Oi"
55
+ _(article.to_submittable_hash).must_equal("translated_content" => { "pt-BR" => { "title" => "Oi" } })
56
+ end
57
+ end
58
+ end
@@ -90,12 +90,10 @@ describe Intercom::Contact do
90
90
  _(contact.to_hash['custom_attributes']).must_equal 'mad' => 123, 'other' => now.to_i, 'thing' => 'yay'
91
91
  end
92
92
 
93
- it 'rejects nested data structures in custom_attributes' do
93
+ it 'rejects lists in custom_attributes' do
94
94
  contact = Intercom::Contact.new
95
95
 
96
96
  _(proc { contact.custom_attributes['thing'] = [1] }).must_raise(ArgumentError)
97
- _(proc { contact.custom_attributes['thing'] = { 1 => 2 } }).must_raise(ArgumentError)
98
- _(proc { contact.custom_attributes['thing'] = { 1 => { 2 => 3 } } }).must_raise(ArgumentError)
99
97
 
100
98
  contact = Intercom::Contact.new(test_contact)
101
99
  _(proc { contact.custom_attributes['thing'] = [1] }).must_raise(ArgumentError)
@@ -3,11 +3,15 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe Intercom::Lib::FlatStore do
6
- it 'raises if you try to set or merge in nested hash structures' do
6
+ it 'raises if you try to set arrays but allows hashes' do
7
7
  data = Intercom::Lib::FlatStore.new
8
8
  _(proc { data['thing'] = [1] }).must_raise ArgumentError
9
- _(proc { data['thing'] = { 1 => 2 } }).must_raise ArgumentError
10
- _(proc { Intercom::Lib::FlatStore.new(1 => { 2 => 3 }) }).must_raise ArgumentError
9
+
10
+ data['thing'] = { 'key' => 'value' }
11
+ _(data['thing']).must_equal({ 'key' => 'value' })
12
+
13
+ flat_store = Intercom::Lib::FlatStore.new('custom_object' => { 'type' => 'Order.list', 'instances' => [{'id' => '123'}] })
14
+ _(flat_store['custom_object']).must_equal({ 'type' => 'Order.list', 'instances' => [{'id' => '123'}] })
11
15
  end
12
16
 
13
17
  it 'raises if you try to use a non string key' do
@@ -28,4 +32,30 @@ describe Intercom::Lib::FlatStore do
28
32
  _(data['b']).must_equal 2
29
33
  _(data[:b]).must_equal 2
30
34
  end
35
+
36
+ describe '#to_submittable_hash' do
37
+ it 'filters out all hash values' do
38
+ data = Intercom::Lib::FlatStore.new(
39
+ 'regular_attr' => 'value',
40
+ 'number_attr' => 42,
41
+ 'custom_object' => {
42
+ 'type' => 'Order.list',
43
+ 'instances' => [
44
+ { 'id' => '31', 'external_id' => 'ext_123' }
45
+ ]
46
+ },
47
+ 'regular_hash' => { 'key' => 'value' },
48
+ 'metadata' => { 'source' => 'api', 'version' => 2 }
49
+ )
50
+
51
+ submittable = data.to_submittable_hash
52
+
53
+ _(submittable['regular_attr']).must_equal 'value'
54
+ _(submittable['number_attr']).must_equal 42
55
+
56
+ _(submittable.key?('custom_object')).must_equal false
57
+ _(submittable.key?('regular_hash')).must_equal false
58
+ _(submittable.key?('metadata')).must_equal false
59
+ end
60
+ end
31
61
  end
@@ -106,12 +106,10 @@ describe 'Intercom::User' do
106
106
  _(user.to_hash['companies']).must_equal companies
107
107
  end
108
108
 
109
- it 'rejects nested data structures in custom_attributes' do
109
+ it 'rejects lists in custom_attributes' do
110
110
  user = Intercom::User.new
111
111
 
112
112
  _(proc { user.custom_attributes['thing'] = [1] }).must_raise(ArgumentError)
113
- _(proc { user.custom_attributes['thing'] = { 1 => 2 } }).must_raise(ArgumentError)
114
- _(proc { user.custom_attributes['thing'] = { 1 => { 2 => 3 } } }).must_raise(ArgumentError)
115
113
 
116
114
  user = Intercom::User.from_api(test_user)
117
115
  _(proc { user.custom_attributes['thing'] = [1] }).must_raise(ArgumentError)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: intercom
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.1
4
+ version: 4.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben McRedmond
@@ -15,7 +15,7 @@ authors:
15
15
  autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
- date: 2022-12-16 00:00:00.000000000 Z
18
+ date: 2026-10-08 00:00:00.000000000 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: minitest
@@ -65,14 +65,14 @@ dependencies:
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '1.0'
68
+ version: '2.0'
69
69
  type: :development
70
70
  prerelease: false
71
71
  version_requirements: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '1.0'
75
+ version: '2.0'
76
76
  - !ruby/object:Gem::Dependency
77
77
  name: fakeweb
78
78
  requirement: !ruby/object:Gem::Requirement
@@ -279,7 +279,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
279
279
  - !ruby/object:Gem::Version
280
280
  version: '0'
281
281
  requirements: []
282
- rubygems_version: 3.2.16
282
+ rubygems_version: 3.0.3.1
283
283
  signing_key:
284
284
  specification_version: 4
285
285
  summary: Ruby bindings for the Intercom API