sms_validation 0.0.1
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 +7 -0
- data/.gitignore +14 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +87 -0
- data/Rakefile +2 -0
- data/lib/sms_validation.rb +5 -0
- data/lib/sms_validation/configuration.rb +48 -0
- data/lib/sms_validation/log.rb +9 -0
- data/lib/sms_validation/sms.rb +61 -0
- data/lib/sms_validation/version.rb +3 -0
- data/sms_validation.gemspec +24 -0
- data/spec/configuration_spec.rb +114 -0
- data/spec/sms_spec.rb +174 -0
- metadata +141 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d771ba3b06bfaf38dd03b4422c54ca14904d0d0f
|
4
|
+
data.tar.gz: f81fa7011d95d86d6b2ea2a60d91a871b4461cea
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 55ef04ab2258fe6af54ace53155e4fc207617e4092a14995152cc72b8303beae6d6c920443917a7c383dd87991e743b8100ed948362060b2c5c273ae548a342b
|
7
|
+
data.tar.gz: 8fcd241178d77fbcc4af945307ff897a11f33313e4100e3f81137d71c9bc1a9ba59695d472965618edf91a546d0c2b1e6e3aa26e28e8ac0fa8391394560c3786
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Isaac Betesh
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# SmsValidation
|
2
|
+
|
3
|
+
This gem does not send SMS messages. It just makes sure the arguments are valid.
|
4
|
+
|
5
|
+
## What are valid arguments for an SMS message?
|
6
|
+
|
7
|
+
- Phone number: 10 digits, does not begin with 0 or 1
|
8
|
+
- Message: Not longer than 160 characters.
|
9
|
+
|
10
|
+
## What if my message is longer than 160 characters?
|
11
|
+
|
12
|
+
You have 3 choices:
|
13
|
+
- Truncate the message to the first 160 characters
|
14
|
+
- Split it into multiple messages
|
15
|
+
- Raise a SmsValidation::Sms::MessageTooLongError error
|
16
|
+
|
17
|
+
You can configure at any time using:
|
18
|
+
|
19
|
+
SmsValidation.configuration.on_message_too_long = :truncate # or :split or :raise_error
|
20
|
+
|
21
|
+
It defaults to :raise_error
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
Add this line to your application's Gemfile:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
gem 'sms_validation'
|
29
|
+
```
|
30
|
+
|
31
|
+
And then execute:
|
32
|
+
|
33
|
+
$ bundle
|
34
|
+
|
35
|
+
Or install it yourself as:
|
36
|
+
|
37
|
+
$ gem install sms_validation
|
38
|
+
|
39
|
+
## Usage
|
40
|
+
|
41
|
+
### Configuration
|
42
|
+
|
43
|
+
SmsValidation.configure do |config|
|
44
|
+
config.on_message_too_long = :truncate # or :split or :raise_error
|
45
|
+
config.logger = ::Logger.new(STDOUT) # Defaults to ::Rails.logger if ::Rails.logger is defined
|
46
|
+
|
47
|
+
# This DOES NOT change the log_level of the logger--use `config.logger.level = :debug` for that
|
48
|
+
# This DOES determine the log level at which messages should be logged.
|
49
|
+
# This provides a convenient way to toggle whether this gem should log without interfering with the log level of others processes sharing the logger.
|
50
|
+
# For instance, if you're using Rails, you probably don't want to set the log_level to DEBUG, because then ActiveRecord will log every query.
|
51
|
+
# But you may still want SmsValidation to log everything it does.
|
52
|
+
config.log_at :info
|
53
|
+
|
54
|
+
# OR you may want SmsValidation to log only when you're logging all other DEBUG messages.
|
55
|
+
config.log_at :debug
|
56
|
+
end
|
57
|
+
|
58
|
+
### Validation
|
59
|
+
|
60
|
+
sms = SmsValidation::Sms.new(8889999999, "The quick brown fox jumps over the lazy dog")
|
61
|
+
puts sms.phone # => 8889999999
|
62
|
+
puts sms.message # => "The quick brown fox jumps over the lazy dog"
|
63
|
+
|
64
|
+
sms = SmsValidation::Sms.new(889999999, "The quick brown fox jumps over the lazy dog")
|
65
|
+
# => SmsValidation::Sms::InvalidPhoneNumberError: "Phone number must be ten digits"
|
66
|
+
|
67
|
+
SmsValidation.configuration.on_message_too_long = :split
|
68
|
+
sms = SmsValidation::Sms.new(8889999999, "The quick brown fox jumps over the lazy dog" * 4)
|
69
|
+
puts sms.phone # => 8889999999
|
70
|
+
puts sms.messages # => ["(MSG 1/2): The quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown ", "(MSG 2/2): fox jumps over the lazy dog"]
|
71
|
+
|
72
|
+
SmsValidation.configuration.on_message_too_long = :truncate
|
73
|
+
sms = SmsValidation::Sms.new(8889999999, "The quick brown fox jumps over the lazy dog" * 4)
|
74
|
+
puts sms.phone # => 8889999999
|
75
|
+
puts sms.message # => ["The quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over "]
|
76
|
+
|
77
|
+
SmsValidation.configuration.on_message_too_long = :raise_error
|
78
|
+
sms = SmsValidation::Sms.new(8889999999, "The quick brown fox jumps over the lazy dog" * 4)
|
79
|
+
# => SmsValidation::Sms::MessageTooLongError, "Message cannot be longer than 160 characters"
|
80
|
+
|
81
|
+
## Contributing
|
82
|
+
|
83
|
+
1. Fork it ( https://github.com/[my-github-username]/sms_validation/fork )
|
84
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
85
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
86
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
87
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module SmsValidation
|
2
|
+
class << self
|
3
|
+
def configuration
|
4
|
+
@configuration ||= Configuration.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def configure
|
8
|
+
yield configuration
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Configuration
|
13
|
+
ON_MESSAGE_TOO_LONG_OPTIONS = [:truncate, :raise_error, :split]
|
14
|
+
LOG_LEVEL_OPTIONS = [:fatal, :error, :warn, :info, :debug]
|
15
|
+
|
16
|
+
attr_reader :logger, :log_level, :on_message_too_long
|
17
|
+
def initialize
|
18
|
+
@logger = Rails.logger if defined?(::Rails.logger)
|
19
|
+
@log_level = :debug
|
20
|
+
@on_message_too_long = :raise_error
|
21
|
+
end
|
22
|
+
|
23
|
+
def on_message_too_long=(action)
|
24
|
+
raise ArgumentError, "SmsValidation.configuration.on_message_too_long must be included in: #{options_string(ON_MESSAGE_TOO_LONG_OPTIONS)}. It cannot be \"#{action}\"" unless ON_MESSAGE_TOO_LONG_OPTIONS.include?(action)
|
25
|
+
@on_message_too_long = action
|
26
|
+
end
|
27
|
+
|
28
|
+
def log_at(level)
|
29
|
+
validate_logger(@logger, level)
|
30
|
+
@log_level = level
|
31
|
+
end
|
32
|
+
|
33
|
+
def logger=(_logger)
|
34
|
+
validate_logger(_logger, @log_level)
|
35
|
+
@logger = _logger
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def validate_logger(_logger, level)
|
40
|
+
raise ArgumentError, "SmsValidation.configuration.log_at argument must be included in: #{options_string(LOG_LEVEL_OPTIONS)}. It cannot be \"#{level}\"" unless LOG_LEVEL_OPTIONS.include?(level)
|
41
|
+
raise ArgumentError, "SmsValidation.configuration.logger must respond to \"#{level}\"" if _logger && !_logger.respond_to?(level)
|
42
|
+
end
|
43
|
+
|
44
|
+
def options_string(array)
|
45
|
+
"[:#{array.join(", :")}]"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "sms_validation/log"
|
2
|
+
|
3
|
+
module SmsValidation
|
4
|
+
class Sms
|
5
|
+
class InvalidPhoneNumberError < ::ArgumentError; end
|
6
|
+
class InvalidMessageError < ::ArgumentError; end
|
7
|
+
class MessageTooLongError < ::ArgumentError; end
|
8
|
+
|
9
|
+
MAX_LENGTH = 160
|
10
|
+
MAX_SECTION_LENGTH = MAX_LENGTH - "(MSG XXX/XXX): ".size
|
11
|
+
MESSAGE_WHEN_SPLIT_MESSAGE = "This message was split because it is too long to fit into a single SMS. Instead of #message, use #messages or change SmsValidation.configuration.on_message_too_long to something other than :split"
|
12
|
+
|
13
|
+
attr_reader :phone, :messages
|
14
|
+
|
15
|
+
def initialize(phone, message)
|
16
|
+
phone = phone.to_s
|
17
|
+
raise InvalidPhoneNumberError, "Phone number must be ten digits" unless /\A[0-9]{10}\z/.match(phone)
|
18
|
+
raise InvalidPhoneNumberError, "Phone number cannot begin with a \"#{phone[0]}\"" if ['0','1'].include?(phone[0].to_s)
|
19
|
+
raise InvalidMessageError, "Message cannot be blank" if message.empty?
|
20
|
+
SmsValidation.configuration.logger.warn { "WARNING: Some characters may be lost because the message must be broken into at least 1000 sections" } if message.size > (999 * MAX_SECTION_LENGTH)
|
21
|
+
@messages = (message.size > MAX_LENGTH) ? SmsValidation::Sms.__send__(SmsValidation.configuration.on_message_too_long, message) : [message.dup]
|
22
|
+
@phone = "1#{phone}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def message
|
26
|
+
@message ||= begin
|
27
|
+
raise StandardError, MESSAGE_WHEN_SPLIT_MESSAGE unless 1 == messages.size
|
28
|
+
messages.first
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class << self
|
33
|
+
def raise_error(message)
|
34
|
+
raise MessageTooLongError, "Message cannot be longer than #{MAX_LENGTH} characters"
|
35
|
+
end
|
36
|
+
|
37
|
+
def truncate(message)
|
38
|
+
truncated_message = message[0,MAX_LENGTH]
|
39
|
+
SmsValidation.log { "Truncating message due to length. Message was: \"#{message}\" but will now be \"#{truncated_message}\"" }
|
40
|
+
[truncated_message]
|
41
|
+
end
|
42
|
+
|
43
|
+
def section_counter(size)
|
44
|
+
size / MAX_SECTION_LENGTH + ((size % MAX_SECTION_LENGTH).zero? ? 0 : 1)
|
45
|
+
end
|
46
|
+
|
47
|
+
def split(message)
|
48
|
+
sections = section_counter(message.size)
|
49
|
+
SmsValidation.log { "Splitting message into #{sections} messages due to length." }
|
50
|
+
split_message = (sections - 1).times.collect do |i|
|
51
|
+
first_char = i * MAX_SECTION_LENGTH
|
52
|
+
SmsValidation.log { "Section ##{i + 1} of ##{sections} contains characters #{first_char + 1} thru #{first_char + MAX_SECTION_LENGTH} of #{message.size}" }
|
53
|
+
"(MSG #{i+1}/#{sections}): #{message[first_char, MAX_SECTION_LENGTH]}"
|
54
|
+
end
|
55
|
+
first_char = (sections-1)*MAX_SECTION_LENGTH
|
56
|
+
SmsValidation.log { "Section ##{sections} of ##{sections} contains characters #{first_char + 1} thru #{message.size} of #{message.size}" }
|
57
|
+
split_message << "(MSG #{sections}/#{sections}): #{message[first_char..-1]}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sms_validation/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "sms_validation"
|
8
|
+
spec.version = SmsValidation::VERSION
|
9
|
+
spec.authors = ["Isaac Betesh"]
|
10
|
+
spec.email = ["iybetesh@gmail.com"]
|
11
|
+
spec.description = "Validate the phone number and content of an SMS Message. This gem does not send SMS messages. It just makes sure the arguments are valid."
|
12
|
+
spec.summary = `cat README.md`
|
13
|
+
spec.homepage = "https://github.com/betesh/sms_validation/"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require "sms_validation/configuration"
|
2
|
+
require "sms_validation/log"
|
3
|
+
require "logger"
|
4
|
+
|
5
|
+
describe SmsValidation::Configuration do
|
6
|
+
before(:each) do
|
7
|
+
SmsValidation.instance_variable_set("@configuration", nil)
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "logger" do
|
11
|
+
let(:logger) { ::Logger.new('/dev/null') }
|
12
|
+
|
13
|
+
def it_should_not_log
|
14
|
+
text = "Some info"
|
15
|
+
described_class::LOG_LEVEL_OPTIONS.each do |log_level|
|
16
|
+
expect(logger).not_to receive(log_level)
|
17
|
+
end
|
18
|
+
expect{SmsValidation.log { text } }.to_not raise_error
|
19
|
+
end
|
20
|
+
|
21
|
+
def it_should_log_at(log_level)
|
22
|
+
text = "Some info"
|
23
|
+
expect(logger).to receive(log_level) do |&arg|
|
24
|
+
expect(arg.call).to eq(text)
|
25
|
+
end
|
26
|
+
expect{SmsValidation.log { text } }.to_not raise_error
|
27
|
+
end
|
28
|
+
|
29
|
+
def when_the_logger_is_configured
|
30
|
+
SmsValidation.configuration.logger = logger
|
31
|
+
end
|
32
|
+
|
33
|
+
[:fatal, :error, :warn, :info, :debug].each do |log_level|
|
34
|
+
describe "can log at #{log_level}" do
|
35
|
+
let(:log_level) { log_level }
|
36
|
+
it "should allow log level ':#{log_level}'" do
|
37
|
+
SmsValidation.configuration.log_at(log_level)
|
38
|
+
when_the_logger_is_configured
|
39
|
+
it_should_log_at(log_level)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should default to log level debug" do
|
45
|
+
when_the_logger_is_configured
|
46
|
+
it_should_log_at(:debug)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should default to Rails.logger when Rails.logger is defined" do
|
50
|
+
stub_const("Rails", double)
|
51
|
+
allow(Rails).to receive(:logger).and_return(logger)
|
52
|
+
it_should_log_at(:debug)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should not attempt to default to Rails.logger when Rails is defined but Rails.logger is defined" do
|
56
|
+
stub_const("Rails", double)
|
57
|
+
it_should_not_log
|
58
|
+
end
|
59
|
+
|
60
|
+
it "can be nil" do
|
61
|
+
SmsValidation.configuration.logger = nil
|
62
|
+
it_should_not_log
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should not allow log level news and should remain in a valid state" do
|
66
|
+
expect{SmsValidation.configuration.log_at(:news)}.to raise_error(ArgumentError, "SmsValidation.configuration.log_at argument must be included in: [:fatal, :error, :warn, :info, :debug]. It cannot be \"news\"")
|
67
|
+
SmsValidation.configuration.logger = logger
|
68
|
+
it_should_log_at(:debug)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should not allow log level that the logger does not respond_to when the logger is created before log level is set and should remain in a valid state" do
|
72
|
+
SmsValidation.configuration.logger = logger
|
73
|
+
allow(logger).to receive(:respond_to?).with(:warn).and_return(false)
|
74
|
+
expect{SmsValidation.configuration.log_at(:warn)}.to raise_error(ArgumentError, "SmsValidation.configuration.logger must respond to \"warn\"")
|
75
|
+
it_should_log_at(:debug)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should not allow log level that the logger does not respond_to when the logger is created after log level is set and should remain in a valid state" do
|
79
|
+
allow(logger).to receive(:respond_to?).with(:warn).and_return(false)
|
80
|
+
SmsValidation.configuration.log_at(:warn)
|
81
|
+
expect{SmsValidation.configuration.logger = logger}.to raise_error(ArgumentError, "SmsValidation.configuration.logger must respond to \"warn\"")
|
82
|
+
it_should_not_log
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "on_message_too_long" do
|
87
|
+
it "should default to :raise_error" do
|
88
|
+
expect(SmsValidation.configuration.on_message_too_long).to eq(:raise_error)
|
89
|
+
end
|
90
|
+
|
91
|
+
[:raise_error, :split, :truncate].each do |value|
|
92
|
+
describe value.to_s do
|
93
|
+
let(:value) { value }
|
94
|
+
it "should be an allowed value" do
|
95
|
+
expect{SmsValidation.configuration.on_message_too_long = value}.to_not raise_error
|
96
|
+
expect(SmsValidation.configuration.on_message_too_long).to eq(value)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should not allow other values and should remain in a valid state" do
|
100
|
+
SmsValidation.configuration.on_message_too_long = value
|
101
|
+
expect{SmsValidation.configuration.on_message_too_long = :do_nothing}.to raise_error(ArgumentError, "SmsValidation.configuration.on_message_too_long must be included in: [:truncate, :raise_error, :split]. It cannot be \"do_nothing\"")
|
102
|
+
expect(SmsValidation.configuration.on_message_too_long).to eq(value)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it "can yield" do
|
109
|
+
SmsValidation.configure do |config|
|
110
|
+
config.on_message_too_long = :split
|
111
|
+
end
|
112
|
+
expect(SmsValidation.configuration.on_message_too_long).to eq(:split)
|
113
|
+
end
|
114
|
+
end
|
data/spec/sms_spec.rb
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
require "sms_validation/sms"
|
2
|
+
require "sms_validation/log"
|
3
|
+
require "logger"
|
4
|
+
|
5
|
+
describe SmsValidation::Sms do
|
6
|
+
let(:phone_number_length) { 10 }
|
7
|
+
let(:phone_number) { "8" * phone_number_length }
|
8
|
+
let(:message) { "TEXT MESSAGE FROM ME TO YOU" }
|
9
|
+
let(:on_message_too_long) { :raise_error }
|
10
|
+
|
11
|
+
before(:each) do
|
12
|
+
SmsValidation.instance_variable_set("@configuration", nil)
|
13
|
+
SmsValidation.configure do |config|
|
14
|
+
config.log_at(:info)
|
15
|
+
config.logger = logger
|
16
|
+
config.on_message_too_long = on_message_too_long
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def it_should_not_log
|
21
|
+
described_class::LOG_LEVEL_OPTIONS.each do |log_level|
|
22
|
+
expect(logger).not_to receive(log_level)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def it_should_log(text, options={})
|
27
|
+
expect(logger).to receive(options[:at] || :info) do |&arg|
|
28
|
+
expect(arg.call).to eq(text)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
subject { described_class.new(phone_number, message) }
|
33
|
+
|
34
|
+
shared_examples_for :all_specs do
|
35
|
+
describe "phone number" do
|
36
|
+
describe "when 9 digits" do
|
37
|
+
let(:phone_number_length) { 9 }
|
38
|
+
|
39
|
+
it "should raise an error" do
|
40
|
+
expect{subject}.to raise_error(described_class::InvalidPhoneNumberError, "Phone number must be ten digits")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "when 11 digits" do
|
45
|
+
let(:phone_number_length) { 11 }
|
46
|
+
|
47
|
+
it "should raise an error" do
|
48
|
+
expect{subject}.to raise_error(described_class::InvalidPhoneNumberError, "Phone number must be ten digits")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "when it starts with a 0" do
|
53
|
+
let(:phone_number) { "0" + "8" * (phone_number_length - 1) }
|
54
|
+
|
55
|
+
it "should raise an error" do
|
56
|
+
expect{subject}.to raise_error(described_class::InvalidPhoneNumberError, "Phone number cannot begin with a \"0\"")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "when it starts with a 1" do
|
61
|
+
let(:phone_number) { "1" + "8" * (phone_number_length - 1) }
|
62
|
+
|
63
|
+
it "should raise an error" do
|
64
|
+
expect{subject}.to raise_error(described_class::InvalidPhoneNumberError, "Phone number cannot begin with a \"1\"")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should prepend a '1' and be safe from changes" do
|
69
|
+
expected_phone_number = "1#{phone_number}"
|
70
|
+
subject
|
71
|
+
phone_number[1..3] = ''
|
72
|
+
expect(subject.phone).to eq(expected_phone_number)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "message" do
|
77
|
+
describe "when blank" do
|
78
|
+
let(:message) { "" }
|
79
|
+
|
80
|
+
it "raises an error" do
|
81
|
+
expect{subject}.to raise_error(described_class::InvalidMessageError, "Message cannot be blank")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "when longer than 160 characters" do
|
86
|
+
describe "when on_message_too_long = :truncate" do
|
87
|
+
let(:on_message_too_long) { :truncate }
|
88
|
+
let(:message) { "A"+"ABCDEFGHIJ"*16 }
|
89
|
+
|
90
|
+
it "is truncated to the first 160 characters" do
|
91
|
+
expect(subject.message).to eq(message[0,160])
|
92
|
+
expect(subject.messages).to eq([message[0,160]])
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should be safe from changing" do
|
96
|
+
expected_message = "#{message[0,160]}"
|
97
|
+
subject
|
98
|
+
message[1..3] = ''
|
99
|
+
expect(subject.message).to eq(expected_message)
|
100
|
+
expect(subject.messages).to eq([expected_message])
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "when on_message_too_long = :raise_error" do
|
105
|
+
let(:on_message_too_long) { :raise_error }
|
106
|
+
let(:message) { "A"*161 }
|
107
|
+
|
108
|
+
it "raises an error" do
|
109
|
+
expect{subject}.to raise_error(described_class::MessageTooLongError, "Message cannot be longer than 160 characters")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "when on_message_too_long = :split" do
|
114
|
+
let(:on_message_too_long) { :split }
|
115
|
+
|
116
|
+
describe "when it's an even split" do
|
117
|
+
let(:message) { "ABCDEFGHIJ"*58 }
|
118
|
+
|
119
|
+
it "should be split into multiple messages" do
|
120
|
+
expect(subject.messages).to eq(["(MSG 1/4): #{message[0,145]}", "(MSG 2/4): #{message[145,145]}", "(MSG 3/4): #{message[290,145]}", "(MSG 4/4): #{message[435,145]}"])
|
121
|
+
expect{subject.message}.to raise_error(StandardError, "This message was split because it is too long to fit into a single SMS. Instead of #message, use #messages or change SmsValidation.configuration.on_message_too_long to something other than :split")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "when it's not an even split" do
|
126
|
+
let(:message) { "ABCDEFGHIJ"*32 }
|
127
|
+
|
128
|
+
it "should be split into multiple messages" do
|
129
|
+
expect(subject.messages).to eq(["(MSG 1/3): #{message[0,145]}", "(MSG 2/3): #{message[145,145]}", "(MSG 3/3): #{message[290..-1]}"])
|
130
|
+
expect{subject.message}.to raise_error(StandardError, "This message was split because it is too long to fit into a single SMS. Instead of #message, use #messages or change SmsValidation.configuration.on_message_too_long to something other than :split")
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should be safe from changing" do
|
134
|
+
expected_messages = ["(MSG 1/3): #{message[0,145]}", "(MSG 2/3): #{message[145,145]}", "(MSG 3/3): #{message[290..-1]}"]
|
135
|
+
subject
|
136
|
+
message[1..3] = ''
|
137
|
+
expect(subject.messages).to eq(expected_messages)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
[:raise_error, :split, :truncate].each do |value|
|
144
|
+
describe "when on_message_too_long = :#{value}" do
|
145
|
+
let(:on_message_too_long) { value }
|
146
|
+
|
147
|
+
it "should be safe from changing the message" do
|
148
|
+
expected_message = "#{message}"
|
149
|
+
subject
|
150
|
+
message[1..3] = ''
|
151
|
+
expect(subject.message).to eq(expected_message)
|
152
|
+
end
|
153
|
+
|
154
|
+
describe "when the initial message is 160 characters" do
|
155
|
+
let(:message) { "A"*160 }
|
156
|
+
|
157
|
+
it "does not change" do
|
158
|
+
expect(subject.message).to eq(message)
|
159
|
+
expect(subject.messages).to eq([message])
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
it_behaves_like :all_specs do
|
168
|
+
let(:logger) { ::Logger.new('/dev/null') }
|
169
|
+
end
|
170
|
+
|
171
|
+
it_behaves_like :all_specs do
|
172
|
+
let(:logger) { nil }
|
173
|
+
end
|
174
|
+
end
|
metadata
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sms_validation
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Isaac Betesh
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Validate the phone number and content of an SMS Message. This gem does
|
56
|
+
not send SMS messages. It just makes sure the arguments are valid.
|
57
|
+
email:
|
58
|
+
- iybetesh@gmail.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
64
|
+
- ".rspec"
|
65
|
+
- Gemfile
|
66
|
+
- LICENSE.txt
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- lib/sms_validation.rb
|
70
|
+
- lib/sms_validation/configuration.rb
|
71
|
+
- lib/sms_validation/log.rb
|
72
|
+
- lib/sms_validation/sms.rb
|
73
|
+
- lib/sms_validation/version.rb
|
74
|
+
- sms_validation.gemspec
|
75
|
+
- spec/configuration_spec.rb
|
76
|
+
- spec/sms_spec.rb
|
77
|
+
homepage: https://github.com/betesh/sms_validation/
|
78
|
+
licenses:
|
79
|
+
- MIT
|
80
|
+
metadata: {}
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
requirements: []
|
96
|
+
rubyforge_project:
|
97
|
+
rubygems_version: 2.4.3
|
98
|
+
signing_key:
|
99
|
+
specification_version: 4
|
100
|
+
summary: '# SmsValidation This gem does not send SMS messages. It just makes sure
|
101
|
+
the arguments are valid. ## What are valid arguments for an SMS message? - Phone
|
102
|
+
number: 10 digits, does not begin with 0 or 1 - Message: Not longer than 160 characters. ##
|
103
|
+
What if my message is longer than 160 characters? You have 3 choices: - Truncate
|
104
|
+
the message to the first 160 characters - Split it into multiple messages - Raise
|
105
|
+
a SmsValidation::Sms::MessageTooLongError error You can configure at any time using: SmsValidation.configuration.on_message_too_long
|
106
|
+
= :truncate # or :split or :raise_error It defaults to :raise_error ## Installation Add
|
107
|
+
this line to your application''s Gemfile: ```ruby gem ''sms_validation'' ``` And
|
108
|
+
then execute: $ bundle Or install it yourself as: $ gem install sms_validation ##
|
109
|
+
Usage ### Configuration SmsValidation.configure do |config| config.on_message_too_long
|
110
|
+
= :truncate # or :split or :raise_error config.logger = ::Logger.new(STDOUT) # Defaults
|
111
|
+
to ::Rails.logger if ::Rails.logger is defined # This DOES NOT change the log_level
|
112
|
+
of the logger--use `config.logger.level = :debug` for that # This DOES determine
|
113
|
+
the log level at which messages should be logged. # This provides a convenient way
|
114
|
+
to toggle whether this gem should log without interfering with the log level of
|
115
|
+
others processes sharing the logger. # For instance, if you''re using Rails, you
|
116
|
+
probably don''t want to set the log_level to DEBUG, because then ActiveRecord will
|
117
|
+
log every query. # But you may still want SmsValidation to log everything it does.
|
118
|
+
config.log_at :info # OR you may want SmsValidation to log only when you''re logging
|
119
|
+
all other DEBUG messages. config.log_at :debug end ### Validation sms = SmsValidation::Sms.new(8889999999,
|
120
|
+
"The quick brown fox jumps over the lazy dog") puts sms.phone # => 8889999999 puts
|
121
|
+
sms.message # => "The quick brown fox jumps over the lazy dog" sms = SmsValidation::Sms.new(889999999,
|
122
|
+
"The quick brown fox jumps over the lazy dog") # => SmsValidation::Sms::InvalidPhoneNumberError:
|
123
|
+
"Phone number must be ten digits" SmsValidation.configuration.on_message_too_long
|
124
|
+
= :split sms = SmsValidation::Sms.new(8889999999, "The quick brown fox jumps over
|
125
|
+
the lazy dog" * 4) puts sms.phone # => 8889999999 puts sms.messages # => ["(MSG
|
126
|
+
1/2): The quick brown fox jumps over the lazy dogThe quick brown fox jumps over
|
127
|
+
the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown ", "(MSG
|
128
|
+
2/2): fox jumps over the lazy dog"] SmsValidation.configuration.on_message_too_long
|
129
|
+
= :truncate sms = SmsValidation::Sms.new(8889999999, "The quick brown fox jumps
|
130
|
+
over the lazy dog" * 4) puts sms.phone # => 8889999999 puts sms.message # => ["The
|
131
|
+
quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe
|
132
|
+
quick brown fox jumps over the lazy dogThe quick brown fox jumps over "] SmsValidation.configuration.on_message_too_long
|
133
|
+
= :raise_error sms = SmsValidation::Sms.new(8889999999, "The quick brown fox jumps
|
134
|
+
over the lazy dog" * 4) # => SmsValidation::Sms::MessageTooLongError, "Message cannot
|
135
|
+
be longer than 160 characters" ## Contributing 1. Fork it ( https://github.com/[my-github-username]/sms_validation/fork
|
136
|
+
) 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit your
|
137
|
+
changes (`git commit -am ''Add some feature''`) 4. Push to the branch (`git push
|
138
|
+
origin my-new-feature`) 5. Create a new Pull Request'
|
139
|
+
test_files:
|
140
|
+
- spec/configuration_spec.rb
|
141
|
+
- spec/sms_spec.rb
|