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 CHANGED
@@ -1,6 +1,39 @@
1
- = textmagic
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
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 0
3
- :minor: 1
3
+ :minor: 2
4
4
  :patch: 0
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['balance'] = response['balance'].to_f
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
- phones = args.flatten.join(',')
19
- Executor.execute('send', @username, @password, options.merge(:text => text, :phone => phones))
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
- Executor.execute('message_status', @username, @password, :ids => ids.flatten.join(','))
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
- def receive
27
- Executor.execute('receive', @username, @password)
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
- Executor.execute('delete_reply', @username, @password, :ids => ids.flatten.join(','))
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
- def initialize(response)
10
- @code, @message = response[:error_code], response[:error_message]
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 "https://www.textmagic.com/app"
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
@@ -1,9 +1,12 @@
1
1
  require 'rubygems'
2
2
  gem 'httparty'
3
3
  require 'httparty'
4
+ require 'charset'
5
+ require 'validation'
4
6
  require 'api'
7
+ require 'response'
5
8
  require 'executor'
6
9
  require 'error'
7
10
 
8
- module TextMagic
11
+ module TextMagic #:nodoc:
9
12
  end
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 numeric balance value' do
35
- TextMagic::API::Executor.expects(:execute).returns({ 'balance' => '3.14' })
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['balance'].should == 3.14
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 'return a hash with message_id, sent_text and parts_count' do
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['message_id'].should == { message_id => @phone }
72
- response['sent_text'].should == @text
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 'return a hash with messages and number of unread messages' do
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 'return a hash with deleted ids' do
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.receive
158
- response['deleted'].should == ids
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
@@ -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
@@ -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 in the response' do
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 ** legth).to_s(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 = "https://www.textmagic.com:443/app/api?"
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.1.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-22}
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/test_textmagic.rb",
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/test_textmagic.rb"
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.1.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-22 00:00:00 -07:00
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/test_textmagic.rb
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/test_textmagic.rb
79
+ - test/test_response.rb
80
+ - test/test_validation.rb
@@ -1,4 +0,0 @@
1
- require 'test_helper'
2
-
3
- # class TextmagicTest < Test::Unit::TestCase
4
- # end