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.
@@ -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
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .rvmrc
@@ -0,0 +1 @@
1
+ sms-unit-test
@@ -0,0 +1 @@
1
+ 2.4.1
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.4.1
4
+
5
+ script: rake
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in text_spec.gemspec
4
+ gemspec
@@ -0,0 +1,5 @@
1
+ guard 'rspec', :cli => "--color", :notification => true do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
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.
@@ -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
+ ```
@@ -0,0 +1,7 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
@@ -0,0 +1,6 @@
1
+ Description:
2
+ Creates text_message_steps.rb in your cucumber step_definitions.
3
+
4
+ Examples:
5
+ `script/rails generate text_spec:steps`
6
+
@@ -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,6 @@
1
+ After do
2
+ SmsUnitTest::Data.clear_messages
3
+ end
4
+
5
+ World(SmsUnitTest::Helpers)
6
+ World(SmsUnitTest::Matchers)
@@ -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,13 @@
1
+ module SmsUnitTest
2
+ class Message
3
+ attr_accessor :number
4
+ attr_accessor :body
5
+ attr_accessor :from
6
+
7
+ def initialize(opts = {})
8
+ @number = opts[:number]
9
+ @body = opts[:body]
10
+ @from = opts[:from]
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ module SmsUnitTest
2
+ class MobileDevice
3
+
4
+ def initialize(number)
5
+ @number = number
6
+ end
7
+
8
+ def messages
9
+ SmsUnitTest::Data.messages.select {|d| d.number == @number}
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module SmsUnitTest
2
+ VERSION = '1.0.1'
3
+ 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,12 @@
1
+ class SmsUnitTestGenerator < Rails::Generator::Base
2
+ def manifest
3
+ m.directory 'features/step_definitions'
4
+ m.file 'sms_steps.rb', 'features/step_definitions/sms_steps.rb'
5
+ end
6
+
7
+ protected
8
+
9
+ def banner
10
+ "Usage: #{0} sms_unit_test"
11
+ end
12
+ end
@@ -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
@@ -0,0 +1,4 @@
1
+ require File.join(File.dirname(__FILE__), *%w[.. lib sms-unit-test])
2
+
3
+ require 'rubygems'
4
+ require 'pry'
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