web47core 0.0.9 → 0.0.10
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/Gemfile.lock +16 -4
- data/README.md +37 -33
- data/config/locales/en.yml +11 -0
- data/lib/app/models/concerns/app47_logger.rb +1 -1
- data/lib/app/models/concerns/core_system_configuration.rb +5 -1
- data/lib/app/models/concerns/email_able.rb +84 -0
- data/lib/app/models/concerns/search_able.rb +100 -0
- data/lib/app/models/concerns/standard_model.rb +2 -2
- data/lib/app/models/concerns/time_zone_able.rb +49 -0
- data/lib/app/models/notification.rb +3 -3
- data/lib/app/models/redis_configuration.rb +137 -0
- data/lib/app/models/slack_notification.rb +14 -30
- data/lib/app/models/sms_notification.rb +5 -7
- data/lib/app/models/smtp_configuration.rb +14 -89
- data/lib/web47core.rb +4 -0
- data/test/fixtures/redis/host.yml +5 -0
- data/test/fixtures/redis/options.yml +8 -0
- data/test/fixtures/redis/sentinel.yml +8 -0
- data/test/fixtures/redis/url.yml +2 -0
- data/test/models/concerns/email_able_test.rb +145 -0
- data/test/models/concerns/search_able_test.rb +80 -0
- data/test/models/concerns/standard_model_test.rb +62 -1
- data/test/models/concerns/time_zone_able_test.rb +77 -0
- data/test/models/redis_configuration_test.rb +86 -0
- data/test/models/slack_notification_test.rb +41 -0
- data/test/models/sms_notification_test.rb +69 -0
- data/test/models/smtp_configuration_test.rb +66 -0
- data/test/test_helper.rb +5 -1
- data/web47core.gemspec +7 -4
- metadata +87 -14
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
#
|
4
|
+
# Temp class for testing
|
5
|
+
#
|
6
|
+
class EmailModel
|
7
|
+
include Mongoid::Document
|
8
|
+
include Mongoid::Timestamps
|
9
|
+
include EmailAble
|
10
|
+
field :once, type: String
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
# Test the email model
|
15
|
+
#
|
16
|
+
class EmailModelTest < ActiveSupport::TestCase
|
17
|
+
should_have_field :email, type: String, klass: EmailModel
|
18
|
+
should_have_field :email_bounced_at, type: Time, klass: EmailModel
|
19
|
+
should_have_field :email_bounce_reason, type: String, klass: EmailModel
|
20
|
+
should_have_field :unconfirmed_email, type: String, klass: EmailModel
|
21
|
+
should_have_field :email_enabled, type: Mongoid::Boolean, default: true, klass: EmailModel
|
22
|
+
|
23
|
+
context 'valid email' do
|
24
|
+
should 'not be valid' do
|
25
|
+
email = EmailModel.new
|
26
|
+
email.email = 'nothing'
|
27
|
+
refute email.valid?
|
28
|
+
end
|
29
|
+
should 'be valid' do
|
30
|
+
email = EmailModel.new
|
31
|
+
email.email = 'joe@abc.com'
|
32
|
+
assert email.valid?
|
33
|
+
assert email.valid_email?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'valid_email?' do
|
38
|
+
setup do
|
39
|
+
@model = EmailModel.new
|
40
|
+
@email = 'known@abc.com'
|
41
|
+
@model.email = @email
|
42
|
+
assert @model.save
|
43
|
+
end
|
44
|
+
should 'be valid by default' do
|
45
|
+
assert @model.valid_email?
|
46
|
+
end
|
47
|
+
should 'not be valid with email_bounce_date' do
|
48
|
+
@model.email_bounced_at = Time.now.utc
|
49
|
+
refute @model.valid_email?
|
50
|
+
end
|
51
|
+
should 'not be valid with enabled turned off' do
|
52
|
+
@model.email_enabled = false
|
53
|
+
refute @model.valid_email?
|
54
|
+
end
|
55
|
+
should 'not be valid with enabled turned off and email_bounce_date' do
|
56
|
+
@model.email_bounced_at = Time.now.utc
|
57
|
+
@model.email_enabled = false
|
58
|
+
refute @model.valid_email?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'reset bounce status with mailgun' do
|
63
|
+
setup do
|
64
|
+
@model = EmailModel.new
|
65
|
+
@email = 'known@abc.com'
|
66
|
+
@model.email = @email
|
67
|
+
@model.email_bounced_at = Time.now.utc
|
68
|
+
@model.email_bounce_reason = 'Testing'
|
69
|
+
assert @model.save
|
70
|
+
end
|
71
|
+
should 'not be called if not configured' do
|
72
|
+
config = SystemConfiguration.configuration
|
73
|
+
config.unset :mailgun_api_key
|
74
|
+
assert config.save
|
75
|
+
RestClient.expects(:delete).never
|
76
|
+
@model.reset_bounce_status
|
77
|
+
assert @model.valid_email?, @model.inspect
|
78
|
+
end
|
79
|
+
should 'reset bounce status' do
|
80
|
+
refute @model.valid_email?
|
81
|
+
config = SystemConfiguration.configuration
|
82
|
+
config.smtp_name = 'app47'
|
83
|
+
config.smtp_address = 'mail.app47.com'
|
84
|
+
config.smtp_domain = 'app47.com'
|
85
|
+
config.mailgun_api_key = 'key'
|
86
|
+
assert config.save
|
87
|
+
RestClient.expects(:delete).once.returns(MockHttpResponse.new)
|
88
|
+
@model.reset_bounce_status
|
89
|
+
assert_not_nil @model.reload
|
90
|
+
assert @model.valid_email?
|
91
|
+
end
|
92
|
+
should 'handle error code from rest client' do
|
93
|
+
App47Logger.expects(:log_error).once
|
94
|
+
refute @model.valid_email?
|
95
|
+
config = SystemConfiguration.configuration
|
96
|
+
config.smtp_name = 'app47'
|
97
|
+
config.smtp_address = 'mail.app47.com'
|
98
|
+
config.smtp_domain = 'app47.com'
|
99
|
+
config.mailgun_api_key = 'key'
|
100
|
+
assert config.save
|
101
|
+
RestClient.expects(:delete).once.raises(RestClient::Exception.new(MockHttpResponse.new(404)))
|
102
|
+
@model.reset_bounce_status
|
103
|
+
assert_not_nil @model.reload
|
104
|
+
assert @model.valid_email?
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'gravatar_url' do
|
109
|
+
setup do
|
110
|
+
@model = EmailModel.new
|
111
|
+
@email = 'known@abc.com'
|
112
|
+
@model.email = @email
|
113
|
+
assert @model.save
|
114
|
+
end
|
115
|
+
should 'go to gravatar site' do
|
116
|
+
url = @model.gravatar_url
|
117
|
+
assert url.start_with? 'https://www.gravatar.com/avatar/', url
|
118
|
+
end
|
119
|
+
should 'correct defaults' do
|
120
|
+
url = @model.gravatar_url
|
121
|
+
assert url.include?('s=32'), url
|
122
|
+
assert url.include?('d=mm'), url
|
123
|
+
end
|
124
|
+
should 'override size' do
|
125
|
+
url = @model.gravatar_url(1024)
|
126
|
+
refute url.include?('s=32'), url
|
127
|
+
assert url.include?('s=1024'), url
|
128
|
+
end
|
129
|
+
should 'override default' do
|
130
|
+
url = @model.gravatar_url(1024, 'retro')
|
131
|
+
refute url.include?('d=mm'), url
|
132
|
+
assert url.include?('d=retro'), url
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
#
|
137
|
+
# Mock class for testing
|
138
|
+
#
|
139
|
+
class MockHttpResponse
|
140
|
+
attr_accessor :code
|
141
|
+
|
142
|
+
def initialize(code = 200)
|
143
|
+
@code = code
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SearchableTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
context 'Update search text on save' do
|
6
|
+
|
7
|
+
should 'update name' do
|
8
|
+
model = NameSearchable.new
|
9
|
+
assert model.save
|
10
|
+
assert_equal 'name', model.search_text
|
11
|
+
end
|
12
|
+
|
13
|
+
should 'update text' do
|
14
|
+
model = NameEmailSearchable.new
|
15
|
+
assert model.save
|
16
|
+
assert_equal 'name email@abc.com', model.search_text
|
17
|
+
end
|
18
|
+
should 'update text handle nil values' do
|
19
|
+
model = NameEmailCodeSearchable.new
|
20
|
+
assert model.save
|
21
|
+
assert_equal 'name email@abc.com', model.search_text
|
22
|
+
end
|
23
|
+
should 'update text with code' do
|
24
|
+
model = NameEmailCodeSearchable.new
|
25
|
+
model.code = 'FOOBar'
|
26
|
+
assert model.save
|
27
|
+
assert_equal 'name email@abc.com foobar', model.search_text
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'search for items' do
|
32
|
+
should 'update text' do
|
33
|
+
NameEmailSearchable.create
|
34
|
+
NameEmailSearchable.create
|
35
|
+
NameEmailSearchable.create
|
36
|
+
model = NameEmailSearchable.new
|
37
|
+
model.name = 'defJKL'
|
38
|
+
assert model.save
|
39
|
+
assert_not_nil model
|
40
|
+
assert_equal 'defjkl email@abc.com', model.search_text
|
41
|
+
assert_equal 1, NameEmailSearchable.matching_search_text('defjkl').count
|
42
|
+
end
|
43
|
+
should 'return sort order' do
|
44
|
+
assert_equal [['name', 1], ['email', 1]], NameEmailSearchable.sort_order
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class NameSearchable
|
50
|
+
include Mongoid::Document
|
51
|
+
include SearchAble
|
52
|
+
field :name, type: String, default: 'Name'
|
53
|
+
field :email, type: String, default: 'email@abc.com'
|
54
|
+
end
|
55
|
+
|
56
|
+
class NameEmailSearchable
|
57
|
+
include Mongoid::Document
|
58
|
+
include SearchAble
|
59
|
+
field :name, type: String, default: 'Name'
|
60
|
+
field :email, type: String, default: 'email@abc.com'
|
61
|
+
|
62
|
+
def search_fields
|
63
|
+
%w[name email]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class NameEmailCodeSearchable
|
68
|
+
include Mongoid::Document
|
69
|
+
include SearchAble
|
70
|
+
field :name, type: String, default: 'Name'
|
71
|
+
field :email, type: String, default: 'email@abc.com'
|
72
|
+
field :code, type: String
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def search_fields
|
77
|
+
%w(name email code)
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -12,9 +12,18 @@ class StandardModelTest < ActiveSupport::TestCase
|
|
12
12
|
end
|
13
13
|
should 'return test input fields' do
|
14
14
|
allowed = TestInput.allowed_param_names
|
15
|
-
assert_equal
|
15
|
+
assert_equal 3, allowed.count
|
16
|
+
assert allowed.include?('input_type'), allowed.inspect
|
17
|
+
assert allowed.include?('test_form_id'), allowed.inspect
|
18
|
+
refute allowed.include?('test_input_field_ids'), allowed.inspect
|
19
|
+
end
|
20
|
+
should 'handle error' do
|
21
|
+
TestInput.expects(:all_associations).once.raises('Doh')
|
22
|
+
allowed = TestInput.allowed_param_names
|
23
|
+
assert_equal 3, allowed.count, allowed.inspect
|
16
24
|
assert allowed.include?('input_type'), allowed.inspect
|
17
25
|
assert allowed.include?('test_form_id'), allowed.inspect
|
26
|
+
assert allowed.include?('test_input_field_ids'), allowed.inspect
|
18
27
|
end
|
19
28
|
end
|
20
29
|
context 'update the model safely' do
|
@@ -64,6 +73,39 @@ class StandardModelTest < ActiveSupport::TestCase
|
|
64
73
|
assert @model.save
|
65
74
|
refute Rails.cache.exist? @model.id.to_s
|
66
75
|
end
|
76
|
+
should 'handle error' do
|
77
|
+
Rails.cache.expects(:delete_matched).once.raises('Doh')
|
78
|
+
assert Rails.cache.exist? @model.id.to_s
|
79
|
+
assert @model.save
|
80
|
+
assert Rails.cache.exist? @model.id.to_s
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'skip call back' do
|
85
|
+
setup do
|
86
|
+
@model = TestCallBack.new value: 'foo'
|
87
|
+
end
|
88
|
+
should 'use call back' do
|
89
|
+
assert_equal 'foo', @model.value
|
90
|
+
@model.value = 'foobar'
|
91
|
+
assert @model.save
|
92
|
+
@model.reload
|
93
|
+
assert_equal 'bar', @model.value
|
94
|
+
end
|
95
|
+
should 'not use call back' do
|
96
|
+
assert_equal 'foo', @model.value
|
97
|
+
@model.value = 'foobar'
|
98
|
+
TestCallBack.without_callback(:save, :before, :bar_it) do
|
99
|
+
assert @model.save
|
100
|
+
end
|
101
|
+
@model.reload
|
102
|
+
assert_equal 'foobar', @model.value
|
103
|
+
end
|
104
|
+
end
|
105
|
+
context 'make_options' do
|
106
|
+
should 'return array' do
|
107
|
+
assert_equal [%w[one One], %w[two Two], %w[three Three]], TestForm.make_options(%w[one two three])
|
108
|
+
end
|
67
109
|
end
|
68
110
|
end
|
69
111
|
|
@@ -82,6 +124,14 @@ class TestInput
|
|
82
124
|
include StandardModel
|
83
125
|
field :input_type
|
84
126
|
belongs_to :test_form
|
127
|
+
has_and_belongs_to_many :test_input_field
|
128
|
+
end
|
129
|
+
|
130
|
+
class TestInputField
|
131
|
+
include StandardModel
|
132
|
+
field :input_type
|
133
|
+
belongs_to :test_form
|
134
|
+
has_and_belongs_to_many :test_input
|
85
135
|
end
|
86
136
|
|
87
137
|
class TestAutoClearCache
|
@@ -90,4 +140,15 @@ class TestAutoClearCache
|
|
90
140
|
def update_cache(value = 'abc123')
|
91
141
|
Rails.cache.write id.to_s, value, expires_in: 60
|
92
142
|
end
|
143
|
+
end
|
144
|
+
|
145
|
+
class TestCallBack
|
146
|
+
include StandardModel
|
147
|
+
|
148
|
+
field :value, type: String, default: 'foo'
|
149
|
+
before_save :bar_it
|
150
|
+
|
151
|
+
def bar_it
|
152
|
+
self.value = 'bar'
|
153
|
+
end
|
93
154
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
|
4
|
+
#
|
5
|
+
# Test the Searchable module
|
6
|
+
#
|
7
|
+
class TimeZoneAbleTest < ActiveSupport::TestCase
|
8
|
+
context 'have default' do
|
9
|
+
should 'set default' do
|
10
|
+
o = TimeZoneTestObject.new
|
11
|
+
assert_nil o.time_zone
|
12
|
+
assert o.save
|
13
|
+
assert_equal 'US/Eastern', o.time_zone
|
14
|
+
end
|
15
|
+
should 'have valid field values' do
|
16
|
+
o = TimeZoneTestObject.new
|
17
|
+
TZInfo::Timezone.all_identifiers.each do |tz|
|
18
|
+
o.time_zone = tz
|
19
|
+
assert o.valid?, o.errors.inspect
|
20
|
+
end
|
21
|
+
end
|
22
|
+
should 'invalid format' do
|
23
|
+
o = TimeZoneTestObject.new
|
24
|
+
o.time_zone = 'Eastern/US'
|
25
|
+
refute o.valid?
|
26
|
+
end
|
27
|
+
should 'pull from system configuration' do
|
28
|
+
assert SystemConfiguration.configuration.update default_time_zone: 'EST'
|
29
|
+
o = TimeZoneTestObject.new
|
30
|
+
assert_nil o.time_zone
|
31
|
+
assert o.save
|
32
|
+
assert_equal 'EST', o.time_zone
|
33
|
+
end
|
34
|
+
end
|
35
|
+
context 'return local time' do
|
36
|
+
setup do
|
37
|
+
@test_obj = TimeZoneTestObject.create!
|
38
|
+
@now = Time.now.utc
|
39
|
+
end
|
40
|
+
should 'give same as account' do
|
41
|
+
tz = TZInfo::Timezone.get('US/Eastern')
|
42
|
+
assert_equal I18n.l(@now.in_time_zone(tz), format: :medium), @test_obj.local_time(@now)
|
43
|
+
end
|
44
|
+
should 'handle error' do
|
45
|
+
TZInfo::Timezone.expects(:get).once.raises('Doh')
|
46
|
+
assert_equal 'Never now', @test_obj.local_time(@now, :medium, 'Never now')
|
47
|
+
end
|
48
|
+
should 'handle error with default' do
|
49
|
+
TZInfo::Timezone.expects(:get).once.raises('Doh')
|
50
|
+
assert_equal 'N/A', @test_obj.local_time(@now)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
context 'return updated_at' do
|
54
|
+
setup do
|
55
|
+
@test_obj = TimeZoneTestObject.create!
|
56
|
+
@now = Time.now.utc
|
57
|
+
end
|
58
|
+
should 'give same as account' do
|
59
|
+
tz = TZInfo::Timezone.get('US/Eastern')
|
60
|
+
assert_equal I18n.l(@now.in_time_zone(tz), format: :medium), @test_obj.local_updated_time(@test_obj)
|
61
|
+
end
|
62
|
+
should 'handle error' do
|
63
|
+
@test_obj.expects(:updated_at).once.raises('Doh')
|
64
|
+
assert_equal 'Never now', @test_obj.local_updated_time(@test_obj, :medium, 'Never now')
|
65
|
+
end
|
66
|
+
should 'handle error with default' do
|
67
|
+
@test_obj.expects(:updated_at).once.raises('Doh')
|
68
|
+
assert_equal 'N/A', @test_obj.local_updated_time(@test_obj)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class TimeZoneTestObject
|
74
|
+
include Mongoid::Document
|
75
|
+
include Mongoid::Timestamps
|
76
|
+
include TimeZoneAble
|
77
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
#
|
4
|
+
# Test the RedisConfiguration model
|
5
|
+
#
|
6
|
+
class RedisConfigurationTest < ActiveSupport::TestCase
|
7
|
+
context 'default file' do
|
8
|
+
should 'return the default configuration file the config file' do
|
9
|
+
config = RedisConfiguration.load
|
10
|
+
refute config[:url].eql?('redis://127.0.0.1:6379'), config.inspect
|
11
|
+
assert_equal 0, config[:db], config.inspect
|
12
|
+
end
|
13
|
+
should 'override the database' do
|
14
|
+
config = RedisConfiguration.load(9)
|
15
|
+
refute config[:url].eql?('redis://127.0.0.1:6379'), config.inspect
|
16
|
+
assert_equal 9, config[:db], config.inspect
|
17
|
+
end
|
18
|
+
end
|
19
|
+
context 'no file' do
|
20
|
+
setup do
|
21
|
+
RedisConfiguration.expects(:config_file_path).returns('config/nothing').at_least_once
|
22
|
+
end
|
23
|
+
should 'return default' do
|
24
|
+
config = RedisConfiguration.load
|
25
|
+
assert_equal '127.0.0.1', config[:host], config.inspect
|
26
|
+
assert_equal 6379, config[:port], config.inspect
|
27
|
+
assert_equal 0, config[:db], config.inspect
|
28
|
+
end
|
29
|
+
should 'set the database' do
|
30
|
+
config = RedisConfiguration.load(5)
|
31
|
+
assert_equal '127.0.0.1', config[:host], config.inspect
|
32
|
+
assert_equal 6379, config[:port], config.inspect
|
33
|
+
assert_equal 5, config[:db], config.inspect
|
34
|
+
end
|
35
|
+
end
|
36
|
+
context 'url' do
|
37
|
+
setup do
|
38
|
+
RedisConfiguration.expects(:config_file_path).returns('test/fixtures/redis/url.yml').at_least_once
|
39
|
+
end
|
40
|
+
should 'return url configuration' do
|
41
|
+
config = RedisConfiguration.load
|
42
|
+
# assert_equal 'redis://localhost:6379/0', config[:url], config.inspect
|
43
|
+
end
|
44
|
+
end
|
45
|
+
context 'host' do
|
46
|
+
setup do
|
47
|
+
RedisConfiguration.expects(:config_file_path).returns('test/fixtures/redis/host.yml').at_least_once
|
48
|
+
end
|
49
|
+
should 'load from file' do
|
50
|
+
config = RedisConfiguration.load
|
51
|
+
assert_equal '127.0.0.1', config[:host], config.inspect
|
52
|
+
assert_equal 6378, config[:port], config.inspect
|
53
|
+
assert_equal 8, config[:db], config.inspect
|
54
|
+
assert_equal 'cache', config[:namespace], config.inspect
|
55
|
+
end
|
56
|
+
should 'load from file and override database number' do
|
57
|
+
config = RedisConfiguration.load(6)
|
58
|
+
assert_equal '127.0.0.1', config[:host], config.inspect
|
59
|
+
assert_equal 6378, config[:port], config.inspect
|
60
|
+
assert_equal 6, config[:db], config.inspect
|
61
|
+
end
|
62
|
+
end
|
63
|
+
context 'sentinel' do
|
64
|
+
setup do
|
65
|
+
RedisConfiguration.expects(:config_file_path).returns('test/fixtures/redis/sentinel.yml').at_least_once
|
66
|
+
end
|
67
|
+
should 'load file' do
|
68
|
+
config = RedisConfiguration.load
|
69
|
+
assert_equal 'redis://production', config[:url], config.inspect
|
70
|
+
assert_equal 'master', config[:role], config.inspect
|
71
|
+
sentinels = config[:sentinels]
|
72
|
+
assert_not_nil sentinels
|
73
|
+
assert_equal 3, sentinels.count
|
74
|
+
assert_equal 'host1', sentinels.first[:host]
|
75
|
+
assert_equal 0, config[:db], config.inspect
|
76
|
+
assert_equal 'cache', config[:namespace], config.inspect
|
77
|
+
end
|
78
|
+
should 'load file and set database' do
|
79
|
+
config = RedisConfiguration.load(8)
|
80
|
+
sentinels = config[:sentinels]
|
81
|
+
assert_not_nil sentinels
|
82
|
+
assert_equal 3, sentinels.count, config.inspect
|
83
|
+
assert_equal 8, config[:db], config.inspect
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|