sms-unit-test 1.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 +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
|
+
[![Build Status](https://travis-ci.org/rosskevin/sms-unit-test.svg)](https://travis-ci.org/rosskevin/sms-unit-test)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/rosskevin/sms-unit-test/badges/gpa.svg)](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
|