bobes-textmagic 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +35 -2
- data/VERSION.yml +1 -1
- data/lib/api.rb +153 -8
- data/lib/charset.rb +23 -0
- data/lib/error.rb +11 -2
- data/lib/executor.rb +18 -2
- data/lib/response.rb +141 -0
- data/lib/textmagic.rb +4 -1
- data/lib/validation.rb +34 -0
- data/test/test_api.rb +110 -56
- data/test/test_charset.rb +28 -0
- data/test/test_error.rb +24 -0
- data/test/test_executor.rb +34 -1
- data/test/test_helper.rb +2 -2
- data/test/test_response.rb +176 -0
- data/test/test_validation.rb +99 -0
- data/textmagic.gemspec +13 -4
- metadata +13 -4
- data/test/test_textmagic.rb +0 -4
data/README.rdoc
CHANGED
@@ -1,6 +1,39 @@
|
|
1
|
-
=
|
1
|
+
= TextMagic
|
2
|
+
|
3
|
+
TextMagic is a Ruby interface to the TextMagic's HTTP API. You need to have
|
4
|
+
a valid TextMagic account to use this gem. Sign up at http://www.textmagic.com
|
5
|
+
to get one.
|
6
|
+
|
7
|
+
== Installation
|
8
|
+
|
9
|
+
Run
|
10
|
+
|
11
|
+
gem install textmagic
|
12
|
+
|
13
|
+
Use +sudo+ if required by your system.
|
14
|
+
|
15
|
+
|
16
|
+
== Basic usage
|
17
|
+
|
18
|
+
To create an API instance, run:
|
19
|
+
|
20
|
+
api = TextMagic::API.new(username, password)
|
21
|
+
|
22
|
+
with your credentials. Created instance will remember the username and password
|
23
|
+
and will use it for all commands.
|
24
|
+
|
25
|
+
To retrieve your account's balance, run:
|
26
|
+
|
27
|
+
api.account['balance']
|
28
|
+
|
29
|
+
To send a text message, run:
|
30
|
+
|
31
|
+
api.send 'Hi Vilma!', '441234567890'
|
32
|
+
|
33
|
+
You can even specify multiple phone numbers:
|
34
|
+
|
35
|
+
api.send 'Hi Vilma!', '314159265358', '271828182845'
|
2
36
|
|
3
|
-
Documentation will come soon.
|
4
37
|
|
5
38
|
== Copyright
|
6
39
|
|
data/VERSION.yml
CHANGED
data/lib/api.rb
CHANGED
@@ -2,33 +2,178 @@ module TextMagic
|
|
2
2
|
|
3
3
|
class API
|
4
4
|
|
5
|
+
extend Charset
|
6
|
+
extend Validation
|
7
|
+
|
8
|
+
# Creates new API instance with specified credentials. These will be
|
9
|
+
# used in all requests to the TextMagic's HTTP gateway done through
|
10
|
+
# this instance. Multiple instances with different credentials can
|
11
|
+
# be used at the same time.
|
12
|
+
#
|
13
|
+
# Example usage:
|
14
|
+
#
|
15
|
+
# api = TextMagic::API.new('fred', 'secret')
|
5
16
|
def initialize(username, password)
|
6
17
|
@username = username
|
7
18
|
@password = password
|
8
19
|
end
|
9
20
|
|
21
|
+
# Executes an account command and returns a hash with account's balance
|
22
|
+
# if successful, otherwise it raises an Error.
|
23
|
+
# The returned hash will be extended with custom reader method defined
|
24
|
+
# in Response module.
|
25
|
+
#
|
26
|
+
# Example usage:
|
27
|
+
#
|
28
|
+
# api.account
|
29
|
+
# # => { 'balance' => 314.15 }
|
30
|
+
#
|
31
|
+
# Using custom reader:
|
32
|
+
#
|
33
|
+
# api.account.balance
|
34
|
+
# # => 314.15
|
10
35
|
def account
|
11
36
|
response = Executor.execute('account', @username, @password)
|
12
|
-
response
|
13
|
-
response
|
37
|
+
response.extend(TextMagic::API::Response::Account)
|
14
38
|
end
|
15
39
|
|
40
|
+
# Executes a send command and returns a hash with message ids, sent text and
|
41
|
+
# number of parts if successful, otherwise it raises an Error.
|
42
|
+
# The returned hash will be extended with custom reader method defined
|
43
|
+
# in Response module.
|
44
|
+
#
|
45
|
+
# This method accepts any positive number of phone numbers and an additional
|
46
|
+
# options hash.
|
47
|
+
#
|
48
|
+
# The optional parameters you can specify in the options hash are:
|
49
|
+
# * +unicode+: accepted values are true, false, 0 and 1
|
50
|
+
# * +max_length+: accepted values are nil, 1, 2 and 3, defaults to nil
|
51
|
+
# If not specified, the method will determine the unicode value based on the
|
52
|
+
# characters in the text.
|
53
|
+
#
|
54
|
+
# Example usage:
|
55
|
+
#
|
56
|
+
# api.send('Hi Vilma', '999314159265')
|
57
|
+
# # => { 'message_ids' => [141421], 'message_id_hash' => { '999314159265' => '141421' }, 'sent_text' => 'Hi Vilma', 'parts_count' => 1 }
|
58
|
+
# api.send(text, phone, :unicode => true)
|
59
|
+
# api.send(text, phone1, phone2, :max_length => 2)
|
60
|
+
# api.send(text, [phone1, phone2])
|
61
|
+
#
|
62
|
+
# Using custom readers:
|
63
|
+
#
|
64
|
+
# response = api.send('Hi Vilma', '999314159265', '999271828182')
|
65
|
+
# response.message_ids
|
66
|
+
# # => ['141421', '173205']
|
67
|
+
# response.message_id_hash
|
68
|
+
# # => { '999314159265' => '141421', '999271828182' => '173205' }
|
69
|
+
# response.message_id
|
70
|
+
# # => '141421'
|
71
|
+
# response.message_id('999271828182')
|
72
|
+
# # => '173205'
|
73
|
+
# response.parts_count
|
74
|
+
# # => 1
|
16
75
|
def send(text, *args)
|
76
|
+
raise Error.new(1, 'Message text is empty') if text.nil? || text.blank?
|
17
77
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
18
|
-
|
19
|
-
|
78
|
+
unicode = API.is_unicode(text)
|
79
|
+
options[:unicode] = case options[:unicode]
|
80
|
+
when 1, true: 1
|
81
|
+
when 0, false: 0
|
82
|
+
when nil: unicode ? 1 : 0
|
83
|
+
else raise Error.new(10, "Wrong parameter value #{options[:unicode]} for parameter unicode")
|
84
|
+
end
|
85
|
+
raise Error.new(6, 'Message contains invalid characters') if unicode && options[:unicode] == 0
|
86
|
+
raise Error.new(7, 'Message too long') unless API.validate_text_length(text, unicode)
|
87
|
+
phones = args.flatten
|
88
|
+
raise Error.new(9, 'Invalid phone number format') unless API.validate_phones(phones)
|
89
|
+
response = Executor.execute('send', @username, @password, options.merge(:text => text, :phone => phones.join(',')))
|
90
|
+
response.extend(TextMagic::API::Response::Send)
|
20
91
|
end
|
21
92
|
|
93
|
+
# Executes a message_status command and returns a hash with states of
|
94
|
+
# messages for specified ids if successful, otherwise it raises a
|
95
|
+
# TextMagic::API::Error.
|
96
|
+
# The returned hash will be extended with custom reader method defined
|
97
|
+
# in Response module.
|
98
|
+
#
|
99
|
+
# This method accepts any positive number of ids specified as an array
|
100
|
+
# or as a list of arguments
|
101
|
+
#
|
102
|
+
# Example usage:
|
103
|
+
#
|
104
|
+
# api.message_status('141421')
|
105
|
+
# # => { '141421' => { 'text' => 'Hi Vilma', 'status' => 'd' , 'created_time' => Mon May 25 16:42:30 +0200 2009, 'reply_number' => '447624800500', 'completed_time' => nil, 'credits_cost' => 0.5 } }
|
106
|
+
# api.message_status('141421', '173205')
|
107
|
+
# api.message_status(['141421', '173205'])
|
108
|
+
#
|
109
|
+
# Using custom readers:
|
110
|
+
#
|
111
|
+
# response = api.message_status('141421', '173205')
|
112
|
+
# response['141421'].text
|
113
|
+
# # => 'Hi Vilma'
|
114
|
+
# response['141421'].status
|
115
|
+
# # => 'd'
|
116
|
+
# response['141421'].created_time
|
117
|
+
# # => Fri May 22 10:10:18 +0200 2009
|
22
118
|
def message_status(*ids)
|
23
|
-
|
119
|
+
ids.flatten!
|
120
|
+
raise TextMagic::API::Error.new(4, 'Insufficient parameters') if ids.empty?
|
121
|
+
response = Executor.execute('message_status', @username, @password, :ids => ids.join(','))
|
122
|
+
response.extend(TextMagic::API::Response::MessageStatus)
|
24
123
|
end
|
25
124
|
|
26
|
-
|
27
|
-
|
125
|
+
# Executes a receive command and returns a hash with unread messages
|
126
|
+
# if successful, otherwise it raises an Error.
|
127
|
+
# The returned hash will be extended with custom reader method defined
|
128
|
+
# in Response module.
|
129
|
+
#
|
130
|
+
# This method accepts an optional +last_retrieved_id+ value.
|
131
|
+
#
|
132
|
+
# Example usage:
|
133
|
+
#
|
134
|
+
# api.receive
|
135
|
+
# # => { 'messages' => [{ 'message_id' => '141421', 'from' => '999314159265', 'timestamp' => Fri May 22 12:12:55 +0200 2009, 'text' => 'Hi Fred!' }], 'unread' => 0 }
|
136
|
+
# api.receive '141421'
|
137
|
+
#
|
138
|
+
# Using custom readers:
|
139
|
+
#
|
140
|
+
# response = api.receive
|
141
|
+
# response.messages
|
142
|
+
# # => [{ 'timestamp' => Fri May 22 12:12:55 +0200 2009, 'from' => '999314159265', 'text' => 'Hi Fred', 'message_id' => '141421' }]
|
143
|
+
# response.unread
|
144
|
+
# # => 0
|
145
|
+
# response.messages[0].timestamp
|
146
|
+
# # => Fri May 22 12:12:55 +0200 2009
|
147
|
+
def receive(last_retrieved_id = nil)
|
148
|
+
response = Executor.execute('receive', @username, @password, :last_retrieved_id => last_retrieved_id)
|
149
|
+
response.extend(TextMagic::API::Response::Receive)
|
28
150
|
end
|
29
151
|
|
152
|
+
# Executes a delete_reply command and returns a hash with a list of deleted
|
153
|
+
# message ids if successful, otherwise it raises an Error.
|
154
|
+
# The returned hash will be extended with custom reader method defined
|
155
|
+
# in Response module.
|
156
|
+
#
|
157
|
+
# This method accepts any positive number of ids specified as an array
|
158
|
+
# or as a list of arguments.
|
159
|
+
#
|
160
|
+
# Example usage:
|
161
|
+
#
|
162
|
+
# api.delete_reply('141421')
|
163
|
+
# # => { 'deleted' => ['141421'] }
|
164
|
+
# api.delete_reply('141421', '173205')
|
165
|
+
# api.delete_reply(['141421', '173205'])
|
166
|
+
#
|
167
|
+
# Using custom readers:
|
168
|
+
#
|
169
|
+
# response = api.delete_reply('141421', '173205')
|
170
|
+
# response.deleted
|
171
|
+
# # => ['141421', '173205']
|
30
172
|
def delete_reply(*ids)
|
31
|
-
|
173
|
+
ids.flatten!
|
174
|
+
raise TextMagic::API::Error.new(4, 'Insufficient parameters') if ids.empty?
|
175
|
+
response = Executor.execute('delete_reply', @username, @password, :ids => ids.join(','))
|
176
|
+
response.extend(TextMagic::API::Response::DeleteReply)
|
32
177
|
end
|
33
178
|
end
|
34
179
|
end
|
data/lib/charset.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module TextMagic
|
2
|
+
|
3
|
+
class API
|
4
|
+
|
5
|
+
module Charset
|
6
|
+
|
7
|
+
GSM_CHARSET = "@£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞ\e\f^{}\\[~]|€ÆæßÉ !\"#¤%&'()*+,-./0123456789:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà".scan(/./u)
|
8
|
+
|
9
|
+
# Returns +true+ if the supplied text contains only characters from
|
10
|
+
# GSM 03.38 charset, otherwise it returns +false+.
|
11
|
+
def is_gsm(text)
|
12
|
+
text.scan(/./u).each { |c| return false unless GSM_CHARSET.include?(c) }
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns +true+ if the supplied text contains characters outside of
|
17
|
+
# GSM 03.38 charset, otherwise it returns +false+.
|
18
|
+
def is_unicode(text)
|
19
|
+
!is_gsm(text)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/error.rb
CHANGED
@@ -6,8 +6,17 @@ module TextMagic
|
|
6
6
|
|
7
7
|
attr_reader :code, :message
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
# Creates an instance of TextMagic::API::Error. Error code and message
|
10
|
+
# can be supplied as arguments or as a response hash.
|
11
|
+
#
|
12
|
+
# TextMagic::API::Error.new(code, message)
|
13
|
+
# TextMagic::API::Error.new('error_code' => code, 'error_message' => message)
|
14
|
+
def initialize(*args)
|
15
|
+
if args.first.is_a?(Hash)
|
16
|
+
@code, @message = args.first['error_code'], args.first['error_message']
|
17
|
+
else
|
18
|
+
@code, @message = args
|
19
|
+
end
|
11
20
|
end
|
12
21
|
|
13
22
|
def to_s
|
data/lib/executor.rb
CHANGED
@@ -5,12 +5,28 @@ module TextMagic
|
|
5
5
|
class Executor
|
6
6
|
|
7
7
|
include HTTParty
|
8
|
-
base_uri "
|
8
|
+
base_uri "http://www.textmagic.com/app"
|
9
9
|
|
10
|
+
# Executes a command by sending a request to the TextMagic's HTTP
|
11
|
+
# gateway. This is a low-level generic method used by methods in
|
12
|
+
# TextMagic::API class. You should never need to use this method
|
13
|
+
# directly.
|
14
|
+
#
|
15
|
+
# Parameters specified in the +options+ hash will be added to the
|
16
|
+
# HTTP request's URI.
|
17
|
+
#
|
18
|
+
# Returns a hash with values parsed from the server's response if
|
19
|
+
# the command was successfully executed. In case the server replies
|
20
|
+
# with error, this method raises a TextMagic::API::Error.
|
10
21
|
def self.execute(command, username, password, options = {})
|
22
|
+
raise TextMagic::API::Error.new(3, 'Command is undefined') if command.nil? || command.blank?
|
23
|
+
if username.nil? || username.blank? || password.nil? || password.blank?
|
24
|
+
raise TextMagic::API::Error.new(5, 'Invalid username & password combination')
|
25
|
+
end
|
11
26
|
options.merge!(:username => username, :password => password, :cmd => command)
|
27
|
+
options.delete_if { |key, value| key.nil? || key.to_s.blank? || value.nil? || value.to_s.blank? }
|
12
28
|
response = self.get('/api', :query => options, :format => :json)
|
13
|
-
raise Error.new(response) if response['error_code']
|
29
|
+
raise Error.new(response) if response && response['error_code']
|
14
30
|
response
|
15
31
|
end
|
16
32
|
end
|
data/lib/response.rb
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
module TextMagic
|
2
|
+
|
3
|
+
class API
|
4
|
+
|
5
|
+
# Used to cleanup response hash and extend it with custom reader methods.
|
6
|
+
#
|
7
|
+
# === Account response hash
|
8
|
+
#
|
9
|
+
# When extended, it
|
10
|
+
# * converts the +balance+ value to +float+ and
|
11
|
+
# * adds a reader method +balance+.
|
12
|
+
#
|
13
|
+
# === Send response hash
|
14
|
+
#
|
15
|
+
# When extended, it
|
16
|
+
# * inverts the +message_id+ hash and puts it in +message_id_hash+,
|
17
|
+
# * adds an array of ids to +message_ids+,
|
18
|
+
# * adds reader methods +message_id_hash+, +message_ids+, +sent_text+ and
|
19
|
+
# +parts_count+ to the hash.
|
20
|
+
# * adds a reader method +message_id+, which returns a +message_id+ for
|
21
|
+
# a given phone number, or the first message_id if no phone number
|
22
|
+
# is specified.
|
23
|
+
#
|
24
|
+
# === Message status response hash
|
25
|
+
#
|
26
|
+
# When extended, it
|
27
|
+
# * converts the +credits_cost+ value to +float+,
|
28
|
+
# * converts the +created_time+ and +completed_time+ values to +Time+,
|
29
|
+
# * adds reader methods +text+, +status+, +reply_number+, +credits_cost+,
|
30
|
+
# +created_time+ and +completed_time+ to all values of the hash.
|
31
|
+
#
|
32
|
+
# === Receive status response hash
|
33
|
+
#
|
34
|
+
# When extended, it
|
35
|
+
# * converts the +timestamp+ value to +Time+,
|
36
|
+
# * adds reader methods +messages+ and +unread+ to the hash
|
37
|
+
# * adds reader methods +message_id+, +timestamp+, +text+ and +from+
|
38
|
+
# to all members of the +messages+ array.
|
39
|
+
#
|
40
|
+
# === Delete reply response hash
|
41
|
+
#
|
42
|
+
# When extended, it
|
43
|
+
# * adds a reader method +deleted+.
|
44
|
+
module Response
|
45
|
+
|
46
|
+
module Account #:nodoc: all
|
47
|
+
|
48
|
+
def self.extended(base)
|
49
|
+
return unless base.is_a?(Hash)
|
50
|
+
base['balance'] = base['balance'].to_f if base['balance']
|
51
|
+
end
|
52
|
+
|
53
|
+
def balance
|
54
|
+
self['balance']
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
module Send #:nodoc: all
|
59
|
+
|
60
|
+
def self.extended(base)
|
61
|
+
return unless base.is_a?(Hash)
|
62
|
+
base['message_id_hash'] = base.delete('message_id').invert if base['message_id']
|
63
|
+
base['message_ids'] = base['message_id_hash'].values.sort if base['message_id_hash']
|
64
|
+
end
|
65
|
+
|
66
|
+
%w(message_id_hash message_ids sent_text parts_count).each do |method|
|
67
|
+
module_eval <<-EOS
|
68
|
+
def #{method}
|
69
|
+
self['#{method}']
|
70
|
+
end
|
71
|
+
EOS
|
72
|
+
end
|
73
|
+
|
74
|
+
def message_id(phone = nil)
|
75
|
+
phone ? message_id_hash[phone] : message_ids.first
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
module MessageStatus #:nodoc: all
|
80
|
+
|
81
|
+
def self.extended(base)
|
82
|
+
return unless base.is_a?(Hash)
|
83
|
+
base.values.each do |status|
|
84
|
+
status['credits_cost'] = status['credits_cost'].to_f if status['credits_cost']
|
85
|
+
status['created_time'] = Time.at(status['created_time'].to_i) if status['created_time']
|
86
|
+
status['completed_time'] = Time.at(status['completed_time'].to_i) if status['completed_time']
|
87
|
+
status.extend Status
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
module Status
|
92
|
+
|
93
|
+
%w(text status reply_number credits_cost created_time completed_time).each do |method|
|
94
|
+
module_eval <<-EOS
|
95
|
+
def #{method}
|
96
|
+
self['#{method}']
|
97
|
+
end
|
98
|
+
EOS
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
module Receive #:nodoc: all
|
104
|
+
|
105
|
+
def self.extended(base)
|
106
|
+
return unless base.is_a?(Hash) && base['messages']
|
107
|
+
base['messages'].each do |message|
|
108
|
+
message['timestamp'] = Time.at(message['timestamp'].to_i) if message['timestamp']
|
109
|
+
message.extend Message
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
%w(messages unread).each do |method|
|
114
|
+
module_eval <<-EOS, __FILE__, __LINE__ + 1
|
115
|
+
def #{method}
|
116
|
+
self['#{method}']
|
117
|
+
end
|
118
|
+
EOS
|
119
|
+
end
|
120
|
+
|
121
|
+
module Message
|
122
|
+
|
123
|
+
%w(message_id timestamp text from).each do |method|
|
124
|
+
module_eval <<-EOS
|
125
|
+
def #{method}
|
126
|
+
self['#{method}']
|
127
|
+
end
|
128
|
+
EOS
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
module DeleteReply #:nodoc: all
|
134
|
+
|
135
|
+
def deleted
|
136
|
+
self['deleted']
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
data/lib/textmagic.rb
CHANGED
data/lib/validation.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module TextMagic
|
2
|
+
|
3
|
+
class API
|
4
|
+
|
5
|
+
module Validation
|
6
|
+
|
7
|
+
MAX_LENGTH_GSM = [160, 306, 459]
|
8
|
+
MAX_LENGTH_UNICODE = [70, 134, 201]
|
9
|
+
|
10
|
+
# Validates message text length. Returns +true+ if the text length is
|
11
|
+
# within the limits for the unicode/parts combination, otherwise it
|
12
|
+
# returns +false+.
|
13
|
+
#
|
14
|
+
# Note: <em>Maximum lengths for 1, 2 and 3-part GSM 03.38 messages are
|
15
|
+
# 160, 306 and 459 respectively.
|
16
|
+
# Maximum lengths for 1, 2 and 3-part unicode messages are
|
17
|
+
# 70, 134 and 201 respectively.</em>
|
18
|
+
def validate_text_length(text, unicode, parts = 3)
|
19
|
+
max_text_length = (unicode ? MAX_LENGTH_UNICODE : MAX_LENGTH_GSM)[parts - 1]
|
20
|
+
text.size <= max_text_length
|
21
|
+
end
|
22
|
+
|
23
|
+
# Validates a list of phone numbers. Returns +true+ if the list is not empty
|
24
|
+
# and all phone numbers are digit-only strings of maximum length of 15,
|
25
|
+
# otherwise it returns +false+.
|
26
|
+
def validate_phones(*phones)
|
27
|
+
phones.flatten!
|
28
|
+
return false if phones.empty?
|
29
|
+
phones.each { |phone| return false unless phone =~ /^\d{1,15}$/ }
|
30
|
+
true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/test/test_api.rb
CHANGED
@@ -2,19 +2,10 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class APITest < Test::Unit::TestCase
|
4
4
|
|
5
|
-
def prepare_api(command, raw_response, options = {})
|
6
|
-
FakeWeb.allow_net_connect = false
|
7
|
-
|
8
|
-
@username, @password = random_string, random_string
|
9
|
-
uri = build_uri(command, @username, @password, options)
|
10
|
-
FakeWeb.register_uri(:get, uri, :string => raw_response)
|
11
|
-
TextMagic::API.new(@username, @password)
|
12
|
-
end
|
13
|
-
|
14
5
|
context 'Initialization' do
|
15
6
|
|
16
7
|
should 'require username and password' do
|
17
|
-
lambda { TextMagic::API.new }.should raise_error
|
8
|
+
lambda { TextMagic::API.new }.should raise_error(ArgumentError)
|
18
9
|
TextMagic::API.new(random_string, random_string)
|
19
10
|
end
|
20
11
|
end
|
@@ -22,6 +13,7 @@ class APITest < Test::Unit::TestCase
|
|
22
13
|
context 'Account command' do
|
23
14
|
|
24
15
|
setup do
|
16
|
+
@balance = 0.01 * rand(1e4)
|
25
17
|
@username, @password = random_string, random_string
|
26
18
|
@api = TextMagic::API.new(@username, @password)
|
27
19
|
end
|
@@ -31,11 +23,17 @@ class APITest < Test::Unit::TestCase
|
|
31
23
|
@api.account
|
32
24
|
end
|
33
25
|
|
34
|
-
should 'return a hash with
|
35
|
-
TextMagic::API::Executor.expects(:execute).returns({ 'balance' =>
|
26
|
+
should 'return a hash extended with TextMagic::API::Response::Account' do
|
27
|
+
TextMagic::API::Executor.expects(:execute).returns({ 'balance' => @balance.to_s })
|
36
28
|
response = @api.account
|
37
29
|
response.class.should == Hash
|
38
|
-
response
|
30
|
+
response.is_a?(TextMagic::API::Response::Account).should == true
|
31
|
+
end
|
32
|
+
|
33
|
+
should 'return a hash with balance value' do
|
34
|
+
TextMagic::API::Executor.expects(:execute).returns({ 'balance' => @balance.to_s })
|
35
|
+
response = @api.account
|
36
|
+
response['balance'].should be_close(@balance, 1e-10)
|
39
37
|
end
|
40
38
|
end
|
41
39
|
|
@@ -45,31 +43,80 @@ class APITest < Test::Unit::TestCase
|
|
45
43
|
@username, @password = random_string, random_string
|
46
44
|
@text, @phone = random_string, random_phone
|
47
45
|
@api = TextMagic::API.new(@username, @password)
|
46
|
+
TextMagic::API::Executor.stubs(:execute)
|
48
47
|
end
|
49
48
|
|
50
49
|
should 'call Executor execute with correct arguments' do
|
51
|
-
TextMagic::API::Executor.expects(:execute).with('send', @username, @password, :text => @text, :phone => @phone)
|
50
|
+
TextMagic::API::Executor.expects(:execute).with('send', @username, @password, :text => @text, :phone => @phone, :unicode => 0)
|
52
51
|
@api.send(@text, @phone)
|
53
52
|
end
|
54
53
|
|
55
54
|
should 'join multiple phone numbers supplied as an array' do
|
56
55
|
phones = Array.new(3) { random_phone }
|
57
|
-
TextMagic::API::Executor.expects(:execute).with('send', @username, @password, :text => @text, :phone => phones.join(','))
|
56
|
+
TextMagic::API::Executor.expects(:execute).with('send', @username, @password, :text => @text, :phone => phones.join(','), :unicode => 0)
|
58
57
|
@api.send(@text, phones)
|
59
58
|
end
|
60
59
|
|
61
60
|
should 'join multiple phone numbers supplied as arguments' do
|
62
61
|
phones = Array.new(3) { random_phone }
|
63
|
-
TextMagic::API::Executor.expects(:execute).with('send', @username, @password, :text => @text, :phone => phones.join(','))
|
62
|
+
TextMagic::API::Executor.expects(:execute).with('send', @username, @password, :text => @text, :phone => phones.join(','), :unicode => 0)
|
64
63
|
@api.send(@text, *phones)
|
65
64
|
end
|
66
65
|
|
67
|
-
should '
|
66
|
+
should 'replace true with 1 for unicode' do
|
67
|
+
TextMagic::API::Executor.expects(:execute).with('send', @username, @password, :text => @text, :phone => @phone, :unicode => 1)
|
68
|
+
@api.send(@text, @phone, :unicode => true)
|
69
|
+
end
|
70
|
+
|
71
|
+
should 'set unicode value to 0 if it is not set to by user and text contains only characters from GSM 03.38 charset' do
|
72
|
+
TextMagic::API::Executor.expects(:execute).with('send', @username, @password, :text => @text, :phone => @phone, :unicode => 0).times(2)
|
73
|
+
@api.send(@text, @phone)
|
74
|
+
@api.send(@text, @phone, :unicode => false)
|
75
|
+
end
|
76
|
+
|
77
|
+
should 'raise an error if unicode is set to 0 and text contains characters outside of GSM 03.38 charset' do
|
78
|
+
text = 'Вильма Привет'
|
79
|
+
lambda { @api.send(text, @phone, :unicode => false) }.should raise_error(TextMagic::API::Error)
|
80
|
+
end
|
81
|
+
|
82
|
+
should 'raise an error if unicode value is not valid' do
|
83
|
+
lambda { @api.send(@text, @phone, :unicode => 2 + rand(10)) }.should raise_error(TextMagic::API::Error)
|
84
|
+
lambda { @api.send(@text, @phone, :unicode => random_string) }.should raise_error(TextMagic::API::Error)
|
85
|
+
end
|
86
|
+
|
87
|
+
should 'raise an error if no phone numbers are specified' do
|
88
|
+
lambda { @api.send(@text) }.should raise_error(TextMagic::API::Error)
|
89
|
+
lambda { @api.send(@text, []) }.should raise_error(TextMagic::API::Error)
|
90
|
+
end
|
91
|
+
|
92
|
+
should 'raise an error if format of any of the specified phone numbers is invalid' do
|
93
|
+
TextMagic::API.expects(:validate_phones).returns(false)
|
94
|
+
lambda { @api.send(@text, random_string) }.should raise_error(TextMagic::API::Error)
|
95
|
+
end
|
96
|
+
|
97
|
+
should 'raise an error if text is empty' do
|
98
|
+
lambda { @api.send('', @phone) }.should raise_error(TextMagic::API::Error)
|
99
|
+
end
|
100
|
+
|
101
|
+
should 'raise an error if text is too long' do
|
102
|
+
TextMagic::API.expects(:validate_text_length).returns(false)
|
103
|
+
lambda { @api.send(@text, @phone) }.should raise_error(TextMagic::API::Error)
|
104
|
+
end
|
105
|
+
|
106
|
+
should 'return a hash extended with TextMagic::API::Response::Send' do
|
68
107
|
message_id = random_string
|
69
108
|
TextMagic::API::Executor.expects(:execute).returns({ 'message_id' => { message_id => @phone }, 'sent_text' => @text, 'parts_count' => 1 })
|
70
109
|
response = @api.send(@text, @phone)
|
71
|
-
response
|
72
|
-
response
|
110
|
+
response.class.should == Hash
|
111
|
+
response.is_a?(TextMagic::API::Response::Send).should == true
|
112
|
+
end
|
113
|
+
|
114
|
+
should 'return a hash with message_id_hash, message_ids, sent_text and parts_count values' do
|
115
|
+
message_id = random_string
|
116
|
+
TextMagic::API::Executor.expects(:execute).returns({ 'message_id' => { message_id => @phone }, 'sent_text' => @text, 'parts_count' => 1 })
|
117
|
+
response = @api.send(@text, @phone)
|
118
|
+
response['message_id_hash'].should == { @phone => message_id }
|
119
|
+
response['message_ids'].should == [message_id]
|
73
120
|
response['parts_count'].should == 1
|
74
121
|
end
|
75
122
|
end
|
@@ -99,9 +146,21 @@ class APITest < Test::Unit::TestCase
|
|
99
146
|
@api.message_status(*ids)
|
100
147
|
end
|
101
148
|
|
149
|
+
should 'not call execute and should raise an exception if no ids are specified' do
|
150
|
+
TextMagic::API::Executor.expects(:execute).never
|
151
|
+
lambda { @api.message_status }.should raise_error(TextMagic::API::Error)
|
152
|
+
end
|
153
|
+
|
154
|
+
should 'return a hash extended with TextMagic::API::Response::MessageStatus' do
|
155
|
+
TextMagic::API::Executor.expects(:execute).returns({ '8659912' => {} })
|
156
|
+
response = @api.message_status(random_string)
|
157
|
+
response.class.should == Hash
|
158
|
+
response.is_a?(TextMagic::API::Response::MessageStatus).should == true
|
159
|
+
end
|
160
|
+
|
102
161
|
should 'return a hash with message ids as keys' do
|
103
162
|
TextMagic::API::Executor.expects(:execute).returns({ '8659912' => {} })
|
104
|
-
response = @api.message_status
|
163
|
+
response = @api.message_status(random_string)
|
105
164
|
response['8659912'].should == {}
|
106
165
|
end
|
107
166
|
end
|
@@ -114,11 +173,24 @@ class APITest < Test::Unit::TestCase
|
|
114
173
|
end
|
115
174
|
|
116
175
|
should 'call Executor execute with correct arguments' do
|
117
|
-
TextMagic::API::Executor.expects(:execute).with('receive', @username, @password)
|
176
|
+
TextMagic::API::Executor.expects(:execute).with('receive', @username, @password, :last_retrieved_id => nil)
|
118
177
|
@api.receive
|
119
178
|
end
|
120
179
|
|
121
|
-
should '
|
180
|
+
should 'accept last_retrieved_id optional value' do
|
181
|
+
last_retrieved_id = rand(1e10)
|
182
|
+
TextMagic::API::Executor.expects(:execute).with('receive', @username, @password, :last_retrieved_id => last_retrieved_id)
|
183
|
+
@api.receive(last_retrieved_id)
|
184
|
+
end
|
185
|
+
|
186
|
+
should 'return a hash extended with TextMagic::API::Response::Receive' do
|
187
|
+
TextMagic::API::Executor.expects(:execute).returns({ 'messages' => [], 'unread' => 0 })
|
188
|
+
response = @api.receive
|
189
|
+
response.class.should == Hash
|
190
|
+
response.is_a?(TextMagic::API::Response::Receive).should == true
|
191
|
+
end
|
192
|
+
|
193
|
+
should 'return a hash with unread and messages values' do
|
122
194
|
TextMagic::API::Executor.expects(:execute).returns({ 'messages' => [], 'unread' => 0 })
|
123
195
|
response = @api.receive
|
124
196
|
response['unread'].should == 0
|
@@ -151,42 +223,24 @@ class APITest < Test::Unit::TestCase
|
|
151
223
|
@api.delete_reply(*ids)
|
152
224
|
end
|
153
225
|
|
154
|
-
should '
|
226
|
+
should 'not call execute and should raise an exception if no ids are specified' do
|
227
|
+
TextMagic::API::Executor.expects(:execute).never
|
228
|
+
lambda { @api.delete_reply }.should raise_error(TextMagic::API::Error)
|
229
|
+
end
|
230
|
+
|
231
|
+
should 'return a hash extended with TextMagic::API::Response::DeleteReply' do
|
155
232
|
ids = Array.new(3) { random_string }
|
156
233
|
TextMagic::API::Executor.expects(:execute).returns({ 'deleted' => ids })
|
157
|
-
response = @api.
|
158
|
-
response
|
234
|
+
response = @api.delete_reply(ids)
|
235
|
+
response.class.should == Hash
|
236
|
+
response.is_a?(TextMagic::API::Response::DeleteReply).should == true
|
237
|
+
end
|
238
|
+
|
239
|
+
should 'return a hash with deleted value' do
|
240
|
+
ids = Array.new(3) { random_string }
|
241
|
+
TextMagic::API::Executor.expects(:execute).returns({ 'deleted' => ids })
|
242
|
+
response = @api.delete_reply(ids)
|
243
|
+
response.deleted.should == ids
|
159
244
|
end
|
160
245
|
end
|
161
246
|
end
|
162
|
-
|
163
|
-
__END__
|
164
|
-
|
165
|
-
Example responses
|
166
|
-
|
167
|
-
account:
|
168
|
-
{"balance":"100"}
|
169
|
-
|
170
|
-
send:
|
171
|
-
{"message_id":{"1234567":"444444123456"},"sent_text":"test","parts_count":1}
|
172
|
-
|
173
|
-
message_status:
|
174
|
-
{"8659912":{"text":"test","status":"d","created_time":"1242979818","reply_number":"447624800500","completed_time":null,"credits_cost":"0.5"},"8659914":{"text":"test","status":"d","created_time":"1242979839","reply_number":"447624800500","completed_time":null,"credits_cost":"0.5"}}
|
175
|
-
|
176
|
-
receive (empty):
|
177
|
-
{"messages":[],"unread":0}
|
178
|
-
|
179
|
-
empty message:
|
180
|
-
{"error_code":1,"error_message":"Messages text is empty"}
|
181
|
-
|
182
|
-
insufficient parameters:
|
183
|
-
{"error_code":4,"error_message":"Insufficient parameters"}
|
184
|
-
|
185
|
-
invalid credentials:
|
186
|
-
{"error_code":5,"error_message":"Invalid username & password combination"}
|
187
|
-
|
188
|
-
invalid phone number format:
|
189
|
-
{"error_code":9,"error_message":"Wrong phone number format"}
|
190
|
-
|
191
|
-
invalid message_id:
|
192
|
-
{"error_code":14,"error_message":"Message with id 8659913 does not exist"}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class CharsetTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context 'is_gsm method' do
|
7
|
+
|
8
|
+
should 'return true if all characters are in GSM 03.38 charset' do
|
9
|
+
TextMagic::API.is_gsm(('a'..'z').to_a.join).should == true
|
10
|
+
TextMagic::API.is_gsm(('A'..'Z').to_a.join).should == true
|
11
|
+
TextMagic::API.is_gsm(('0'..'9').to_a.join).should == true
|
12
|
+
TextMagic::API.is_gsm("@£$¥€").should == true
|
13
|
+
TextMagic::API.is_gsm("\n\r\e\f\\\"").should == true
|
14
|
+
TextMagic::API.is_gsm("èéùìòÇØøÅåÉÆæß").should == true
|
15
|
+
TextMagic::API.is_gsm("ΔΦΓΛΩΠΨΣΘΞ").should == true
|
16
|
+
TextMagic::API.is_gsm("^{}[~]| !#¤%&'()").should == true
|
17
|
+
TextMagic::API.is_gsm("*+,-./_:;<=>?¡¿§").should == true
|
18
|
+
TextMagic::API.is_gsm("ÖÑÜöñüàäÄ").should == true
|
19
|
+
end
|
20
|
+
|
21
|
+
should 'return false if some characters are outside of GSM 03.38 charset' do
|
22
|
+
TextMagic::API.is_gsm('Arabic: مرحبا فيلما').should == false
|
23
|
+
TextMagic::API.is_gsm('Chinese: 您好').should == false
|
24
|
+
TextMagic::API.is_gsm('Cyrilic: Вильма Привет').should == false
|
25
|
+
TextMagic::API.is_gsm('Thai: สวัสดี').should == false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/test/test_error.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ErrorTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context 'Initialization' do
|
6
|
+
|
7
|
+
setup do
|
8
|
+
@code = rand(1e3)
|
9
|
+
@message = random_string
|
10
|
+
end
|
11
|
+
|
12
|
+
should 'accept a hash with error_code and error_message' do
|
13
|
+
e = TextMagic::API::Error.new('error_code' => @code, 'error_message' => @message)
|
14
|
+
e.code.should == @code
|
15
|
+
e.message.should == @message
|
16
|
+
end
|
17
|
+
|
18
|
+
should 'accept error_code and error_message' do
|
19
|
+
e = TextMagic::API::Error.new(@code, @message)
|
20
|
+
e.code.should == @code
|
21
|
+
e.message.should == @message
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/test/test_executor.rb
CHANGED
@@ -13,12 +13,45 @@ class ExecutorTest < Test::Unit::TestCase
|
|
13
13
|
@uri = build_uri(@command, @username, @password, @options)
|
14
14
|
end
|
15
15
|
|
16
|
+
should 'not send HTTP request without command' do
|
17
|
+
TextMagic::API::Executor.expects(:get).never
|
18
|
+
lambda {
|
19
|
+
TextMagic::API::Executor.execute(nil, @username, @password, @options)
|
20
|
+
}.should raise_error(TextMagic::API::Error)
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'not send HTTP request without username' do
|
24
|
+
TextMagic::API::Executor.expects(:get).never
|
25
|
+
lambda {
|
26
|
+
TextMagic::API::Executor.execute(@command, nil, @password, @options)
|
27
|
+
}.should raise_error(TextMagic::API::Error)
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'not send HTTP request without password' do
|
31
|
+
TextMagic::API::Executor.expects(:get).never
|
32
|
+
lambda {
|
33
|
+
TextMagic::API::Executor.execute(@command, @username, nil, @options)
|
34
|
+
}.should raise_error(TextMagic::API::Error)
|
35
|
+
end
|
36
|
+
|
16
37
|
should 'send a GET request to proper uri' do
|
17
38
|
response = random_string
|
18
39
|
FakeWeb.register_uri(:get, @uri, :string => response)
|
19
40
|
TextMagic::API::Executor.execute(@command, @username, @password, @options)
|
20
41
|
end
|
21
42
|
|
43
|
+
should 'not send parameters with empty keys' do
|
44
|
+
options_with_empty_values = @options.merge(nil => random_string, '' => random_string)
|
45
|
+
TextMagic::API::Executor.expects(:get).with('/api', :query => @options, :format => :json)
|
46
|
+
TextMagic::API::Executor.execute(@command, @username, @password, options_with_empty_values)
|
47
|
+
end
|
48
|
+
|
49
|
+
should 'not send parameters with empty values' do
|
50
|
+
options_with_empty_values = @options.merge(random_string => nil, random_string => '')
|
51
|
+
TextMagic::API::Executor.expects(:get).with('/api', :query => @options, :format => :json)
|
52
|
+
TextMagic::API::Executor.execute(@command, @username, @password, options_with_empty_values)
|
53
|
+
end
|
54
|
+
|
22
55
|
should 'raise an error if the response contains error_code' do
|
23
56
|
response = "{error_code:#{1 + rand(10)}}"
|
24
57
|
FakeWeb.register_uri(:get, @uri, :string => response)
|
@@ -27,7 +60,7 @@ class ExecutorTest < Test::Unit::TestCase
|
|
27
60
|
}.should raise_error(TextMagic::API::Error)
|
28
61
|
end
|
29
62
|
|
30
|
-
should 'return a hash with values
|
63
|
+
should 'return a hash with values from the response' do
|
31
64
|
hash = random_hash
|
32
65
|
FakeWeb.register_uri(:get, @uri, :string => hash.to_json)
|
33
66
|
response = TextMagic::API::Executor.execute(@command, @username, @password, @options)
|
data/test/test_helper.rb
CHANGED
@@ -14,7 +14,7 @@ class Test::Unit::TestCase
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def random_string(legth = 5)
|
17
|
-
rand(36
|
17
|
+
Array.new(legth) { rand(36).to_s(36) }.join
|
18
18
|
end
|
19
19
|
|
20
20
|
def random_phone
|
@@ -29,7 +29,7 @@ end
|
|
29
29
|
|
30
30
|
def build_uri(command, username, password, options = {})
|
31
31
|
options.merge!(:cmd => command, :username => username, :password => password)
|
32
|
-
uri = "
|
32
|
+
uri = "http://www.textmagic.com/app/api?"
|
33
33
|
uri << options.collect { |key, value| "#{key}=#{value}"}.join('&')
|
34
34
|
end
|
35
35
|
|
@@ -0,0 +1,176 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ResponseTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context 'Account response' do
|
6
|
+
|
7
|
+
setup do
|
8
|
+
@balance = 0.1 * rand(1e4)
|
9
|
+
@response = { 'balance' => @balance.to_s }
|
10
|
+
@response.extend TextMagic::API::Response::Account
|
11
|
+
end
|
12
|
+
|
13
|
+
should 'allow access to balance' do
|
14
|
+
@response.balance.should be_close(@balance, 1e-10)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'Send response' do
|
19
|
+
|
20
|
+
setup do
|
21
|
+
@message_id = {
|
22
|
+
'141421' => '999314159265',
|
23
|
+
'173205' => '999271828182'
|
24
|
+
}
|
25
|
+
@text = random_string
|
26
|
+
@parts_count = rand(10)
|
27
|
+
@response = {
|
28
|
+
'message_id' => @message_id,
|
29
|
+
'sent_text' => @text,
|
30
|
+
'parts_count' => @parts_count
|
31
|
+
}
|
32
|
+
@response.extend TextMagic::API::Response::Send
|
33
|
+
end
|
34
|
+
|
35
|
+
should 'allow access to inverted message_id hash' do
|
36
|
+
@response.message_id_hash.should == @message_id.invert
|
37
|
+
end
|
38
|
+
|
39
|
+
should 'allow access to message_ids array' do
|
40
|
+
@response.message_ids.should == ['141421', '173205']
|
41
|
+
end
|
42
|
+
|
43
|
+
should 'allow access to message_id for a given phone number' do
|
44
|
+
@response.message_id('999314159265').should == '141421'
|
45
|
+
@response.message_id('999271828182').should == '173205'
|
46
|
+
end
|
47
|
+
|
48
|
+
should 'allow access to sent_text' do
|
49
|
+
@response.sent_text.should == @text
|
50
|
+
end
|
51
|
+
|
52
|
+
should 'allow access to parts_count' do
|
53
|
+
@response.parts_count.should == @parts_count
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'MessageStatus response' do
|
58
|
+
|
59
|
+
setup do
|
60
|
+
@text = random_string
|
61
|
+
@reply_number = random_phone
|
62
|
+
@created_time = (Time.now - 30).to_i
|
63
|
+
@completed_time = (Time.now - 20).to_i
|
64
|
+
@credits_cost = 0.01 * rand(300)
|
65
|
+
@response = {
|
66
|
+
'141421' => {
|
67
|
+
'text' => @text,
|
68
|
+
'status' => 'd',
|
69
|
+
'created_time' => @created_time,
|
70
|
+
'reply_number' => @reply_number,
|
71
|
+
'completed_time' => @completed_time,
|
72
|
+
'credits_cost' => @credits_cost
|
73
|
+
},
|
74
|
+
'173205' => {
|
75
|
+
'text' => 'test',
|
76
|
+
'status' => 'r',
|
77
|
+
'created_time' => '1242979839',
|
78
|
+
'reply_number' => '447624800500',
|
79
|
+
'completed_time' => nil,
|
80
|
+
'credits_cost' => 0.5
|
81
|
+
}
|
82
|
+
}
|
83
|
+
@response.extend TextMagic::API::Response::MessageStatus
|
84
|
+
end
|
85
|
+
|
86
|
+
should 'allow access to text for all statuses' do
|
87
|
+
@response['141421'].text.should == @text
|
88
|
+
@response['173205'].text.should == 'test'
|
89
|
+
end
|
90
|
+
|
91
|
+
should 'allow access to status for a given message_id' do
|
92
|
+
@response['141421'].status.should == 'd'
|
93
|
+
@response['173205'].status.should == 'r'
|
94
|
+
end
|
95
|
+
|
96
|
+
should 'allow access to reply_number for a given message_id' do
|
97
|
+
@response['141421'].reply_number.should == @reply_number
|
98
|
+
@response['173205'].reply_number.should == '447624800500'
|
99
|
+
end
|
100
|
+
|
101
|
+
should 'allow access to created_time for a given message_id' do
|
102
|
+
@response['141421'].created_time.should == Time.at(@created_time)
|
103
|
+
@response['173205'].created_time.should == Time.at(1242979839)
|
104
|
+
end
|
105
|
+
|
106
|
+
should 'allow access to completed_time for a given message_id' do
|
107
|
+
@response['141421'].completed_time.should == Time.at(@completed_time)
|
108
|
+
@response['173205'].completed_time.should == nil
|
109
|
+
end
|
110
|
+
|
111
|
+
should 'allow access to credits_cost for a given message_id' do
|
112
|
+
@response['141421'].credits_cost.should be_close(@credits_cost, 1e-10)
|
113
|
+
@response['173205'].credits_cost.should be_close(0.5, 1e-10)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'Receive response' do
|
118
|
+
|
119
|
+
setup do
|
120
|
+
@timestamp = (Time.now - 30).to_i
|
121
|
+
@message1 = {
|
122
|
+
'timestamp' => @timestamp,
|
123
|
+
'from' => '999314159265',
|
124
|
+
'text' => 'Hi Fred',
|
125
|
+
'message_id' => '141421'
|
126
|
+
}
|
127
|
+
@message2 = {
|
128
|
+
'timestamp' => 1243244148,
|
129
|
+
'from' => '999271828182',
|
130
|
+
'text' => 'Hello buddy',
|
131
|
+
'message_id' => '173205'
|
132
|
+
}
|
133
|
+
@messages = [@message1, @message2]
|
134
|
+
@unread = rand(1e4)
|
135
|
+
@response = { 'unread' => @unread, 'messages' => @messages }
|
136
|
+
@response.extend TextMagic::API::Response::Receive
|
137
|
+
end
|
138
|
+
|
139
|
+
should 'allow access to unread' do
|
140
|
+
@response.unread.should == @unread
|
141
|
+
end
|
142
|
+
|
143
|
+
should 'allow access to messages array' do
|
144
|
+
@response.messages.should == @messages
|
145
|
+
end
|
146
|
+
|
147
|
+
should 'allow access to message_id for all messages' do
|
148
|
+
@response.messages.first.message_id.should == '141421'
|
149
|
+
end
|
150
|
+
|
151
|
+
should 'allow access to timestamp for all messages' do
|
152
|
+
@response.messages.first.timestamp.should == Time.at(@timestamp)
|
153
|
+
end
|
154
|
+
|
155
|
+
should 'allow access to from for all messages' do
|
156
|
+
@response.messages.first.from.should == '999314159265'
|
157
|
+
end
|
158
|
+
|
159
|
+
should 'allow access to text for all messages' do
|
160
|
+
@response.messages.first.text.should == 'Hi Fred'
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context 'DeleteReply response' do
|
165
|
+
|
166
|
+
setup do
|
167
|
+
@ids = ['141421', '1780826']
|
168
|
+
@response = { 'deleted' => @ids }
|
169
|
+
@response.extend TextMagic::API::Response::DeleteReply
|
170
|
+
end
|
171
|
+
|
172
|
+
should 'allow access to deleted' do
|
173
|
+
@response.deleted.should == @ids
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class ValidationTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context 'validate_text_length method for non-unicode texts' do
|
7
|
+
|
8
|
+
should 'return true if parts limit is set to 1 and text length is less than or equal to 160' do
|
9
|
+
TextMagic::API.validate_text_length(random_string(160), false, 1).should == true
|
10
|
+
end
|
11
|
+
|
12
|
+
should 'return false if parts limit is set to 1 and text length is greater than 160' do
|
13
|
+
TextMagic::API.validate_text_length(random_string(161), false, 1).should == false
|
14
|
+
end
|
15
|
+
|
16
|
+
should 'return true if parts limit is set to 2 and text length is less than or equal to 306' do
|
17
|
+
TextMagic::API.validate_text_length(random_string(306), false, 2).should == true
|
18
|
+
end
|
19
|
+
|
20
|
+
should 'return false if parts limit is set to 2 and text length is greater than 306' do
|
21
|
+
TextMagic::API.validate_text_length(random_string(307), false, 2).should == false
|
22
|
+
end
|
23
|
+
|
24
|
+
should 'return true if parts limit is set to 3 or is not specified and text length is less than or equal to 459' do
|
25
|
+
TextMagic::API.validate_text_length(random_string(459), false).should == true
|
26
|
+
TextMagic::API.validate_text_length(random_string(459), false, 3).should == true
|
27
|
+
end
|
28
|
+
|
29
|
+
should 'return false if parts limit is set to 3 or is not specified and text length is greater than 459' do
|
30
|
+
TextMagic::API.validate_text_length(random_string(460), false).should == false
|
31
|
+
TextMagic::API.validate_text_length(random_string(460), false, 3).should == false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'validate_text_length method for unicode texts' do
|
36
|
+
|
37
|
+
should 'return true if parts limit is set to 1 and text length is less than or equal to 70' do
|
38
|
+
TextMagic::API.validate_text_length(random_string(70), true, 1).should == true
|
39
|
+
end
|
40
|
+
|
41
|
+
should 'return false if parts limit is set to 1 and text length is greater than 70' do
|
42
|
+
TextMagic::API.validate_text_length(random_string(71), true, 1).should == false
|
43
|
+
end
|
44
|
+
|
45
|
+
should 'return true if parts limit is set to 2 and text length is less than or equal to 134' do
|
46
|
+
TextMagic::API.validate_text_length(random_string(134), true, 2).should == true
|
47
|
+
end
|
48
|
+
|
49
|
+
should 'return false if parts limit is set to 2 and text length is greater than 134' do
|
50
|
+
TextMagic::API.validate_text_length(random_string(135), true, 2).should == false
|
51
|
+
end
|
52
|
+
|
53
|
+
should 'return true if parts limit is set to 3 or is not specified and text length is less than or equal to 201' do
|
54
|
+
TextMagic::API.validate_text_length(random_string(201), true).should == true
|
55
|
+
TextMagic::API.validate_text_length(random_string(201), true, 3).should == true
|
56
|
+
end
|
57
|
+
|
58
|
+
should 'return false if parts limit is set to 3 or is not specified and text length is greater than 201' do
|
59
|
+
TextMagic::API.validate_text_length(random_string(202), true).should == false
|
60
|
+
TextMagic::API.validate_text_length(random_string(202), true, 3).should == false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'validate_phones method' do
|
65
|
+
|
66
|
+
should 'return true if phone number consists of up to 15 digits' do
|
67
|
+
TextMagic::API.validate_phones(rand(10 ** 15).to_s).should == true
|
68
|
+
end
|
69
|
+
|
70
|
+
should 'return false if phone number is longer than 15 digits' do
|
71
|
+
TextMagic::API.validate_phones((10 ** 16 + rand(10 ** 15)).to_s).should == false
|
72
|
+
end
|
73
|
+
|
74
|
+
should 'return false if phone number contains non-digits' do
|
75
|
+
TextMagic::API.validate_phones(random_string).should == false
|
76
|
+
end
|
77
|
+
|
78
|
+
should 'return false if phone number is empty' do
|
79
|
+
TextMagic::API.validate_phones('').should == false
|
80
|
+
end
|
81
|
+
|
82
|
+
should 'return true if all phone numbers in a list are valid' do
|
83
|
+
phone1, phone2 = rand(10 ** 15).to_s, rand(10 ** 15).to_s
|
84
|
+
TextMagic::API.validate_phones(phone1, phone2).should == true
|
85
|
+
TextMagic::API.validate_phones([phone1, phone2]).should == true
|
86
|
+
end
|
87
|
+
|
88
|
+
should 'return false if phone numbers list is empty' do
|
89
|
+
TextMagic::API.validate_phones().should == false
|
90
|
+
end
|
91
|
+
|
92
|
+
should 'return false if format of any of phone numbers in a list is invalid' do
|
93
|
+
phone1 = rand(10 ** 15).to_s, rand(10 ** 15).to_s
|
94
|
+
phone2 = random_string
|
95
|
+
TextMagic::API.validate_phones(phone1, phone2).should == false
|
96
|
+
TextMagic::API.validate_phones([phone1, phone2]).should == false
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/textmagic.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{textmagic}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.2.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Vladimir Bobes Tuzinsky"]
|
9
|
-
s.date = %q{2009-05-
|
9
|
+
s.date = %q{2009-05-25}
|
10
10
|
s.email = %q{vladimir.tuzinsky@gmail.com}
|
11
11
|
s.extra_rdoc_files = [
|
12
12
|
"LICENSE",
|
@@ -20,13 +20,19 @@ Gem::Specification.new do |s|
|
|
20
20
|
"Rakefile",
|
21
21
|
"VERSION.yml",
|
22
22
|
"lib/api.rb",
|
23
|
+
"lib/charset.rb",
|
23
24
|
"lib/error.rb",
|
24
25
|
"lib/executor.rb",
|
26
|
+
"lib/response.rb",
|
25
27
|
"lib/textmagic.rb",
|
28
|
+
"lib/validation.rb",
|
26
29
|
"test/test_api.rb",
|
30
|
+
"test/test_charset.rb",
|
31
|
+
"test/test_error.rb",
|
27
32
|
"test/test_executor.rb",
|
28
33
|
"test/test_helper.rb",
|
29
|
-
"test/
|
34
|
+
"test/test_response.rb",
|
35
|
+
"test/test_validation.rb",
|
30
36
|
"textmagic.gemspec"
|
31
37
|
]
|
32
38
|
s.has_rdoc = true
|
@@ -38,9 +44,12 @@ Gem::Specification.new do |s|
|
|
38
44
|
s.summary = %q{Ruby interface to the TextMagic's SMS gateway}
|
39
45
|
s.test_files = [
|
40
46
|
"test/test_api.rb",
|
47
|
+
"test/test_charset.rb",
|
48
|
+
"test/test_error.rb",
|
41
49
|
"test/test_executor.rb",
|
42
50
|
"test/test_helper.rb",
|
43
|
-
"test/
|
51
|
+
"test/test_response.rb",
|
52
|
+
"test/test_validation.rb"
|
44
53
|
]
|
45
54
|
|
46
55
|
if s.respond_to? :specification_version then
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bobes-textmagic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Bobes Tuzinsky
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-05-
|
12
|
+
date: 2009-05-25 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -30,13 +30,19 @@ files:
|
|
30
30
|
- Rakefile
|
31
31
|
- VERSION.yml
|
32
32
|
- lib/api.rb
|
33
|
+
- lib/charset.rb
|
33
34
|
- lib/error.rb
|
34
35
|
- lib/executor.rb
|
36
|
+
- lib/response.rb
|
35
37
|
- lib/textmagic.rb
|
38
|
+
- lib/validation.rb
|
36
39
|
- test/test_api.rb
|
40
|
+
- test/test_charset.rb
|
41
|
+
- test/test_error.rb
|
37
42
|
- test/test_executor.rb
|
38
43
|
- test/test_helper.rb
|
39
|
-
- test/
|
44
|
+
- test/test_response.rb
|
45
|
+
- test/test_validation.rb
|
40
46
|
- textmagic.gemspec
|
41
47
|
has_rdoc: true
|
42
48
|
homepage: http://github.com/bobes/textmagic
|
@@ -66,6 +72,9 @@ specification_version: 2
|
|
66
72
|
summary: Ruby interface to the TextMagic's SMS gateway
|
67
73
|
test_files:
|
68
74
|
- test/test_api.rb
|
75
|
+
- test/test_charset.rb
|
76
|
+
- test/test_error.rb
|
69
77
|
- test/test_executor.rb
|
70
78
|
- test/test_helper.rb
|
71
|
-
- test/
|
79
|
+
- test/test_response.rb
|
80
|
+
- test/test_validation.rb
|
data/test/test_textmagic.rb
DELETED