smslist 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE.md ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2013 Yury Lebedev
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,114 @@
1
+ # Smslist
2
+
3
+ [![Build Status](https://secure.travis-ci.org/lebedev-yury/smslist.png?branch=master)][travis]
4
+ [![Dependency Status](https://gemnasium.com/lebedev-yury/smslist.png?travis)][gemnasium]
5
+ [![Code Climate](https://codeclimate.com/github/lebedev-yury/smslist.png)][codeclimate]
6
+ [![Coverage Status](https://coveralls.io/repos/lebedev-yury/smslist/badge.png?branch=master)][coveralls]
7
+
8
+ [travis]: http://travis-ci.org/lebedev-yury/smslist
9
+ [gemnasium]: https://gemnasium.com/lebedev-yury/smslist
10
+ [codeclimate]: https://codeclimate.com/github/lebedev-yury/smslist
11
+ [coveralls]: https://coveralls.io/r/lebedev-yury/smslist
12
+
13
+ Simple Ruby wrapper for the SMSlist API. [SMSlist][smslist] is a service for mass sending sms messages.
14
+
15
+ [smslist]: http://www.smscell.ru
16
+
17
+ ## Installation
18
+
19
+ ```ruby
20
+ gem install smslist
21
+ ```
22
+
23
+ ## Configuration
24
+
25
+ You can configure this gem in an initializer:
26
+
27
+ ```ruby
28
+ Smslist.configure do |c|
29
+ c.sender = '79101234567'
30
+
31
+ # you can use the token
32
+ c.token = 'your_api_token'
33
+
34
+ # or authenticate with login and password
35
+ c.login = 'username'
36
+ c.password = 'secret'
37
+ end
38
+ ```
39
+
40
+ Or simply:
41
+
42
+ ```ruby
43
+ client = Smslist.new(sender: '79101234567', token: 'your_api_token')
44
+ ```
45
+
46
+ ## Usage
47
+
48
+ ### Getting the balance and remaining sms count
49
+
50
+ ```ruby
51
+ balance = client.balance
52
+ remaining = client.remaining_sms
53
+ ```
54
+
55
+ ### Sending sms messages
56
+
57
+ ```ruby
58
+ recipients = %w(79031234567 79032345678 79033456789)
59
+ response = client.send_sms('Your text message', recipients)
60
+ ```
61
+
62
+ If can pass optional param, to send a flash sms message:
63
+
64
+ ```ruby
65
+ response = client.send_sms('Your text message', recipients, flash: true)
66
+ ```
67
+
68
+ You will get a hash for each number, with status, message id (to retrieve status later) and number of parts:
69
+
70
+ ```ruby
71
+ {
72
+ '79031234567' => { status: :ok, id: 1001, parts: 2 },
73
+ ...
74
+ '79033456789' => { error: 'Номер телефона присутствует в стоп-листе.' }
75
+ }
76
+ ```
77
+
78
+ Status :ok means, that the message was successfully placed in a queue.
79
+
80
+ ### Getting state of sent messages
81
+
82
+ ```ruby
83
+ message_ids = %w(1001 1002 1003 1004)
84
+ response = client.state(message_ids)
85
+ ```
86
+
87
+ You will get a hash for id, with state and datetime, or error message.
88
+
89
+ ## Supported Ruby Versions
90
+
91
+ This library aims to support and is [tested against][travis] the following Ruby
92
+ implementations:
93
+
94
+ * Ruby 1.8.7
95
+ * Ruby 1.9.2
96
+ * Ruby 1.9.3
97
+ * Ruby 2.0.0
98
+
99
+ If something doesn't work on one of these Ruby versions, it's a bug.
100
+
101
+ This library may inadvertently work (or seem to work) on other Ruby
102
+ implementations, however support will only be provided for the versions listed
103
+ above.
104
+
105
+ ## Inspiration
106
+ Smslist was inspired by [Octokit][].
107
+
108
+ [octokit]: https://github.com/pengwynn/octokit
109
+
110
+ ## Copyright
111
+ Copyright (c) 2013 Yury Lebedev.
112
+ See [LICENSE][] for details.
113
+
114
+ [license]: LICENSE.md
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :test => :spec
8
+ task :default => :spec
9
+
10
+ namespace :doc do
11
+ require 'yard'
12
+ YARD::Rake::YardocTask.new do |task|
13
+ task.files = ['README.md', 'LICENSE.md', 'lib/**/*.rb']
14
+ task.options = [
15
+ '--output-dir', 'doc/yard',
16
+ '--markup', 'markdown',
17
+ ]
18
+ end
19
+ end
data/lib/smslist.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'nokogiri'
2
+ require 'smslist/configuration'
3
+ require 'smslist/error'
4
+ require 'smslist/client'
5
+
6
+ module Smslist
7
+ extend Configuration
8
+ class << self
9
+ # Alias for Smslist::Client.new
10
+ #
11
+ # @return [Smslist::Client]
12
+ def new(options = {})
13
+ Smslist::Client.new(options)
14
+ end
15
+
16
+ # Delegate to Smslist::Client.new
17
+ def method_missing(method, *args, &block)
18
+ return super unless new.respond_to?(method)
19
+ new.send(method, *args, &block)
20
+ end
21
+
22
+ def respond_to?(method, include_private = false)
23
+ new.respond_to?(method, include_private) || super(method, include_private)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,14 @@
1
+ module Smslist
2
+ module Authentication
3
+ def authentication
4
+ if token
5
+ {:token => token}
6
+ elsif login && password
7
+ {:login => login, :password => password}
8
+ else
9
+ raise Smslist::UnauthorizedError.new('Access token, or login '\
10
+ 'and password are not initialized')
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ require 'smslist/authentication'
2
+ require 'smslist/request'
3
+ require 'smslist/response'
4
+
5
+ require 'smslist/client/balance'
6
+ require 'smslist/client/sms'
7
+ require 'smslist/client/state'
8
+
9
+ module Smslist
10
+ class Client
11
+ attr_accessor(*Configuration::VALID_OPTIONS_KEYS)
12
+
13
+ def initialize(options = {})
14
+ options = Smslist.options.merge(options)
15
+
16
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
17
+ self.send("#{key}=", options[key])
18
+ end
19
+ end
20
+
21
+ include Smslist::Authentication
22
+ include Smslist::Request
23
+ include Smslist::Response
24
+
25
+ include Smslist::Client::Balance
26
+ include Smslist::Client::Sms
27
+ include Smslist::Client::State
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ module Smslist
2
+ class Client
3
+ module Balance
4
+ # Get account balance
5
+ #
6
+ # @return [Float] account balance
7
+ # @example Get balance for user qwerty
8
+ # client = Smslist.new(login: 'qwerty', password: 'secret')
9
+ # client.balance
10
+ def balance
11
+ response = parse_xml(post build_xml_body.to_xml, :balance)
12
+ response.xpath('response/money').text.to_f
13
+ end
14
+
15
+ # Get remaining sms count
16
+ #
17
+ # @return [Integer] remaining sms count
18
+ # @example Get remaining sms count for user qwerty
19
+ # client = Smslist.new(login: 'qwerty', password: 'secret')
20
+ # client.remaining_sms
21
+ def remaining_sms
22
+ response = parse_xml(post build_xml_body.to_xml, :balance)
23
+ response.xpath('response/sms').first.text.to_i
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,52 @@
1
+ module Smslist
2
+ class Client
3
+ module Sms
4
+ # Send sms message for a list of recipients
5
+ #
6
+ # @param text [String] Message text
7
+ # @param recipients [Array] Array of phone numbers
8
+ # @option values [Boolean] :flash True for flash sms messages
9
+ # @return [Hash] Hash with statuses for each sent message
10
+ # @example Send message to a list of users
11
+ # client = Smslist.new(token: 'secret', sender: '4040')
12
+ #
13
+ # recipients = %w(79031234567 79032345678)
14
+ # client.send_sms('Message', recipients)
15
+ def send_sms(text, recipients = [], options = {})
16
+ unless sms_sender = sender
17
+ raise Smslist::NoSenderError.new('You must set a sender')
18
+ end
19
+
20
+ body = build_xml_body do |xml|
21
+ xml.message(type: "#{ 'flash' if options[:flash] }sms") {
22
+ xml.sender sms_sender
23
+ xml.text_ text.encode(:xml => :text)
24
+ recipients.each_with_index do |recipient, index|
25
+ xml.abonent :phone => recipient, :number_sms => index + 1
26
+ end
27
+ }
28
+ end
29
+
30
+ response = parse_xml(post body.to_xml)
31
+ parse_send_sms_response(response, recipients)
32
+ end
33
+
34
+ private
35
+
36
+ def parse_send_sms_response(response, recipients)
37
+ response_array = response.xpath('response/information').map do |node|
38
+ if node.text == 'send'
39
+ [
40
+ recipients[node[:number_sms].to_i - 1],
41
+ {:status => :ok, :id => node['id_sms'].to_i, :parts => node['parts'].to_i }
42
+ ]
43
+ else
44
+ [recipients[node[:number_sms].to_i - 1], { :error => node.text }]
45
+ end
46
+ end
47
+
48
+ Hash[*response_array.flatten]
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,64 @@
1
+ module Smslist
2
+ class Client
3
+ module State
4
+ STATE_ERRORS = {
5
+ 1 => 'The subscriber is absent or out of a coverage',
6
+ 2 => 'Call barred service activated',
7
+ 3 => 'Unknown subscriber',
8
+ 4 => 'Memory capacity exceeded',
9
+ 5 => 'Equipment protocol error',
10
+ 6 => 'Teleservice not provisioned',
11
+ 7 => 'Facility not supported',
12
+ 8 => 'Subscriber is busy',
13
+ 9 => 'Roaming restrictions',
14
+ 10 => 'Timeout',
15
+ 11 => 'SS7 routing error',
16
+ 12 => 'Internal system failure',
17
+ 13 => 'SMSC failure'
18
+ }.freeze
19
+
20
+ # Get state for a list of message ids
21
+ #
22
+ # @param message_ids [Array] Array of message ids
23
+ # @return [Hash] Hash with state, time or error for each message
24
+ # @example Get state for a list of message ids
25
+ # client = Smslist.new(token: 'secret')
26
+ #
27
+ # message_ids = %w(10001 10002 10003)
28
+ # client.state(message_ids)
29
+ def state(message_ids = [])
30
+ body = build_xml_body do |xml|
31
+ xml.get_state {
32
+ message_ids.each do |id|
33
+ xml.id_sms id
34
+ end
35
+ }
36
+ end
37
+
38
+ response = parse_xml(post body.to_xml, :state)
39
+ parse_state_response(response)
40
+ end
41
+
42
+ private
43
+
44
+ def parse_state_response(response)
45
+ response_array = response.xpath('response/state').map do |node|
46
+ if node[:err] == '0'
47
+ [
48
+ node['id_sms'],
49
+ {
50
+ :state => node.text,
51
+ :datetime => DateTime.strptime(node['time'], '%Y-%m-%d %H:%M:%S')
52
+ }
53
+ ]
54
+ else
55
+ [node['id_sms'], { :state => node.text,
56
+ :error => STATE_ERRORS[node['err'].to_i] }]
57
+ end
58
+ end
59
+
60
+ Hash[*response_array.flatten]
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,55 @@
1
+ require 'smslist/version'
2
+
3
+ module Smslist
4
+ module Configuration
5
+ VALID_OPTIONS_KEYS = [
6
+ :api_endpoint,
7
+ :login,
8
+ :password,
9
+ :token,
10
+ :user_agent,
11
+ :sender
12
+ ].freeze
13
+
14
+ METHOD_ENDPOINTS = [
15
+ :state,
16
+ :balance,
17
+ :incoming,
18
+ :def,
19
+ :list_bases,
20
+ :bases,
21
+ :list_phones,
22
+ :phones,
23
+ :delete_phones,
24
+ :stop,
25
+ :list_sheduled,
26
+ :scheduled
27
+ ].freeze
28
+
29
+ DEFAULT_API_ENDPOINT = 'https://my.smscell.ru/xml/'
30
+ DEFAULT_USER_AGENT = "Smslist Ruby Gem #{Smslist::VERSION}".freeze
31
+
32
+ attr_accessor(*VALID_OPTIONS_KEYS)
33
+
34
+ def self.extended(base)
35
+ base.reset
36
+ end
37
+
38
+ def configure
39
+ yield self
40
+ end
41
+
42
+ def options
43
+ VALID_OPTIONS_KEYS.inject({}) { |o, k| o.merge!(k => send(k)) }
44
+ end
45
+
46
+ def reset
47
+ self.user_agent = DEFAULT_USER_AGENT
48
+ self.api_endpoint = DEFAULT_API_ENDPOINT
49
+ self.login = nil
50
+ self.password = nil
51
+ self.token = nil
52
+ self.sender = nil
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,11 @@
1
+ module Smslist
2
+ class Error < StandardError
3
+ def initialize(response = nil)
4
+ @response = response
5
+ super @response
6
+ end
7
+ end
8
+
9
+ class UnauthorizedError < Error; end
10
+ class NoSenderError < Error; end
11
+ end
@@ -0,0 +1,37 @@
1
+ require 'httparty'
2
+
3
+ module Smslist
4
+ module Request
5
+ def post(xml, method = nil)
6
+ HTTParty.post request_uri(method), :body => xml, :headers => headers
7
+ end
8
+
9
+ def build_xml_body(&block)
10
+ Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
11
+ xml.request {
12
+ xml.security {
13
+ authentication.each { |k, v| xml.send(k, :value => v) }
14
+ }
15
+ xml.instance_eval(&block) if block_given?
16
+ }
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def headers
23
+ {
24
+ 'Content-type' => 'text/xml; charset=utf-8',
25
+ 'User-Agent' => Configuration::DEFAULT_USER_AGENT
26
+ }
27
+ end
28
+
29
+ def request_uri(method = nil)
30
+ if method && Configuration::METHOD_ENDPOINTS.include?(method)
31
+ [Configuration::DEFAULT_API_ENDPOINT, method.to_s + '.php'].join
32
+ else
33
+ Configuration::DEFAULT_API_ENDPOINT
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,10 @@
1
+ module Smslist
2
+ module Response
3
+ def parse_xml(response)
4
+ Nokogiri::XML(response.body).tap do |xml|
5
+ error = xml.xpath('response/error').text
6
+ raise Smslist::Error.new(error) unless error.empty?
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module Smslist
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <response>
3
+ <money>10</money>
4
+ <sms area="Россия">20</sms>
5
+ <sms area="Украина">10</sms>
6
+ </response>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <response>
3
+ <information number_sms="1" id_sms="1001" parts="2">send</information>
4
+ <information number_sms="2" id_sms="1002" parts="2">send</information>
5
+ <information number_sms="3" id_sms="1003" parts="2">send</information>
6
+ <information number_sms="4" id_sms="1004" parts="2">Номер телефона присутствует в стоп-листе.</information>
7
+ </response>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <response>
3
+ <state id_sms="1001" time="2011-01-01 12:57:46" err="0">deliver</state>
4
+ <state id_sms="1002" time="2011-01-01 12:57:46" err="0">deliver</state>
5
+ <state id_sms="1003" time="2011-01-01 12:57:46" err="0">expired</state>
6
+ <state id_sms="1004" time="" err="1">not_deliver</state>
7
+ </response>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <response>
3
+ <error>Неправильный логин или пароль</error>
4
+ </response></code></pre>
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Smslist::Client::Balance do
6
+ let(:client) { Smslist::Client.new(:token => 'secret') }
7
+
8
+ describe '#balance' do
9
+ it 'returns remaining balance' do
10
+ stub_post('balance.php').to_return(xml_response('balance.xml'))
11
+ expect(client.balance).to eq(10.0)
12
+ end
13
+ end
14
+
15
+ describe '#remaining_sms' do
16
+ it 'returns remaining sms count' do
17
+ stub_post('balance.php').to_return(xml_response('balance.xml'))
18
+ expect(client.remaining_sms).to eq(20)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,40 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Smslist::Client::Sms do
6
+
7
+ describe '#send_sms' do
8
+ context 'sender is set' do
9
+ let(:client) { Smslist::Client.new(:token => 'secret', :sender => '4000') }
10
+ let(:recipients) { %w(79031234567 79032345678 79033456789 79034567890) }
11
+
12
+ before(:each) { stub_post('').to_return(xml_response('sms.xml')) }
13
+
14
+ it 'returns a Hash' do
15
+ expect(client.send_sms('Hello everyone', recipients)).to be_a(Hash)
16
+ end
17
+
18
+ it 'includes a Hash for sent messages, with status, id and parts count' do
19
+ expect(client.send_sms('Hello everyone', recipients, :flash => true))
20
+ .to include('79031234567' => { :status => :ok, :id => 1001, :parts => 2 })
21
+ end
22
+
23
+ it 'includes a Hash for not sent messages' do
24
+ expect(client.send_sms('Hello everyone', recipients))
25
+ .to include('79034567890' => { :error => 'Номер телефона присутствует в стоп-листе.' })
26
+ end
27
+ end
28
+
29
+ context 'sender is not set' do
30
+ let(:client) { Smslist::Client.new(:token => 'secret') }
31
+ let(:recipients) { %w(79031234567) }
32
+
33
+ it 'raises NoSenderError' do
34
+ expect {
35
+ client.send_sms('Hello everyone', recipients)
36
+ }.to raise_error(Smslist::NoSenderError)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Smslist::Client::State do
6
+
7
+ describe '#state' do
8
+ let(:client) { Smslist::Client.new(:token => 'secret') }
9
+ let(:message_ids) { %w(1001 1002 1003 1004) }
10
+
11
+ before(:each) { stub_post('state.php').to_return(xml_response('state.xml')) }
12
+
13
+ it 'returns a Hash' do
14
+ expect(client.state(message_ids)).to be_a(Hash)
15
+ end
16
+
17
+ it 'includes a Hash for delivered messages, with state' do
18
+ expect(client.state(message_ids)['1001'][:state]).to eql('deliver')
19
+ end
20
+
21
+ it 'includes a Hash for delivered messages, with delivered datetime' do
22
+ datetime = DateTime.strptime('2011-01-01 12:57:46', '%Y-%m-%d %H:%M:%S')
23
+ expect(client.state(message_ids)['1001'][:datetime]).to be_within(1).of(datetime)
24
+ end
25
+
26
+ it 'includes a Hash for not delivered messages' do
27
+ expect(client.state(message_ids))
28
+ .to include('1004' => { :state => 'not_deliver',
29
+ :error => 'The subscriber is absent or out of a coverage' })
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ describe Smslist::Client do
4
+
5
+ describe 'api endpoint' do
6
+ it 'defaults to https://my.smscell.ru/xml' do
7
+ client = Smslist::Client.new
8
+ expect(client.api_endpoint).to eq('https://my.smscell.ru/xml/')
9
+ end
10
+ end
11
+
12
+ context 'Authentication module' do
13
+ describe '#authentication' do
14
+ it 'hash with a token, if token, login and password are set' do
15
+ client = Smslist::Client.new(
16
+ :login => 'username',
17
+ :password => 'secret',
18
+ :token => 'api_token'
19
+ )
20
+ expect(client.authentication).to eql({ :token => 'api_token' })
21
+ end
22
+
23
+ it 'hash with login and password, if login and password are set' do
24
+ client = Smslist::Client.new(
25
+ :login => 'username',
26
+ :password => 'secret'
27
+ )
28
+ expect(client.authentication).to eql({ :login => 'username', :password => 'secret' })
29
+ end
30
+
31
+ it 'raises Smslist::UnauthorizedError, if credentials are not set' do
32
+ client = Smslist::Client.new
33
+ expect {
34
+ client.authentication
35
+ }.to raise_error(Smslist::UnauthorizedError)
36
+ end
37
+ end
38
+ end
39
+
40
+ context 'wrong credentials' do
41
+ let(:client) { Smslist::Client.new(:token => 'secret') }
42
+ before(:each) do
43
+ stub_post('balance.php').to_return(xml_response('wrong_credentials.xml'))
44
+ end
45
+
46
+ it 'raises Error' do
47
+ expect {
48
+ client.balance
49
+ }.to raise_error(Smslist::Error)
50
+ end
51
+ end
52
+
53
+ context 'Request module' do
54
+ let(:client) { Smslist::Client.new }
55
+
56
+ describe '#headers' do
57
+ let(:headers) { client.send(:headers) }
58
+ it 'Content-type is set to text/xml, charset is utf-8' do
59
+ expect(headers).to include('Content-type' => 'text/xml; charset=utf-8')
60
+ end
61
+
62
+ it 'User-Agent is set' do
63
+ expect(headers).to include('User-Agent' => "Smslist Ruby Gem #{Smslist::VERSION}")
64
+ end
65
+ end
66
+
67
+ describe '#request_uri' do
68
+ it 'returns API endpoint if method is nil' do
69
+ expect(client.send(:request_uri)).to eql('https://my.smscell.ru/xml/')
70
+ end
71
+
72
+ it 'returns API endpoint if the method does not exist' do
73
+ uri = client.send(:request_uri, :wrong_method)
74
+ expect(uri).to eql('https://my.smscell.ru/xml/')
75
+ end
76
+
77
+ it 'returns full url to php script if the method exists' do
78
+ uri = client.send(:request_uri, :balance)
79
+ expect(uri).to eql('https://my.smscell.ru/xml/balance.php')
80
+ end
81
+ end
82
+ end
83
+
84
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Smslist do
4
+
5
+ describe '.new' do
6
+ it 'is a Smslist::Client' do
7
+ expect(Smslist.new).to be_a Smslist::Client
8
+ end
9
+ end
10
+
11
+ describe '.respond_to?' do
12
+ it 'is true if method exists' do
13
+ expect(Smslist.respond_to?(:new, true)).to eq(true)
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,41 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+
4
+ require 'smslist'
5
+ require 'rspec'
6
+ require 'webmock/rspec'
7
+
8
+ RSpec.configure do |config|
9
+ config.expect_with :rspec do |c|
10
+ c.syntax = :expect
11
+ end
12
+ end
13
+
14
+ def stub_post(path)
15
+ WebMock::stub_request(:post, smslist_url(path))
16
+ end
17
+
18
+ def fixture_path
19
+ File.expand_path("../fixtures", __FILE__)
20
+ end
21
+
22
+ def fixture(file)
23
+ File.new(fixture_path + '/' + file)
24
+ end
25
+
26
+ def xml_response(file)
27
+ {
28
+ :body => fixture(file),
29
+ :headers => {
30
+ :content_type => 'text/xml; charset=utf-8'
31
+ }
32
+ }
33
+ end
34
+
35
+ def smslist_url(url)
36
+ if url =~ /^http/
37
+ url
38
+ else
39
+ "#{Smslist::Configuration::DEFAULT_API_ENDPOINT}#{url}"
40
+ end
41
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: smslist
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Yury Lebedev
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: httparty
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0.10'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0.10'
30
+ - !ruby/object:Gem::Dependency
31
+ name: nokogiri
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '1.5'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '1.5'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '2.0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '2.0'
78
+ description: Now you can send sms messages to your users.
79
+ email:
80
+ - lebedev.yurii@gmail.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - LICENSE.md
86
+ - Rakefile
87
+ - README.md
88
+ - lib/smslist/authentication.rb
89
+ - lib/smslist/client/balance.rb
90
+ - lib/smslist/client/sms.rb
91
+ - lib/smslist/client/state.rb
92
+ - lib/smslist/client.rb
93
+ - lib/smslist/configuration.rb
94
+ - lib/smslist/error.rb
95
+ - lib/smslist/request.rb
96
+ - lib/smslist/response.rb
97
+ - lib/smslist/version.rb
98
+ - lib/smslist.rb
99
+ - spec/fixtures/balance.xml
100
+ - spec/fixtures/sms.xml
101
+ - spec/fixtures/state.xml
102
+ - spec/fixtures/wrong_credentials.xml
103
+ - spec/smslist/client/balance_spec.rb
104
+ - spec/smslist/client/sms_spec.rb
105
+ - spec/smslist/client/state_spec.rb
106
+ - spec/smslist/client_spec.rb
107
+ - spec/smslist_spec.rb
108
+ - spec/spec_helper.rb
109
+ homepage: https://github.com/lebedev-yury/smslist
110
+ licenses:
111
+ - MIT
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: 1.3.6
128
+ requirements: []
129
+ rubyforge_project:
130
+ rubygems_version: 1.8.23
131
+ signing_key:
132
+ specification_version: 3
133
+ summary: Ruby wrapper for smslist API
134
+ test_files: []
135
+ has_rdoc: