intercom-rails 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/intercom-rails.rb +3 -1
- data/lib/intercom-rails/auto_include_filter.rb +1 -1
- data/lib/intercom-rails/config.rb +64 -72
- data/lib/intercom-rails/custom_data_helper.rb +7 -2
- data/lib/intercom-rails/exceptions.rb +2 -2
- data/lib/intercom-rails/import.rb +3 -3
- data/lib/intercom-rails/proxy.rb +81 -0
- data/lib/intercom-rails/proxy/company.rb +35 -0
- data/lib/intercom-rails/proxy/user.rb +48 -0
- data/lib/intercom-rails/script_tag.rb +25 -6
- data/lib/intercom-rails/script_tag_helper.rb +1 -0
- data/lib/intercom-rails/version.rb +1 -1
- data/lib/rails/generators/intercom/config/intercom.rb.erb +26 -8
- data/test/intercom-rails/auto_include_filter_test.rb +18 -4
- data/test/intercom-rails/config_test.rb +13 -8
- data/test/intercom-rails/proxy/company_test.rb +21 -0
- data/test/intercom-rails/{user_proxy_test.rb → proxy/user_test.rb} +23 -16
- data/test/intercom-rails/script_tag_test.rb +12 -0
- data/test/test_setup.rb +7 -0
- metadata +10 -6
- data/lib/intercom-rails/user_proxy.rb +0 -84
data/lib/intercom-rails.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'intercom-rails/exceptions'
|
2
|
-
require 'intercom-rails/
|
2
|
+
require 'intercom-rails/proxy'
|
3
|
+
require 'intercom-rails/proxy/user'
|
4
|
+
require 'intercom-rails/proxy/company'
|
3
5
|
require 'intercom-rails/script_tag'
|
4
6
|
require 'intercom-rails/script_tag_helper'
|
5
7
|
require 'intercom-rails/custom_data_helper'
|
@@ -46,7 +46,7 @@ module IntercomRails
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def intercom_script_tag
|
49
|
-
@script_tag ||= ScriptTag.new(:find_current_user_details => true, :controller => controller)
|
49
|
+
@script_tag ||= ScriptTag.new(:find_current_user_details => true, :find_current_company_details => true, :controller => controller)
|
50
50
|
end
|
51
51
|
|
52
52
|
end
|
@@ -1,99 +1,91 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
module Config
|
4
|
-
|
5
|
-
def self.reset!
|
6
|
-
[self, InboxConfig].each do |configer|
|
7
|
-
configer.instance_variables.each do |var|
|
8
|
-
configer.send(:remove_instance_variable, var)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
# Your Intercom app_id
|
14
|
-
def self.app_id=(value)
|
15
|
-
@app_id = value
|
16
|
-
end
|
1
|
+
class Module
|
17
2
|
|
18
|
-
|
19
|
-
|
20
|
-
|
3
|
+
def config_accessor(*args, &block)
|
4
|
+
config_reader(*args)
|
5
|
+
config_writer(*args, &block)
|
6
|
+
end
|
21
7
|
|
22
|
-
|
23
|
-
|
24
|
-
|
8
|
+
def config_reader(name)
|
9
|
+
self.send(:define_singleton_method, name) do
|
10
|
+
instance_variable_get("@#{name}")
|
25
11
|
end
|
12
|
+
end
|
26
13
|
|
27
|
-
|
28
|
-
|
14
|
+
def config_writer(name, &block)
|
15
|
+
self.send(:define_singleton_method, "#{name}=") do |value|
|
16
|
+
block.call(value) if block
|
17
|
+
instance_variable_set("@#{name}", value)
|
29
18
|
end
|
19
|
+
end
|
30
20
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
21
|
+
def config_group(name, &block)
|
22
|
+
camelized_name = name.to_s.split('_').map { |s| s[0].upcase + s[1..-1] }.join('')
|
23
|
+
group = self.const_set(camelized_name, Module.new)
|
35
24
|
|
36
|
-
|
37
|
-
|
25
|
+
self.send(:define_singleton_method, name) do
|
26
|
+
group
|
38
27
|
end
|
39
28
|
|
40
|
-
|
41
|
-
|
42
|
-
raise ArgumentError, "current_user should be a Proc" unless value.kind_of?(Proc)
|
43
|
-
@current_user = value
|
44
|
-
end
|
29
|
+
group.instance_eval(&block)
|
30
|
+
end
|
45
31
|
|
46
|
-
|
47
|
-
@current_user
|
48
|
-
end
|
32
|
+
end
|
49
33
|
|
50
|
-
|
51
|
-
def self.user_model=(value)
|
52
|
-
raise ArgumentError, "user_model should be a Proc" unless value.kind_of?(Proc)
|
53
|
-
@user_model = value
|
54
|
-
end
|
34
|
+
module IntercomRails
|
55
35
|
|
56
|
-
|
57
|
-
@user_model
|
58
|
-
end
|
36
|
+
module Config
|
59
37
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
38
|
+
def self.reset!
|
39
|
+
to_reset = self.constants.map {|c| const_get c}
|
40
|
+
to_reset << self
|
64
41
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
42
|
+
to_reset.each do |configer|
|
43
|
+
configer.instance_variables.each do |var|
|
44
|
+
configer.send(:remove_instance_variable, var)
|
45
|
+
end
|
69
46
|
end
|
70
|
-
|
71
|
-
@custom_data = value
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.custom_data
|
75
|
-
@custom_data
|
76
47
|
end
|
48
|
+
|
49
|
+
config_accessor :app_id
|
50
|
+
config_accessor :api_secret
|
51
|
+
config_accessor :api_key
|
77
52
|
|
78
|
-
|
53
|
+
config_group :user do
|
54
|
+
config_accessor :current do |value|
|
55
|
+
raise ArgumentError, "user.current should be a Proc" unless value.kind_of?(Proc)
|
56
|
+
end
|
79
57
|
|
80
|
-
|
58
|
+
config_accessor :model do |value|
|
59
|
+
raise ArgumentError, "user.model should be a Proc" unless value.kind_of?(Proc)
|
60
|
+
end
|
81
61
|
|
82
|
-
|
83
|
-
|
84
|
-
|
62
|
+
config_accessor :custom_data do |value|
|
63
|
+
raise ArgumentError, "user.custom_data should be a hash" unless value.kind_of?(Hash)
|
64
|
+
unless value.reject { |_,v| v.kind_of?(Proc) || v.kind_of?(Symbol) }.count.zero?
|
65
|
+
raise ArgumentError, "all custom_data attributes should be either a Proc or a symbol"
|
66
|
+
end
|
67
|
+
end
|
85
68
|
end
|
69
|
+
|
70
|
+
config_group :company do
|
71
|
+
config_accessor :current do |value|
|
72
|
+
raise ArgumentError, "company.current should be a Proc" unless value.kind_of?(Proc)
|
73
|
+
end
|
86
74
|
|
87
|
-
|
88
|
-
|
75
|
+
config_accessor :custom_data do |value|
|
76
|
+
raise ArgumentError, "company.custom_data should be a hash" unless value.kind_of?(Hash)
|
77
|
+
unless value.reject { |_,v| v.kind_of?(Proc) || v.kind_of?(Symbol) }.count.zero?
|
78
|
+
raise ArgumentError, "all custom_data attributes should be either a Proc or a symbol"
|
79
|
+
end
|
80
|
+
end
|
89
81
|
end
|
90
82
|
|
91
|
-
|
92
|
-
|
93
|
-
end
|
83
|
+
config_group :inbox do
|
84
|
+
config_accessor :counter
|
94
85
|
|
95
|
-
|
96
|
-
|
86
|
+
config_accessor :style do |value|
|
87
|
+
raise ArgumentError, "inbox.style must be one of :default or :custom" unless [:default, :custom].include?(value)
|
88
|
+
end
|
97
89
|
end
|
98
90
|
|
99
91
|
end
|
@@ -6,11 +6,16 @@ module IntercomRails
|
|
6
6
|
# for the current request from within the controller. e.g.
|
7
7
|
#
|
8
8
|
# def destroy
|
9
|
-
# intercom_custom_data['canceled_at'] = Time.now
|
9
|
+
# intercom_custom_data.user['canceled_at'] = Time.now
|
10
10
|
# ...
|
11
11
|
# end
|
12
12
|
def intercom_custom_data
|
13
|
-
@_request_specific_intercom_custom_data ||=
|
13
|
+
@_request_specific_intercom_custom_data ||= begin
|
14
|
+
s = Struct.new(:user, :company).new
|
15
|
+
s.user = {}
|
16
|
+
s.company = {}
|
17
|
+
s
|
18
|
+
end
|
14
19
|
end
|
15
20
|
|
16
21
|
end
|
@@ -69,7 +69,7 @@ module IntercomRails
|
|
69
69
|
def batches
|
70
70
|
user_klass.find_in_batches(:batch_size => MAX_BATCH_SIZE) do |users|
|
71
71
|
users_for_wire = users.map do |u|
|
72
|
-
user_proxy =
|
72
|
+
user_proxy = Proxy::User.new(u)
|
73
73
|
user_proxy.valid? ? user_proxy.to_hash : nil
|
74
74
|
end.compact
|
75
75
|
|
@@ -82,8 +82,8 @@ module IntercomRails
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def user_klass
|
85
|
-
if IntercomRails.config.
|
86
|
-
IntercomRails.config.
|
85
|
+
if IntercomRails.config.user.model.present?
|
86
|
+
IntercomRails.config.user.model.call
|
87
87
|
else
|
88
88
|
User
|
89
89
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module IntercomRails
|
2
|
+
|
3
|
+
module Proxy
|
4
|
+
|
5
|
+
class Proxy
|
6
|
+
|
7
|
+
def self.class_string
|
8
|
+
self.to_s.split('::').last
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.inherited(subclass)
|
12
|
+
subclass.class_eval do
|
13
|
+
attr_reader class_string.downcase.to_s
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :search_object, :proxied_object
|
18
|
+
|
19
|
+
def initialize(object_to_proxy, search_object = nil)
|
20
|
+
@search_object = search_object
|
21
|
+
@proxied_object = instance_variable_set(:"@#{type}", object_to_proxy)
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_hash
|
25
|
+
standard_data.merge custom_data
|
26
|
+
end
|
27
|
+
|
28
|
+
def custom_data
|
29
|
+
custom_data_from_config.merge custom_data_from_request
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
def attribute_present?(attribute)
|
35
|
+
proxied_object.respond_to?(attribute) && proxied_object.send(attribute).present?
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.type
|
39
|
+
self.class_string.downcase.to_sym
|
40
|
+
end
|
41
|
+
|
42
|
+
def type
|
43
|
+
self.class.type
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.config
|
47
|
+
IntercomRails.config.send(type)
|
48
|
+
end
|
49
|
+
|
50
|
+
def config
|
51
|
+
self.class.config
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def custom_data_from_request
|
57
|
+
search_object.intercom_custom_data.send(type)
|
58
|
+
rescue NoMethodError
|
59
|
+
{}
|
60
|
+
end
|
61
|
+
|
62
|
+
def custom_data_from_config
|
63
|
+
return {} if config.custom_data.blank?
|
64
|
+
config.custom_data.reduce({}) do |custom_data, (k,v)|
|
65
|
+
custom_data.merge(k => custom_data_value_from_proc_or_symbol(v))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def custom_data_value_from_proc_or_symbol(proc_or_symbol)
|
70
|
+
if proc_or_symbol.kind_of?(Symbol)
|
71
|
+
proxied_object.send(proc_or_symbol)
|
72
|
+
elsif proc_or_symbol.kind_of?(Proc)
|
73
|
+
proc_or_symbol.call(proxied_object)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module IntercomRails
|
2
|
+
|
3
|
+
module Proxy
|
4
|
+
|
5
|
+
class Company < Proxy
|
6
|
+
|
7
|
+
def self.current_in_context(search_object)
|
8
|
+
begin
|
9
|
+
if config.current.present?
|
10
|
+
company_proxy = new(search_object.instance_eval(&config.current), search_object)
|
11
|
+
return company_proxy if company_proxy.valid?
|
12
|
+
end
|
13
|
+
rescue NameError
|
14
|
+
end
|
15
|
+
|
16
|
+
raise NoCompanyFoundError
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid?
|
20
|
+
company.respond_to?(:id) && company.id.present?
|
21
|
+
end
|
22
|
+
|
23
|
+
def standard_data
|
24
|
+
hsh = {}
|
25
|
+
hsh[:id] = company.id
|
26
|
+
hsh[:name] = company.name if attribute_present?(:name)
|
27
|
+
hsh[:created_at] = company.created_at if attribute_present?(:created_at)
|
28
|
+
hsh
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module IntercomRails
|
2
|
+
|
3
|
+
module Proxy
|
4
|
+
|
5
|
+
class User < Proxy
|
6
|
+
|
7
|
+
POTENTIAL_USER_OBJECTS = [
|
8
|
+
Proc.new { instance_eval &IntercomRails.config.user.current if IntercomRails.config.user.current.present? },
|
9
|
+
Proc.new { current_user },
|
10
|
+
Proc.new { @user }
|
11
|
+
]
|
12
|
+
|
13
|
+
def self.current_in_context(search_object)
|
14
|
+
POTENTIAL_USER_OBJECTS.each do |potential_object|
|
15
|
+
begin
|
16
|
+
user_proxy = new(search_object.instance_eval(&potential_object), search_object)
|
17
|
+
return user_proxy if user_proxy.valid?
|
18
|
+
rescue NameError
|
19
|
+
next
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
raise NoUserFoundError
|
24
|
+
end
|
25
|
+
|
26
|
+
def standard_data
|
27
|
+
hsh = {}
|
28
|
+
|
29
|
+
hsh[:user_id] = user.id if attribute_present?(:id)
|
30
|
+
[:email, :name, :created_at].each do |attribute|
|
31
|
+
hsh[attribute] = user.send(attribute) if attribute_present?(attribute)
|
32
|
+
end
|
33
|
+
|
34
|
+
hsh
|
35
|
+
end
|
36
|
+
|
37
|
+
def valid?
|
38
|
+
return false if user.blank?
|
39
|
+
return true if user.respond_to?(:id) && user.id.present?
|
40
|
+
return true if user.respond_to?(:email) && user.email.present?
|
41
|
+
false
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -9,7 +9,7 @@ module IntercomRails
|
|
9
9
|
new(*args).output
|
10
10
|
end
|
11
11
|
|
12
|
-
attr_reader :user_details
|
12
|
+
attr_reader :user_details, :company_details
|
13
13
|
attr_accessor :secret, :widget_options, :controller
|
14
14
|
|
15
15
|
def initialize(options = {})
|
@@ -17,6 +17,11 @@ module IntercomRails
|
|
17
17
|
self.widget_options = widget_options_from_config.merge(options[:widget] || {})
|
18
18
|
self.controller = options[:controller]
|
19
19
|
self.user_details = options[:find_current_user_details] ? find_current_user_details : options[:user_details]
|
20
|
+
self.company_details = if options[:find_current_company_details]
|
21
|
+
find_current_company_details
|
22
|
+
elsif options[:user_details]
|
23
|
+
options[:user_details].delete(:company) if options[:user_details]
|
24
|
+
end
|
20
25
|
end
|
21
26
|
|
22
27
|
def valid?
|
@@ -24,10 +29,10 @@ module IntercomRails
|
|
24
29
|
end
|
25
30
|
|
26
31
|
def intercom_settings
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
32
|
+
hsh = user_details
|
33
|
+
hsh[:widget] = widget_options if widget_options.present?
|
34
|
+
hsh[:company] = company_details if company_details.present?
|
35
|
+
hsh
|
31
36
|
end
|
32
37
|
|
33
38
|
def output
|
@@ -69,11 +74,25 @@ module IntercomRails
|
|
69
74
|
|
70
75
|
def find_current_user_details
|
71
76
|
return {} unless controller.present?
|
72
|
-
|
77
|
+
Proxy::User.current_in_context(controller).to_hash
|
73
78
|
rescue NoUserFoundError
|
74
79
|
{}
|
75
80
|
end
|
76
81
|
|
82
|
+
def company_details=(company_details)
|
83
|
+
@company_details = convert_dates_to_unix_timestamps(company_details || {})
|
84
|
+
@company_details = @company_details.with_indifferent_access.tap do |c|
|
85
|
+
[:id, :name].each { |k| c.delete(k) if c[k].nil? }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def find_current_company_details
|
90
|
+
return {} unless controller.present?
|
91
|
+
Proxy::Company.current_in_context(controller).to_hash
|
92
|
+
rescue NoCompanyFoundError
|
93
|
+
{}
|
94
|
+
end
|
95
|
+
|
77
96
|
def user_hash
|
78
97
|
components = [secret, (user_details[:user_id] || user_details[:email])]
|
79
98
|
Digest::SHA1.hexdigest(components.join)
|
@@ -31,6 +31,7 @@ module IntercomRails
|
|
31
31
|
controller.instance_variable_set(IntercomRails::SCRIPT_TAG_HELPER_CALLED_INSTANCE_VARIABLE, true) if defined?(controller)
|
32
32
|
options[:user_details] = user_details if user_details.present?
|
33
33
|
options[:find_current_user_details] = !options[:user_details]
|
34
|
+
options[:find_current_company_details] = !(options[:user_details] && options[:user_details][:company])
|
34
35
|
options[:controller] = controller if defined?(controller)
|
35
36
|
|
36
37
|
ScriptTag.generate(options)
|
@@ -10,7 +10,7 @@ IntercomRails.config do |config|
|
|
10
10
|
<%- if @api_secret -%>
|
11
11
|
config.api_secret = "<%= @api_secret %>"
|
12
12
|
<%- else -%>
|
13
|
-
# config.api_secret =
|
13
|
+
# config.api_secret = "..."
|
14
14
|
<%- end -%>
|
15
15
|
|
16
16
|
# == Intercom API Key
|
@@ -27,23 +27,41 @@ IntercomRails.config do |config|
|
|
27
27
|
# The method/variable that contains the logged in user in your controllers.
|
28
28
|
# If it is `current_user` or `@user`, then you can ignore this
|
29
29
|
#
|
30
|
-
# config.
|
30
|
+
# config.user.current = Proc.new { current_user }
|
31
31
|
|
32
32
|
# == User model class
|
33
33
|
# The class which defines your user model
|
34
34
|
#
|
35
|
-
# config.
|
35
|
+
# config.user.model = Proc.new { User }
|
36
36
|
|
37
|
-
# == Custom Data
|
37
|
+
# == User Custom Data
|
38
38
|
# A hash of additional data you wish to send about your users.
|
39
39
|
# You can provide either a method name which will be sent to the current
|
40
40
|
# user object, or a Proc which will be passed the current user.
|
41
41
|
#
|
42
|
-
# config.custom_data = {
|
43
|
-
#
|
44
|
-
#
|
42
|
+
# config.user.custom_data = {
|
43
|
+
# :plan => Proc.new { |current_user| current_user.plan.name },
|
44
|
+
# :favorite_color => :favorite_color
|
45
45
|
# }
|
46
|
-
|
46
|
+
|
47
|
+
<%- if @app_id == 'tx2p130c' -%>
|
48
|
+
# == Current company name
|
49
|
+
# The method/variable that contains the current company for the current user,
|
50
|
+
# in your controllers. 'Companies' are generic groupings of users, so this
|
51
|
+
# could be a company, app or group.
|
52
|
+
#
|
53
|
+
# config.company.current = Proc.new { @app }
|
54
|
+
|
55
|
+
# == Company Custom Data
|
56
|
+
# A hash of additional data you wish to send about a company.
|
57
|
+
# This works the same as User custom data above.
|
58
|
+
#
|
59
|
+
# config.company.custom_data = {
|
60
|
+
# :number_of_messages => Proc.new { |app| app.messages.count },
|
61
|
+
# :is_interesting => :is_interesting?
|
62
|
+
# }
|
63
|
+
<%- end -%>
|
64
|
+
|
47
65
|
# == Inbox Style
|
48
66
|
# This enables the Intercom inbox which allows your users to read their
|
49
67
|
# past conversations with your app, as well as start new ones. It is
|
@@ -10,10 +10,16 @@ class TestController < ActionController::Base
|
|
10
10
|
@user = dummy_user
|
11
11
|
render :text => params[:body], :content_type => 'text/html'
|
12
12
|
end
|
13
|
+
|
14
|
+
def with_user_and_app_instance_variables
|
15
|
+
@user = dummy_user
|
16
|
+
@app = dummy_company
|
17
|
+
render :text => params[:body], :content_type => 'text/html'
|
18
|
+
end
|
13
19
|
|
14
20
|
def with_user_instance_variable_and_custom_data
|
15
21
|
@user = dummy_user
|
16
|
-
intercom_custom_data['testing_stuff'] = true
|
22
|
+
intercom_custom_data.user['testing_stuff'] = true
|
17
23
|
render :text => params[:body], :content_type => 'text/html'
|
18
24
|
end
|
19
25
|
|
@@ -80,7 +86,6 @@ class AutoIncludeFilterTest < ActionController::TestCase
|
|
80
86
|
def test_user_instance_variable_present_with_body_tag_and_custom_data
|
81
87
|
get :with_user_instance_variable_and_custom_data, :body => "<body>Hello world</body>"
|
82
88
|
assert_includes @response.body, "<script>"
|
83
|
-
assert_includes @response.body, "custom_data"
|
84
89
|
assert_includes @response.body, "testing_stuff"
|
85
90
|
end
|
86
91
|
|
@@ -93,8 +98,7 @@ class AutoIncludeFilterTest < ActionController::TestCase
|
|
93
98
|
end
|
94
99
|
|
95
100
|
def test_setting_current_user_with_intercom_config
|
96
|
-
IntercomRails.config.
|
97
|
-
|
101
|
+
IntercomRails.config.user.current = Proc.new { @admin }
|
98
102
|
get :with_admin_instance_variable, :body => "<body>Hello world</body>"
|
99
103
|
|
100
104
|
assert_includes @response.body, "<script>"
|
@@ -105,6 +109,7 @@ class AutoIncludeFilterTest < ActionController::TestCase
|
|
105
109
|
def test_auto_insert_with_api_secret_set
|
106
110
|
IntercomRails.config.api_secret = 'abcd'
|
107
111
|
get :with_current_user_method, :body => "<body>Hello world</body>"
|
112
|
+
|
108
113
|
assert_includes @response.body, "<script>"
|
109
114
|
assert_includes @response.body, "user_hash"
|
110
115
|
assert_includes @response.body, Digest::SHA1.hexdigest('abcd' + @controller.current_user.email)
|
@@ -126,4 +131,13 @@ class AutoIncludeFilterTest < ActionController::TestCase
|
|
126
131
|
assert_equal @response.body, "<body>Hello world</body>"
|
127
132
|
end
|
128
133
|
|
134
|
+
def test_includes_company
|
135
|
+
IntercomRails.config.company.current = Proc.new { @app }
|
136
|
+
get :with_user_and_app_instance_variables, :body => "<body>Hello world</body>"
|
137
|
+
|
138
|
+
assert_includes @response.body, "<script>"
|
139
|
+
assert_includes @response.body, "company"
|
140
|
+
assert_includes @response.body, "6"
|
141
|
+
end
|
142
|
+
|
129
143
|
end
|
@@ -11,13 +11,13 @@ class ConfigTest < MiniTest::Unit::TestCase
|
|
11
11
|
|
12
12
|
def test_setting_current_user
|
13
13
|
current_user = Proc.new { @blah }
|
14
|
-
IntercomRails.config.
|
15
|
-
assert_equal IntercomRails.config.
|
14
|
+
IntercomRails.config.user.current = current_user
|
15
|
+
assert_equal IntercomRails.config.user.current, current_user
|
16
16
|
end
|
17
17
|
|
18
18
|
def test_setting_current_user_not_to_a_proc
|
19
19
|
assert_raises ArgumentError do
|
20
|
-
IntercomRails.config.
|
20
|
+
IntercomRails.config.user.current = 1
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -31,7 +31,7 @@ class ConfigTest < MiniTest::Unit::TestCase
|
|
31
31
|
|
32
32
|
def test_custom_data_rejects_non_proc_or_symbol_attributes
|
33
33
|
exception = assert_raises ArgumentError do
|
34
|
-
IntercomRails.config.custom_data = {
|
34
|
+
IntercomRails.config.user.custom_data = {
|
35
35
|
'foo' => Proc.new {},
|
36
36
|
'bar' => 'heyheyhey!'
|
37
37
|
}
|
@@ -46,14 +46,19 @@ class ConfigTest < MiniTest::Unit::TestCase
|
|
46
46
|
'bar' => :method_name
|
47
47
|
}
|
48
48
|
|
49
|
-
IntercomRails.config.custom_data = custom_data_config
|
50
|
-
assert_equal custom_data_config, IntercomRails.config.custom_data
|
49
|
+
IntercomRails.config.user.custom_data = custom_data_config
|
50
|
+
assert_equal custom_data_config, IntercomRails.config.user.custom_data
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_setting_inbox_style
|
54
|
+
IntercomRails.config.inbox.style = :custom
|
55
|
+
assert_equal :custom, IntercomRails.config.inbox.style
|
51
56
|
end
|
52
57
|
|
53
58
|
def test_reset_clears_existing_config
|
54
|
-
IntercomRails.config.custom_data = {'muffin' => :muffin}
|
59
|
+
IntercomRails.config.user.custom_data = {'muffin' => :muffin}
|
55
60
|
IntercomRails.config.reset!
|
56
|
-
assert_equal nil, IntercomRails.config.custom_data
|
61
|
+
assert_equal nil, IntercomRails.config.user.custom_data
|
57
62
|
end
|
58
63
|
|
59
64
|
def test_reset_clears_inbox_config_too
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'test_setup'
|
2
|
+
|
3
|
+
class CompanyTest < MiniTest::Unit::TestCase
|
4
|
+
|
5
|
+
include InterTest
|
6
|
+
|
7
|
+
Company = IntercomRails::Proxy::Company
|
8
|
+
DUMMY_COMPANY = dummy_company
|
9
|
+
|
10
|
+
def test_finds_current_company
|
11
|
+
IntercomRails.config.company.current = Proc.new { @app }
|
12
|
+
object_with_app_instance_var = Object.new
|
13
|
+
object_with_app_instance_var.instance_variable_set(:@app, DUMMY_COMPANY)
|
14
|
+
|
15
|
+
c = Company.current_in_context(object_with_app_instance_var)
|
16
|
+
assert_equal true, c.valid?
|
17
|
+
expected_hash = {:id => '6', :name => 'Intercom'}
|
18
|
+
assert_equal expected_hash, c.to_hash
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'test_setup'
|
2
2
|
|
3
|
-
class
|
3
|
+
class UserTest < MiniTest::Unit::TestCase
|
4
|
+
|
5
|
+
User = IntercomRails::Proxy::User
|
4
6
|
|
5
7
|
include InterTest
|
6
8
|
include IntercomRails
|
@@ -9,7 +11,7 @@ class UserProxyTest < MiniTest::Unit::TestCase
|
|
9
11
|
|
10
12
|
def test_raises_error_when_no_user_found
|
11
13
|
assert_raises(IntercomRails::NoUserFoundError) {
|
12
|
-
|
14
|
+
User.current_in_context(Object.new)
|
13
15
|
}
|
14
16
|
end
|
15
17
|
|
@@ -21,7 +23,7 @@ class UserProxyTest < MiniTest::Unit::TestCase
|
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
24
|
-
@user_proxy =
|
26
|
+
@user_proxy = User.current_in_context(object_with_current_user_method)
|
25
27
|
assert_user_found
|
26
28
|
end
|
27
29
|
|
@@ -31,7 +33,7 @@ class UserProxyTest < MiniTest::Unit::TestCase
|
|
31
33
|
@user = DUMMY_USER
|
32
34
|
end
|
33
35
|
|
34
|
-
@user_proxy =
|
36
|
+
@user_proxy = User.current_in_context(object_with_instance_variable)
|
35
37
|
assert_user_found
|
36
38
|
end
|
37
39
|
|
@@ -43,8 +45,8 @@ class UserProxyTest < MiniTest::Unit::TestCase
|
|
43
45
|
end
|
44
46
|
end
|
45
47
|
|
46
|
-
IntercomRails.config.
|
47
|
-
@user_proxy =
|
48
|
+
IntercomRails.config.user.current = Proc.new { something_esoteric }
|
49
|
+
@user_proxy = User.current_in_context(object_from_config)
|
48
50
|
assert_user_found
|
49
51
|
end
|
50
52
|
|
@@ -60,36 +62,41 @@ class UserProxyTest < MiniTest::Unit::TestCase
|
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
63
|
-
IntercomRails.config.custom_data = {
|
65
|
+
IntercomRails.config.user.custom_data = {
|
64
66
|
'plan' => :plan
|
65
67
|
}
|
66
68
|
|
67
|
-
@user_proxy =
|
68
|
-
|
69
|
-
assert_equal expected_custom_data, @user_proxy.to_hash[:custom_data]
|
69
|
+
@user_proxy = User.new(plan_dummy_user)
|
70
|
+
assert_equal 'pro', @user_proxy.to_hash['plan']
|
70
71
|
end
|
71
72
|
|
72
73
|
def test_valid_returns_true_if_user_id_or_email
|
73
|
-
assert_equal true,
|
74
|
+
assert_equal true, User.new(DUMMY_USER).valid?
|
74
75
|
end
|
75
76
|
|
76
77
|
def test_includes_custom_data_from_intercom_custom_data
|
77
78
|
object_with_intercom_custom_data = Object.new
|
78
79
|
object_with_intercom_custom_data.instance_eval do
|
79
80
|
def intercom_custom_data
|
80
|
-
|
81
|
+
o = Object.new
|
82
|
+
o.instance_eval do
|
83
|
+
def user
|
84
|
+
{:ponies => :rainbows}
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
o
|
81
89
|
end
|
82
90
|
end
|
83
91
|
|
84
|
-
@user_proxy =
|
85
|
-
|
86
|
-
assert_equal expected_custom_data, @user_proxy.to_hash[:custom_data]
|
92
|
+
@user_proxy = User.new(DUMMY_USER, object_with_intercom_custom_data)
|
93
|
+
assert_equal :rainbows, @user_proxy.to_hash[:ponies]
|
87
94
|
end
|
88
95
|
|
89
96
|
def test_valid_returns_false_for_nil
|
90
97
|
search_object = false
|
91
98
|
search_object.stub(:id) { raise NameError }
|
92
|
-
assert_equal false,
|
99
|
+
assert_equal false, User.new(search_object).valid?
|
93
100
|
end
|
94
101
|
|
95
102
|
end
|
@@ -87,5 +87,17 @@ class ScriptTagTest < MiniTest::Unit::TestCase
|
|
87
87
|
assert_equal expected_widget_settings, script_tag.intercom_settings['widget']
|
88
88
|
end
|
89
89
|
|
90
|
+
def test_company_discovery_and_inclusion
|
91
|
+
IntercomRails.config.company.current = Proc.new { @app }
|
92
|
+
object_with_app_instance_variable = Object.new
|
93
|
+
object_with_app_instance_variable.instance_eval do
|
94
|
+
@app = dummy_company
|
95
|
+
end
|
96
|
+
|
97
|
+
script_tag = ScriptTag.new(:controller => object_with_app_instance_variable,
|
98
|
+
:find_current_company_details => true)
|
99
|
+
expected_company = {'id' => '6', 'name' => 'Intercom'}
|
100
|
+
assert_equal expected_company, script_tag.intercom_settings[:company]
|
101
|
+
end
|
90
102
|
|
91
103
|
end
|
data/test/test_setup.rb
CHANGED
@@ -10,6 +10,13 @@ def dummy_user(options = {})
|
|
10
10
|
user
|
11
11
|
end
|
12
12
|
|
13
|
+
def dummy_company(options = {})
|
14
|
+
company = Struct.new(:id, :name).new
|
15
|
+
company.id = options[:id] || '6'
|
16
|
+
company.name = options[:name] || 'Intercom'
|
17
|
+
company
|
18
|
+
end
|
19
|
+
|
13
20
|
def fake_action_view_class
|
14
21
|
klass = Class.new(ActionView::Base)
|
15
22
|
klass.class_eval do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: intercom-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -143,10 +143,12 @@ files:
|
|
143
143
|
- lib/intercom-rails/exceptions.rb
|
144
144
|
- lib/intercom-rails/import.rb
|
145
145
|
- lib/intercom-rails/intercom.rake
|
146
|
+
- lib/intercom-rails/proxy/company.rb
|
147
|
+
- lib/intercom-rails/proxy/user.rb
|
148
|
+
- lib/intercom-rails/proxy.rb
|
146
149
|
- lib/intercom-rails/railtie.rb
|
147
150
|
- lib/intercom-rails/script_tag.rb
|
148
151
|
- lib/intercom-rails/script_tag_helper.rb
|
149
|
-
- lib/intercom-rails/user_proxy.rb
|
150
152
|
- lib/intercom-rails/version.rb
|
151
153
|
- lib/intercom-rails.rb
|
152
154
|
- lib/rails/generators/intercom/config/config_generator.rb
|
@@ -160,9 +162,10 @@ files:
|
|
160
162
|
- test/intercom-rails/config_test.rb
|
161
163
|
- test/intercom-rails/import_network_test.rb
|
162
164
|
- test/intercom-rails/import_unit_test.rb
|
165
|
+
- test/intercom-rails/proxy/company_test.rb
|
166
|
+
- test/intercom-rails/proxy/user_test.rb
|
163
167
|
- test/intercom-rails/script_tag_helper_test.rb
|
164
168
|
- test/intercom-rails/script_tag_test.rb
|
165
|
-
- test/intercom-rails/user_proxy_test.rb
|
166
169
|
- test/test_setup.rb
|
167
170
|
homepage: http://www.intercom.io
|
168
171
|
licenses: []
|
@@ -178,7 +181,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
178
181
|
version: '0'
|
179
182
|
segments:
|
180
183
|
- 0
|
181
|
-
hash:
|
184
|
+
hash: -893769769593597927
|
182
185
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
183
186
|
none: false
|
184
187
|
requirements:
|
@@ -187,7 +190,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
187
190
|
version: '0'
|
188
191
|
segments:
|
189
192
|
- 0
|
190
|
-
hash:
|
193
|
+
hash: -893769769593597927
|
191
194
|
requirements: []
|
192
195
|
rubyforge_project: intercom-rails
|
193
196
|
rubygems_version: 1.8.23
|
@@ -201,7 +204,8 @@ test_files:
|
|
201
204
|
- test/intercom-rails/config_test.rb
|
202
205
|
- test/intercom-rails/import_network_test.rb
|
203
206
|
- test/intercom-rails/import_unit_test.rb
|
207
|
+
- test/intercom-rails/proxy/company_test.rb
|
208
|
+
- test/intercom-rails/proxy/user_test.rb
|
204
209
|
- test/intercom-rails/script_tag_helper_test.rb
|
205
210
|
- test/intercom-rails/script_tag_test.rb
|
206
|
-
- test/intercom-rails/user_proxy_test.rb
|
207
211
|
- test/test_setup.rb
|
@@ -1,84 +0,0 @@
|
|
1
|
-
module IntercomRails
|
2
|
-
|
3
|
-
class UserProxy
|
4
|
-
|
5
|
-
POTENTIAL_USER_OBJECTS = [
|
6
|
-
Proc.new { instance_eval &IntercomRails.config.current_user if IntercomRails.config.current_user.present? },
|
7
|
-
Proc.new { current_user },
|
8
|
-
Proc.new { @user }
|
9
|
-
]
|
10
|
-
|
11
|
-
def self.from_current_user_in_object(search_object)
|
12
|
-
POTENTIAL_USER_OBJECTS.each do |potential_user|
|
13
|
-
begin
|
14
|
-
user_proxy = new(search_object.instance_eval(&potential_user), search_object)
|
15
|
-
return user_proxy if user_proxy.valid?
|
16
|
-
rescue NameError
|
17
|
-
next
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
raise NoUserFoundError
|
22
|
-
end
|
23
|
-
|
24
|
-
attr_reader :search_object, :user
|
25
|
-
|
26
|
-
def initialize(user, search_object = nil)
|
27
|
-
@user = user
|
28
|
-
@search_object = search_object
|
29
|
-
end
|
30
|
-
|
31
|
-
def to_hash
|
32
|
-
hsh = {}
|
33
|
-
|
34
|
-
hsh[:user_id] = user.id if attribute_present?(:id)
|
35
|
-
[:email, :name, :created_at].each do |attribute|
|
36
|
-
hsh[attribute] = user.send(attribute) if attribute_present?(attribute)
|
37
|
-
end
|
38
|
-
|
39
|
-
hsh[:custom_data] = custom_data
|
40
|
-
hsh.delete(:custom_data) unless hsh[:custom_data].present?
|
41
|
-
|
42
|
-
hsh
|
43
|
-
end
|
44
|
-
|
45
|
-
def custom_data
|
46
|
-
custom_data_from_config.merge custom_data_from_request
|
47
|
-
end
|
48
|
-
|
49
|
-
def valid?
|
50
|
-
return false if user.blank?
|
51
|
-
return true if user.respond_to?(:id) && user.id.present?
|
52
|
-
return true if user.respond_to?(:email) && user.email.present?
|
53
|
-
false
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
def attribute_present?(attribute)
|
58
|
-
user.respond_to?(attribute) && user.send(attribute).present?
|
59
|
-
end
|
60
|
-
|
61
|
-
def custom_data_value_from_proc_or_symbol(proc_or_symbol)
|
62
|
-
if proc_or_symbol.kind_of?(Symbol)
|
63
|
-
user.send(proc_or_symbol)
|
64
|
-
elsif proc_or_symbol.kind_of?(Proc)
|
65
|
-
proc_or_symbol.call(user)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def custom_data_from_request
|
70
|
-
search_object.intercom_custom_data
|
71
|
-
rescue NoMethodError
|
72
|
-
{}
|
73
|
-
end
|
74
|
-
|
75
|
-
def custom_data_from_config
|
76
|
-
return {} if Config.custom_data.blank?
|
77
|
-
Config.custom_data.reduce({}) do |custom_data, (k,v)|
|
78
|
-
custom_data.merge(k => custom_data_value_from_proc_or_symbol(v))
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|