bobes-textmagic 0.1.0 → 0.2.0
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/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