sms_validation 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|