sms-unit-test 1.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 +5 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/Guardfile +5 -0
- data/LICENSE +22 -0
- data/README.md +90 -0
- data/Rakefile +7 -0
- data/lib/generators/sms_spec/steps/USAGE +6 -0
- data/lib/generators/sms_spec/steps/steps_generator.rb +14 -0
- data/lib/generators/sms_spec/steps/templates/sms_steps.rb +40 -0
- data/lib/sms-unit-test.rb +1 -0
- data/lib/sms_unit_test.rb +15 -0
- data/lib/sms_unit_test/cucumber.rb +6 -0
- data/lib/sms_unit_test/data.rb +38 -0
- data/lib/sms_unit_test/drivers/clickatell.rb +20 -0
- data/lib/sms_unit_test/drivers/twilio-ruby.rb +89 -0
- data/lib/sms_unit_test/helpers.rb +49 -0
- data/lib/sms_unit_test/matchers.rb +41 -0
- data/lib/sms_unit_test/message.rb +13 -0
- data/lib/sms_unit_test/mobile_device.rb +12 -0
- data/lib/sms_unit_test/version.rb +3 -0
- data/rails_generators/sms_unit_test/templates/sms_steps.rb +49 -0
- data/rails_generators/sms_unit_test_generator.rb +12 -0
- data/sms-unit-test.gemspec +26 -0
- data/spec/drivers/clickatell_spec.rb +31 -0
- data/spec/drivers/twilio_spec.rb +100 -0
- data/spec/helpers_spec.rb +153 -0
- data/spec/matchers_spec.rb +88 -0
- data/spec/spec_helper.rb +4 -0
- metadata +149 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6ab8546f2e10a07343012bf3793c5b9ee3d38f54
|
4
|
+
data.tar.gz: 52e5937e427649c65831d837d1c8782def64489d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8e9d16c94cb3d47044efbef8a848173820ed5a615708db085e69802cddc9c6e7b9eb17536169eeb674f5267a4984c34f61bb216c315391317816e0955499411a
|
7
|
+
data.tar.gz: 75ec3cab06219c27f613d83c66c5e1b48d0cb102e954858538943a6654ac9965f0b6875f24efe6b858ee9f7e525201d1a4374056fbde576cf838645c342fae6c
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
sms-unit-test
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.4.1
|
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2017-present Kevin Ross
|
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,90 @@
|
|
1
|
+
# sms-unit-test
|
2
|
+
|
3
|
+
[](https://travis-ci.org/rosskevin/sms-unit-test)
|
4
|
+
[](https://codeclimate.com/github/rosskevin/sms-unit-test)
|
5
|
+
|
6
|
+
This is a hard **_maintained_** fork of the sporadically maintained `sms-spec`. Unlike that gem, I hope to provide it a home with maintenance releases as necessary.
|
7
|
+
|
8
|
+
**PRs are welcome**, as are additional maintainers.
|
9
|
+
|
10
|
+
An RSpec DSL and Cucumber steps to test SMS interactions with your Ruby on Rails application.
|
11
|
+
|
12
|
+
Currently this gem only supports testing SMS messaging using the
|
13
|
+
[twilio-ruby](https://github.com/twilio/twilio-ruby) and
|
14
|
+
[lookout-clickatell](https://github.com/lookout/clickatell) gem.
|
15
|
+
|
16
|
+
## Setup
|
17
|
+
Add the sms-unit-test gem to `Gemfile`:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
group :test do
|
21
|
+
gem "sms-unit-test"
|
22
|
+
end
|
23
|
+
```
|
24
|
+
|
25
|
+
## RSpec
|
26
|
+
Configure a driver and include helper and matcher methods in the `spec_helper.rb`:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
require "sms_unit_test"
|
30
|
+
|
31
|
+
Spec::Runner.configure do |config|
|
32
|
+
config.include(SmsUnitTest::Helpers)
|
33
|
+
config.include(SmsUnitTest::Matchers)
|
34
|
+
end
|
35
|
+
|
36
|
+
SmsUnitTest.driver = :"twilio-ruby" #this can be any available sms-unit-test driver
|
37
|
+
```
|
38
|
+
|
39
|
+
### Usage
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
describe "alarm notifications" do
|
43
|
+
subject(:job) { AlarmNotificationJob.new }
|
44
|
+
|
45
|
+
context "via sms" do
|
46
|
+
let!(:subscription) { FactoryGirl.create :alarm_subscription_sms }
|
47
|
+
|
48
|
+
it "delivers an alarm notification" do
|
49
|
+
job.perform
|
50
|
+
|
51
|
+
open_last_text_message_for(subscription.recipient)
|
52
|
+
expect(current_text_message.body).to eq("Yo")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
## Cucumber
|
59
|
+
Add the following to `env.rb`:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
require "sms_unit_test"
|
63
|
+
require "sms_unit_test/cucumber"
|
64
|
+
```
|
65
|
+
|
66
|
+
This loads the `sms_unit_test` RSpec helpers into your cucumber wold. Then,
|
67
|
+
run the following to generate the `text_messsage_steps.rb` file:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
rails generate sms_unit_test:steps
|
71
|
+
```
|
72
|
+
|
73
|
+
### Usage
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
Feature: Registering via SMS
|
77
|
+
|
78
|
+
In order to use our application
|
79
|
+
As a user
|
80
|
+
I want to be able to register with any mobile phone
|
81
|
+
|
82
|
+
Scenario: A user submits their phone number for registration
|
83
|
+
Given I am on the homepage
|
84
|
+
And I fill in "What is your phone number?" with "6165552345"
|
85
|
+
When I press "Register"
|
86
|
+
|
87
|
+
Then I should see "Thank You"
|
88
|
+
And "6165552345" opens the text message
|
89
|
+
And I should see "Thank you for registering. To confirm your subscript reply YES." in the text message body
|
90
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module SmsUnitTest
|
4
|
+
class StepsGenerator < Rails::Generators::Base
|
5
|
+
def generate
|
6
|
+
copy_file 'sms_steps.rb', 'features/step_definitions/sms_steps.rb'
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.source_root
|
10
|
+
File.join(File.dirname(__FILE__), 'templates')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# -------------------------------------------
|
2
|
+
# Available methods
|
3
|
+
# -------------------------------------------
|
4
|
+
|
5
|
+
# messages
|
6
|
+
# add_message
|
7
|
+
# set_current_number
|
8
|
+
# current_number
|
9
|
+
# clear_messages
|
10
|
+
# current_text_message
|
11
|
+
# open_last_text_message_for
|
12
|
+
|
13
|
+
|
14
|
+
Given /^no text messages have been sent$/ do
|
15
|
+
clear_messages
|
16
|
+
end
|
17
|
+
|
18
|
+
Given /^all text messages have been read$/ do
|
19
|
+
clear_messages
|
20
|
+
end
|
21
|
+
|
22
|
+
Then /^"([^"]*)" should receive a text message$/ do |phone_number|
|
23
|
+
expect(messages_for(phone_number)).to_not be_empty
|
24
|
+
end
|
25
|
+
|
26
|
+
Then /^"([^"]*)" should receive no text messages$/ do |phone_number|
|
27
|
+
expect(messages_for(phone_number)).to be_empty
|
28
|
+
end
|
29
|
+
|
30
|
+
When /^"([^"]*?)" opens? the text message$/ do |mobile_number|
|
31
|
+
open_last_text_message_for(mobile_number)
|
32
|
+
end
|
33
|
+
|
34
|
+
Then /^I should see "([^"]*)" in the text message body$/ do |content|
|
35
|
+
expect(current_text_message).to have_body(content)
|
36
|
+
end
|
37
|
+
|
38
|
+
Then /^I should see the following in the text message body:$/ do |content|
|
39
|
+
expect(current_text_message).to have_body(content)
|
40
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'sms_unit_test'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rspec/core'
|
2
|
+
require 'rspec/expectations'
|
3
|
+
require 'rspec/mocks'
|
4
|
+
require 'sms_unit_test/version'
|
5
|
+
require 'sms_unit_test/helpers'
|
6
|
+
require 'sms_unit_test/data'
|
7
|
+
require 'sms_unit_test/message'
|
8
|
+
require 'sms_unit_test/mobile_device'
|
9
|
+
require 'sms_unit_test/matchers'
|
10
|
+
|
11
|
+
module SmsUnitTest
|
12
|
+
def self.driver=(driver_sym)
|
13
|
+
require "sms_unit_test/drivers/#{driver_sym.to_s}"
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module SmsUnitTest
|
2
|
+
class Data
|
3
|
+
def self.add_message message
|
4
|
+
@@messages ||= []
|
5
|
+
@@messages << message
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.clear_messages
|
9
|
+
@@messages = []
|
10
|
+
@@current_text_message = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.messages
|
14
|
+
@@messages ||= []
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.set_current_number(number)
|
18
|
+
@@current_number = number
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.current_number
|
22
|
+
@@current_number
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.current_text_message
|
26
|
+
@@current_text_message ||= nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.open_last_text_message_for(phone_number)
|
30
|
+
message = messages_for(phone_number).first
|
31
|
+
@@current_text_message = messages.delete(message)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.messages_for(phone_number)
|
35
|
+
messages.select { |m| m.number == phone_number }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Clickatell
|
2
|
+
class API
|
3
|
+
include SmsUnitTest::Helpers
|
4
|
+
|
5
|
+
def self.authenticate(api_key, login, password)
|
6
|
+
new(api_key, login, password)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(api_key, login, password)
|
10
|
+
@api_key = api_key
|
11
|
+
@login = login
|
12
|
+
@password = password
|
13
|
+
end
|
14
|
+
|
15
|
+
def send_message(dest, body, opts={})
|
16
|
+
from = opts[:from]
|
17
|
+
add_message SmsUnitTest::Message.new(:number => dest, :from => from, :body => body)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
begin
|
2
|
+
require 'twilio-ruby'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'WARNING: Twilio is not loaded properly. Ensure to add "twilio-ruby" to your Gemfile before using this driver'
|
5
|
+
end
|
6
|
+
|
7
|
+
module Twilio
|
8
|
+
extend SingleForwardable
|
9
|
+
|
10
|
+
def_delegators :configuration, :account_sid, :auth_token
|
11
|
+
|
12
|
+
##
|
13
|
+
# Pre-configure with account SID and auth token so that you don't need to
|
14
|
+
# pass them to various initializers each time.
|
15
|
+
def self.configure(&block)
|
16
|
+
yield configuration
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Returns an existing or instantiates a new configuration object.
|
21
|
+
def self.configuration
|
22
|
+
@configuration ||= Util::Configuration.new
|
23
|
+
end
|
24
|
+
private_class_method :configuration
|
25
|
+
|
26
|
+
module REST
|
27
|
+
class Client
|
28
|
+
|
29
|
+
def initialize(*args)
|
30
|
+
# mimic the primary class's #initialize.
|
31
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
32
|
+
@config = options #DEFAULTS.merge! options
|
33
|
+
|
34
|
+
@account_sid = args[0] || Twilio.account_sid
|
35
|
+
@auth_token = args[1] || Twilio.auth_token
|
36
|
+
if @account_sid.nil? || @auth_token.nil?
|
37
|
+
raise ArgumentError, 'Account SID and auth token are required'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Messages
|
42
|
+
include SmsUnitTest::Helpers
|
43
|
+
|
44
|
+
def create(opts={})
|
45
|
+
to = opts[:to]
|
46
|
+
body = opts[:body]
|
47
|
+
from = opts[:from]
|
48
|
+
add_message SmsUnitTest::Message.new(:number => to, :from => from, :body => body)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class Account
|
53
|
+
def sms
|
54
|
+
Sms.new
|
55
|
+
end
|
56
|
+
|
57
|
+
def messages
|
58
|
+
Messages.new
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def account
|
63
|
+
account = Account.new
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
## Mirror method_missing approach
|
68
|
+
##
|
69
|
+
# Delegate account methods from the client. This saves having to call
|
70
|
+
# <tt>client.account</tt> every time for resources on the default
|
71
|
+
# account.
|
72
|
+
def method_missing(method_name, *args, &block)
|
73
|
+
if account.respond_to?(method_name)
|
74
|
+
account.send(method_name, *args, &block)
|
75
|
+
else
|
76
|
+
super
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def respond_to?(method_name, include_private=false)
|
81
|
+
if account.respond_to?(method_name, include_private)
|
82
|
+
true
|
83
|
+
else
|
84
|
+
super
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module SmsUnitTest
|
4
|
+
module Helpers
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def_delegators :"SmsUnitTest::Data",
|
8
|
+
:messages,
|
9
|
+
:add_message,
|
10
|
+
:set_current_number,
|
11
|
+
:current_number,
|
12
|
+
:clear_messages,
|
13
|
+
:current_text_message,
|
14
|
+
:messages_for,
|
15
|
+
:open_last_text_message_for
|
16
|
+
|
17
|
+
def twiml_message(from, body, opts={})
|
18
|
+
base_options = {
|
19
|
+
"AccountSid"=>"1234567812345678",
|
20
|
+
"Body"=> body,
|
21
|
+
"ToZip"=>"94949",
|
22
|
+
"FromState"=>"MI",
|
23
|
+
"ToCity"=>"NOVATO",
|
24
|
+
"SmsSid"=>"1234567812345678",
|
25
|
+
"ToState"=>"CA",
|
26
|
+
"To"=>"8155552671",
|
27
|
+
"ToCountry"=>"US",
|
28
|
+
"FromCountry"=>"US",
|
29
|
+
"SmsMessageSid"=>"123456712345671234567",
|
30
|
+
"ApiVersion"=>"2008-08-01",
|
31
|
+
"FromCity"=>"GRAND RAPIDS",
|
32
|
+
"SmsStatus"=>"received",
|
33
|
+
"From"=> from,
|
34
|
+
"FromZip"=>"49507"
|
35
|
+
}
|
36
|
+
|
37
|
+
base_options.merge! opts
|
38
|
+
end
|
39
|
+
|
40
|
+
def clkatel_message(from, text, opts={})
|
41
|
+
base_options = {
|
42
|
+
"From"=> from,
|
43
|
+
"Text" => text
|
44
|
+
}
|
45
|
+
|
46
|
+
base_options.merge! opts
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module SmsUnitTest
|
2
|
+
module Matchers
|
3
|
+
|
4
|
+
RSpec::Matchers.define :have_text_messages do
|
5
|
+
match do |mobile_device|
|
6
|
+
mobile_device.messages.count > 0
|
7
|
+
end
|
8
|
+
|
9
|
+
if Gem::Version.new(RSpec::Core::Version::STRING) >= Gem::Version.new("3.0.0.beta2")
|
10
|
+
failure_message do |mobile_device|
|
11
|
+
"expected the mobile device '#{mobile_device.number}' to have text messages but it did not"
|
12
|
+
end
|
13
|
+
|
14
|
+
failure_message_when_negated do |mobile_device|
|
15
|
+
"expected the mobile device '#{mobile_device.number}' to have no text messages but it did"
|
16
|
+
end
|
17
|
+
else
|
18
|
+
failure_message_for_should do |mobile_device|
|
19
|
+
"expected the mobile device '#{mobile_device.number}' to have text messages but it did not"
|
20
|
+
end
|
21
|
+
|
22
|
+
failure_message_for_should_not do |mobile_device|
|
23
|
+
"expected the mobile device '#{mobile_device.number}' to have no text messages but it did"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
RSpec::Matchers.define :have_body do |expected_body|
|
29
|
+
match do |message|
|
30
|
+
message.body == expected_body
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
RSpec::Matchers.define :have_body_like do |expected_body|
|
35
|
+
match do |message|
|
36
|
+
message.body.match(expected_body)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# -------------------------------------------
|
2
|
+
# Available methods
|
3
|
+
# -------------------------------------------
|
4
|
+
|
5
|
+
# messages
|
6
|
+
# add_message
|
7
|
+
# set_current_number
|
8
|
+
# current_number
|
9
|
+
# clear_messages
|
10
|
+
# current_text_message
|
11
|
+
# open_last_text_message_for
|
12
|
+
|
13
|
+
|
14
|
+
Given /^no text messages have been sent$/ do
|
15
|
+
clear_messages
|
16
|
+
end
|
17
|
+
|
18
|
+
Given /^all text messages have been read$/ do
|
19
|
+
clear_messages
|
20
|
+
end
|
21
|
+
|
22
|
+
Then /^"([^"]*)" should receive a text message$/ do |phone_number|
|
23
|
+
messages_for(phone_number).should_not be_empty
|
24
|
+
end
|
25
|
+
|
26
|
+
Then /^"([^"]*)" should receive no text messages$/ do |phone_number|
|
27
|
+
messages_for(phone_number).should be_empty
|
28
|
+
end
|
29
|
+
|
30
|
+
When /^"([^"]*?)" opens? the text message$/ do |mobile_number|
|
31
|
+
open_last_text_message_for(mobile_number)
|
32
|
+
end
|
33
|
+
|
34
|
+
Then /^I should see "([^"]*)" in the text message body$/ do |content|
|
35
|
+
current_text_message.should have_body(content)
|
36
|
+
end
|
37
|
+
|
38
|
+
Then /^I should see the following in the text message body:$/ do |content|
|
39
|
+
current_text_message.should have_body(content)
|
40
|
+
end
|
41
|
+
|
42
|
+
Then /^I should see "([^"]*)" somewhere in the text message body$/ do |content|
|
43
|
+
current_text_message.should have_body_like(content)
|
44
|
+
end
|
45
|
+
|
46
|
+
Then /^I should see the following somewhere in the text message body:$/ do |content|
|
47
|
+
current_text_message.should have_body_like(content)
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
3
|
+
require 'sms_unit_test/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'sms-unit-test'
|
7
|
+
s.version = SmsUnitTest::VERSION
|
8
|
+
s.authors = ['Kevin Ross']
|
9
|
+
s.email = ['kevin.ross@alienfast.com']
|
10
|
+
s.homepage = 'https://github.com/rosskevin/sms-unit-test'
|
11
|
+
s.summary = %q{Test SMS interactions with RSpec and Cucumber}
|
12
|
+
s.description = %q{SMS Spec gives you an RSpec DSL and Cucumber steps to test SMS interactions.}
|
13
|
+
|
14
|
+
s.rubyforge_project = 'sms-unit-test'
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ['lib']
|
20
|
+
|
21
|
+
s.add_dependency 'rspec', '~> 3.1'
|
22
|
+
s.add_development_dependency 'rake'
|
23
|
+
s.add_development_dependency 'twilio-ruby', '~> 4.2'
|
24
|
+
s.add_development_dependency 'lookout-clickatell', '~> 0.8'
|
25
|
+
s.add_development_dependency 'pry'
|
26
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SmsUnitTest do
|
4
|
+
include SmsUnitTest::Helpers
|
5
|
+
|
6
|
+
before do
|
7
|
+
SmsUnitTest.driver = :"clickatell"
|
8
|
+
@to_number = '27999900001' # TEST NUMBER
|
9
|
+
@from_number = '27999900005' # TEST NUMBER
|
10
|
+
@api = Clickatell::API.authenticate(
|
11
|
+
ENV["CLICKATELL_API_KEY"],
|
12
|
+
ENV["CLICKATELL_LOGIN"],
|
13
|
+
ENV["CLICKATELL_PASSWORD"]
|
14
|
+
)
|
15
|
+
|
16
|
+
SmsUnitTest::Data.clear_messages
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "the clickatell driver" do
|
20
|
+
it "captures the outgoing message for testing" do
|
21
|
+
@api.send_message(@to_number, 'Hello from clickatell')
|
22
|
+
open_last_text_message_for(@to_number)
|
23
|
+
|
24
|
+
expect(current_text_message).to have_body("Hello from clickatell")
|
25
|
+
expect(current_text_message.number).to eql(@to_number)
|
26
|
+
expect(current_text_message.from).to be_nil
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'twilio-ruby' do
|
4
|
+
include SmsUnitTest::Helpers
|
5
|
+
SmsUnitTest.driver = :'twilio-ruby'
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
SmsUnitTest::Data.clear_messages
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'instantiation options' do
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
@account_sid = 'ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
15
|
+
@auth_token = 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'
|
16
|
+
@client = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'with two args' do
|
20
|
+
@client = Twilio::REST::Client.new @account_sid, @auth_token
|
21
|
+
expect(@client).to_not be_nil
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'with config' do
|
25
|
+
Twilio.configure do |config|
|
26
|
+
config.account_sid = @account_sid
|
27
|
+
config.auth_token = @auth_token
|
28
|
+
end
|
29
|
+
@client = Twilio::REST::Client.new
|
30
|
+
expect(@client).to_not be_nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
context 'using method_missing approach' do
|
36
|
+
|
37
|
+
before do
|
38
|
+
@account_sid = 'ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
39
|
+
@auth_token = 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'
|
40
|
+
Twilio.configure do |config|
|
41
|
+
config.account_sid = @account_sid
|
42
|
+
config.auth_token = @auth_token
|
43
|
+
end
|
44
|
+
@client = Twilio::REST::Client.new
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'intercepts calls to twilio sms client' do
|
48
|
+
@client.messages.create(
|
49
|
+
:from => '+14159341234',
|
50
|
+
:to => '+16105557069',
|
51
|
+
:body => 'Hey there!'
|
52
|
+
)
|
53
|
+
|
54
|
+
open_last_text_message_for('+16105557069')
|
55
|
+
expect(current_text_message).to_not be_nil
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'records the from number for a message' do
|
59
|
+
@client.messages.create(
|
60
|
+
:from => '+14159341234',
|
61
|
+
:to => '+16105557069',
|
62
|
+
:body => 'Hey there!'
|
63
|
+
)
|
64
|
+
|
65
|
+
open_last_text_message_for('+16105557069')
|
66
|
+
expect(current_text_message.from).to eq('+14159341234')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'using .account.* methods' do
|
71
|
+
|
72
|
+
before do
|
73
|
+
@account_sid = 'ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
74
|
+
@auth_token = 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'
|
75
|
+
@client = Twilio::REST::Client.new @account_sid, @auth_token
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'intercepts calls to twilio sms client' do
|
79
|
+
@client.account.messages.create(
|
80
|
+
:from => '+14159341234',
|
81
|
+
:to => '+16105557069',
|
82
|
+
:body => 'Hey there!'
|
83
|
+
)
|
84
|
+
|
85
|
+
open_last_text_message_for('+16105557069')
|
86
|
+
expect(current_text_message).to_not be_nil
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'records the from number for a message' do
|
90
|
+
@client.account.messages.create(
|
91
|
+
:from => '+14159341234',
|
92
|
+
:to => '+16105557069',
|
93
|
+
:body => 'Hey there!'
|
94
|
+
)
|
95
|
+
|
96
|
+
open_last_text_message_for('+16105557069')
|
97
|
+
expect(current_text_message.from).to eq('+14159341234')
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[spec_helper])
|
2
|
+
|
3
|
+
describe SmsUnitTest::Helpers do
|
4
|
+
include SmsUnitTest::Helpers
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
SmsUnitTest::Data.clear_messages
|
8
|
+
end
|
9
|
+
|
10
|
+
describe ".messages" do
|
11
|
+
describe "before any messages have been sent" do
|
12
|
+
it "is empty" do
|
13
|
+
expect(messages).to be_empty
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "after a message has been sent" do
|
18
|
+
it "adds a message" do
|
19
|
+
expect(lambda {
|
20
|
+
add_message SmsUnitTest::Message.new :number => "5555555512", :body => "Hello there"
|
21
|
+
}).to change(messages, :count).by(1)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe ".set_current_number" do
|
27
|
+
it "assigns the current number" do
|
28
|
+
set_current_number "555551234"
|
29
|
+
expect(current_number).to eql("555551234")
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'does not format phone numbers' do
|
33
|
+
set_current_number '+1555551234'
|
34
|
+
expect(current_number).to eql( '+1555551234')
|
35
|
+
|
36
|
+
set_current_number '+1 (616) 555-2929'
|
37
|
+
expect(current_number).to eql('+1 (616) 555-2929')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe ".clear_messages" do
|
42
|
+
it "removes all messages" do
|
43
|
+
add_message SmsUnitTest::Message.new :number => "5555555512", :body => "Hello there"
|
44
|
+
add_message SmsUnitTest::Message.new :number => "5555555512", :body => "Hello there"
|
45
|
+
add_message SmsUnitTest::Message.new :number => "5555555512", :body => "Hello there"
|
46
|
+
|
47
|
+
expect(messages.count).to eql(3)
|
48
|
+
clear_messages
|
49
|
+
expect(messages.count).to eql(0)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe ".current_text_message" do
|
54
|
+
describe "when there are not text messages yet" do
|
55
|
+
before :each do
|
56
|
+
SmsUnitTest::Data.clear_messages
|
57
|
+
end
|
58
|
+
|
59
|
+
it "returns nil" do
|
60
|
+
expect(current_text_message).to be_nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "when there are messages" do
|
65
|
+
let(:message1) { SmsUnitTest::Message.new :number => "5555555513", :body => "Hi" }
|
66
|
+
let(:message2) { SmsUnitTest::Message.new :number => "5555555512", :body => "Hello there" }
|
67
|
+
|
68
|
+
before do
|
69
|
+
add_message message1
|
70
|
+
add_message message2
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "and no messages have been opened" do
|
74
|
+
it "should be nil" do
|
75
|
+
expect(current_text_message).to be_nil
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "and a message has been opened" do
|
80
|
+
before do
|
81
|
+
open_last_text_message_for("5555555513")
|
82
|
+
end
|
83
|
+
|
84
|
+
it "returns the last open text message" do
|
85
|
+
expect(current_text_message).to eql(message1)
|
86
|
+
|
87
|
+
open_last_text_message_for("5555555513")
|
88
|
+
expect(current_text_message).to be_nil
|
89
|
+
|
90
|
+
open_last_text_message_for("5555555512")
|
91
|
+
expect(current_text_message).to eql(message2)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe ".twiml_message" do
|
98
|
+
context "with defaults" do
|
99
|
+
let(:message) {
|
100
|
+
twiml_message("+16165559982", "Ahoy!")
|
101
|
+
}
|
102
|
+
|
103
|
+
it "modifies the From attribute" do
|
104
|
+
expect(message["From"]).to eql("+16165559982")
|
105
|
+
end
|
106
|
+
|
107
|
+
it "Modifies the Body attribute" do
|
108
|
+
expect(message["Body"]).to eql("Ahoy!")
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "Overriding options" do
|
113
|
+
let(:message) {
|
114
|
+
twiml_message("+16165559982", "Ahoy!", "ToZip" => "49506", "ToCity" => "Detroit")
|
115
|
+
}
|
116
|
+
|
117
|
+
it "overrides the specified attributes" do
|
118
|
+
expect(message["ToZip"]).to eql("49506")
|
119
|
+
expect(message["ToCity"]).to eql("Detroit")
|
120
|
+
expect(message["Body"]).to eql("Ahoy!")
|
121
|
+
expect(message["From"]).to eql("+16165559982")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe ".clkatel_message" do
|
127
|
+
context "with defaults" do
|
128
|
+
let(:message) {
|
129
|
+
clkatel_message("+16165559982", "Ahoy!")
|
130
|
+
}
|
131
|
+
|
132
|
+
it "modifies the From attribute" do
|
133
|
+
expect(message["From"]).to eql("+16165559982")
|
134
|
+
end
|
135
|
+
|
136
|
+
it "Modifies the Body attribute" do
|
137
|
+
expect(message["Text"]).to eql("Ahoy!")
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "Overriding options" do
|
142
|
+
let(:message) {
|
143
|
+
clkatel_message("+16165559982", "Ahoy!")
|
144
|
+
}
|
145
|
+
|
146
|
+
it "overrides the specified attributes" do
|
147
|
+
expect(message["Text"]).to eql("Ahoy!")
|
148
|
+
expect(message["From"]).to eql("+16165559982")
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[spec_helper])
|
2
|
+
|
3
|
+
describe SmsUnitTest::Matchers do
|
4
|
+
include SmsUnitTest::Helpers
|
5
|
+
include SmsUnitTest::Matchers
|
6
|
+
|
7
|
+
let(:mobile_number) { "5555555512" }
|
8
|
+
|
9
|
+
class MatcherMatch
|
10
|
+
def initialize(object_to_test_match)
|
11
|
+
@object_to_test_match = object_to_test_match
|
12
|
+
end
|
13
|
+
|
14
|
+
def description
|
15
|
+
"match when provided #{@object_to_test_match.inspect}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def matches?(matcher)
|
19
|
+
@matcher = matcher
|
20
|
+
matcher.matches?(@object_to_test_match)
|
21
|
+
end
|
22
|
+
|
23
|
+
def failure_message
|
24
|
+
"expected #{@matcher.inspect} to match when provided #{@object_to_test_match.inspect}, but it did not"
|
25
|
+
end
|
26
|
+
|
27
|
+
def failure_message_when_negated
|
28
|
+
"expected #{@matcher.inspect} not to match when provided #{@object_to_test_match.inspect}, but it did"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def match(object_to_test_match)
|
33
|
+
if object_to_test_match.is_a?(Regexp)
|
34
|
+
super # delegate to rspec's built in 'match' matcher
|
35
|
+
else
|
36
|
+
MatcherMatch.new(object_to_test_match)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe ".have_text_messages" do
|
41
|
+
include SmsUnitTest::Matchers
|
42
|
+
|
43
|
+
describe "when the mobile device has no text messages" do
|
44
|
+
it "should not match" do
|
45
|
+
device = SmsUnitTest::MobileDevice.new(:number => mobile_number)
|
46
|
+
expect(have_text_messages).to_not match(device)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "when the mobile device has text messages" do
|
51
|
+
it "should match" do
|
52
|
+
add_message SmsUnitTest::Message.new(:number => mobile_number, :body => "something")
|
53
|
+
|
54
|
+
device = SmsUnitTest::MobileDevice.new(mobile_number)
|
55
|
+
expect(have_text_messages).to match(device)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe ".have_body" do
|
61
|
+
describe "when bodies match" do
|
62
|
+
it "matches" do
|
63
|
+
message = SmsUnitTest::Message.new(:number => mobile_number, :body => "something")
|
64
|
+
|
65
|
+
expect(have_body("something")).to match(message)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe ".have_body_like" do
|
71
|
+
describe "when bodies partially match" do
|
72
|
+
it "matches" do
|
73
|
+
message = SmsUnitTest::Message.new(:number => mobile_number, :body => "something is here")
|
74
|
+
|
75
|
+
expect(have_body_like("something")).to match(message)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "when bodies don't partiall match" do
|
80
|
+
it "does not match" do
|
81
|
+
message = SmsUnitTest::Message.new(:number => mobile_number, :body => "something is here")
|
82
|
+
|
83
|
+
expect(have_body_like("godzilla")).to_not match(message)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sms-unit-test
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kevin Ross
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-10-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: twilio-ruby
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '4.2'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '4.2'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: lookout-clickatell
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.8'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.8'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: SMS Spec gives you an RSpec DSL and Cucumber steps to test SMS interactions.
|
84
|
+
email:
|
85
|
+
- kevin.ross@alienfast.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".ruby-gemset"
|
92
|
+
- ".ruby-version"
|
93
|
+
- ".travis.yml"
|
94
|
+
- Gemfile
|
95
|
+
- Guardfile
|
96
|
+
- LICENSE
|
97
|
+
- README.md
|
98
|
+
- Rakefile
|
99
|
+
- lib/generators/sms_spec/steps/USAGE
|
100
|
+
- lib/generators/sms_spec/steps/steps_generator.rb
|
101
|
+
- lib/generators/sms_spec/steps/templates/sms_steps.rb
|
102
|
+
- lib/sms-unit-test.rb
|
103
|
+
- lib/sms_unit_test.rb
|
104
|
+
- lib/sms_unit_test/cucumber.rb
|
105
|
+
- lib/sms_unit_test/data.rb
|
106
|
+
- lib/sms_unit_test/drivers/clickatell.rb
|
107
|
+
- lib/sms_unit_test/drivers/twilio-ruby.rb
|
108
|
+
- lib/sms_unit_test/helpers.rb
|
109
|
+
- lib/sms_unit_test/matchers.rb
|
110
|
+
- lib/sms_unit_test/message.rb
|
111
|
+
- lib/sms_unit_test/mobile_device.rb
|
112
|
+
- lib/sms_unit_test/version.rb
|
113
|
+
- rails_generators/sms_unit_test/templates/sms_steps.rb
|
114
|
+
- rails_generators/sms_unit_test_generator.rb
|
115
|
+
- sms-unit-test.gemspec
|
116
|
+
- spec/drivers/clickatell_spec.rb
|
117
|
+
- spec/drivers/twilio_spec.rb
|
118
|
+
- spec/helpers_spec.rb
|
119
|
+
- spec/matchers_spec.rb
|
120
|
+
- spec/spec_helper.rb
|
121
|
+
homepage: https://github.com/rosskevin/sms-unit-test
|
122
|
+
licenses: []
|
123
|
+
metadata: {}
|
124
|
+
post_install_message:
|
125
|
+
rdoc_options: []
|
126
|
+
require_paths:
|
127
|
+
- lib
|
128
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
requirements: []
|
139
|
+
rubyforge_project: sms-unit-test
|
140
|
+
rubygems_version: 2.6.13
|
141
|
+
signing_key:
|
142
|
+
specification_version: 4
|
143
|
+
summary: Test SMS interactions with RSpec and Cucumber
|
144
|
+
test_files:
|
145
|
+
- spec/drivers/clickatell_spec.rb
|
146
|
+
- spec/drivers/twilio_spec.rb
|
147
|
+
- spec/helpers_spec.rb
|
148
|
+
- spec/matchers_spec.rb
|
149
|
+
- spec/spec_helper.rb
|