esendex 0.1.1 → 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/lib/esendex.rb CHANGED
@@ -1,9 +1,46 @@
1
1
  module Esendex
2
- require 'esendex/account'
3
- require 'esendex/message'
4
- require 'esendex/exceptions'
5
- require 'esendex/message_batch_submission'
6
- require 'esendex/version'
2
+ require_relative 'esendex/version'
3
+ require_relative 'esendex/api_connection'
4
+ require_relative 'esendex/account'
5
+ require_relative 'esendex/message'
6
+ require_relative 'esendex/exceptions'
7
+ require_relative 'esendex/message_batch_submission'
7
8
 
9
+ require_relative 'esendex/railtie' if defined?(Rails)
10
+
8
11
  API_NAMESPACE = 'http://api.esendex.com/ns/'
12
+ API_HOST = 'https://api.esendex.com'
13
+ API_VERSION = 'v1.0'
14
+
15
+ def self.configure
16
+ yield self if block_given?
17
+
18
+ unless Esendex.username
19
+ raise StandardError.new("username required. Either set Esendex.username or set environment variable ESENDEX_USERNAME")
20
+ end
21
+
22
+ unless Esendex.password
23
+ raise StandardError.new("password required. Either set Esendex.password or set environment variable ESENDEX_PASSWORD")
24
+ end
25
+ end
26
+
27
+ class << self
28
+ attr_writer :account_reference, :username, :password
29
+
30
+ def account_reference
31
+ @account_reference ||= ENV['ESENDEX_ACCOUNT']
32
+ end
33
+
34
+ def username
35
+ @username ||= ENV['ESENDEX_USERNAME']
36
+ end
37
+
38
+ def password
39
+ @password ||= ENV['ESENDEX_PASSWORD']
40
+ end
41
+ end
42
+
43
+ def self.user_agent
44
+ "EsendexRubyGem/#{Esendex::VERSION}"
45
+ end
9
46
  end
@@ -3,47 +3,34 @@ require 'nokogiri'
3
3
 
4
4
  module Esendex
5
5
  class Account
6
- attr_accessor :account_reference, :username, :password
7
- attr_reader :messages_remaining
6
+ attr_accessor :reference
8
7
 
9
- def initialize(account_reference, username, password, connection = Nestful::Connection.new('http://api.esendex.com'))
10
- @account_reference = account_reference
11
- @username = username
12
- @password = password
13
-
14
- @connection = connection
15
- @connection.user = @username
16
- @connection.password = @password
17
- @connection.auth_type = :basic
18
-
19
- begin
20
- response = @connection.get "/v0.1/accounts/#{@account_reference}", default_headers
21
- doc = Nokogiri::XML(response.body)
22
- @messages_remaining = doc.at_xpath('//api:accounts/api:account/api:messagesremaining', 'api' => Esendex::API_NAMESPACE).content.to_i
23
- rescue Exception => exception
24
- raise ApiErrorFactory.new.get_api_error(exception)
25
- end
8
+ def initialize(account_reference = Esendex.account_reference)
9
+ @reference = account_reference
26
10
  end
27
11
 
28
- def default_headers
29
- {"User-Agent" => "Esendex Gem #{Esendex::Version::STRING}"}
12
+ def api_connection
13
+ @api_connection ||= ApiConnection.new
30
14
  end
31
-
32
- def send_message(message)
33
- self.send_messages([message])
15
+
16
+ def messages_remaining
17
+ response = api_connection.get "/v1.0/accounts/#{@reference}"
18
+ doc = Nokogiri::XML(response.body)
19
+ doc.at_xpath('//api:accounts/api:account/api:messagesremaining', 'api' => Esendex::API_NAMESPACE).content.to_i
20
+ end
21
+
22
+ def send_message(args={})
23
+ raise ArgumentError.new(":to required") unless args[:to]
24
+ raise ArgumentError.new(":body required") unless args[:body]
25
+
26
+ send_messages([Message.new(args[:to], args[:body], args[:from])])
34
27
  end
35
28
 
36
29
  def send_messages(messages)
37
-
38
- batch_submission = MessageBatchSubmission.new(@account_reference, messages)
39
-
40
- begin
41
- response = @connection.post "/v1.0/messagedispatcher", batch_submission.to_s, default_headers
42
- doc = Nokogiri::XML(response.body)
43
- doc.at_xpath('//api:messageheaders', 'api' => Esendex::API_NAMESPACE)['batchid']
44
- rescue Exception => exception
45
- raise ApiErrorFactory.new.get_api_error(exception)
46
- end
30
+ batch_submission = MessageBatchSubmission.new(@reference, messages)
31
+ response = api_connection.post "/v1.0/messagedispatcher", batch_submission.to_s
32
+ doc = Nokogiri::XML(response.body)
33
+ doc.at_xpath('//api:messageheaders', 'api' => Esendex::API_NAMESPACE)['batchid']
47
34
  end
48
35
 
49
36
  end
@@ -0,0 +1,28 @@
1
+ require 'nestful'
2
+
3
+ class ApiConnection
4
+
5
+ def initialize
6
+ @connection = Nestful::Connection.new(Esendex::API_HOST)
7
+ @connection.user = Esendex.username
8
+ @connection.password = Esendex.password
9
+ @connection.auth_type = :basic
10
+ end
11
+
12
+ def default_headers
13
+ { 'User-Agent' => Esendex.user_agent }
14
+ end
15
+
16
+ def get(url)
17
+ @connection.get url, default_headers
18
+ rescue => e
19
+ raise ApiErrorFactory.new.get_api_error(e)
20
+ end
21
+
22
+ def post(url, body)
23
+ @connection.post url, body, default_headers
24
+ rescue => e
25
+ raise ApiErrorFactory.new.get_api_error(e)
26
+ end
27
+
28
+ end
@@ -11,25 +11,25 @@ module Esendex
11
11
  class Message
12
12
  attr_accessor :to, :body, :from
13
13
 
14
- def initialize(to, body)
15
- self.to = to
16
- self.body = body
14
+ def initialize(to, body, from=nil)
15
+ @to = to
16
+ @body = body
17
17
  end
18
18
 
19
19
  def xml_node
20
20
  doc = Nokogiri::XML('<message/>')
21
21
 
22
22
  to = Nokogiri::XML::Node.new 'to', doc
23
- to.content = self.to
23
+ to.content = @to
24
24
  doc.root.add_child(to)
25
25
 
26
26
  body = Nokogiri::XML::Node.new 'body', doc
27
- body.content = self.body
27
+ body.content = @body
28
28
  doc.root.add_child(body)
29
29
 
30
- if self.from
30
+ if @from
31
31
  from = Nokogiri::XML::Node.new 'from', doc
32
- from.content = self.from
32
+ from.content = @from
33
33
  doc.root.add_child(from)
34
34
  end
35
35
 
@@ -0,0 +1,12 @@
1
+ require 'esendex'
2
+ require 'rails'
3
+
4
+ module MyPlugin
5
+ class Railtie < Rails::Railtie
6
+ railtie_name :esendex
7
+
8
+ rake_tasks do
9
+ load "tasks/esendex.rake"
10
+ end
11
+ end
12
+ end
@@ -1,9 +1,3 @@
1
1
  module Esendex
2
- class Version
3
- MAJOR = 0
4
- MINOR = 1
5
- PATCH = 1
6
-
7
- STRING = [MAJOR, MINOR, PATCH].compact.join('.')
8
- end
2
+ VERSION = "0.2.0"
9
3
  end
data/readme.md ADDED
@@ -0,0 +1,83 @@
1
+ # Esendex
2
+
3
+ Ruby Gem for interacting with the Esendex API
4
+
5
+ This is in very early stages of development but supports sending one or multiple messages using your account details
6
+
7
+ ## Usage
8
+
9
+ ### Setting up
10
+
11
+ From the command line
12
+
13
+ gem install esendex
14
+
15
+ or in your project's Gemfile.
16
+
17
+ gem 'esendex'
18
+
19
+ Before sending messages you need to configure the gem with your credentials. In a Rails app this would typically go into a file called `esendex.rb` in the *config/initializers*.
20
+
21
+ ```ruby
22
+ Esendex.configure do |config|
23
+ config.username = "<username>"
24
+ config.password = "<password>"
25
+ config.account_reference = "<account_reference>"
26
+ end
27
+ ```
28
+
29
+ You can omit account reference and specify it when you instantiate an account object if you're using multiple accounts.
30
+
31
+ You can also specify these using the environment variables `ESENDEX_USERNAME`, `ESENDEX_PASSWORD` and `ESENDEX_ACCOUNT`.
32
+
33
+ ### Sending Messages
34
+
35
+ First instantiate an Account with the reference. You can omit the reference if you've already configured one to use in the *Esendex.configure* step.
36
+
37
+ ```ruby
38
+ account = Account.new("EX123456")
39
+ ```
40
+
41
+ then, call the send method on the account object with a hash describing the message. The return value is a *batch_id* you can use to obtain the status of the messages you have sent.
42
+
43
+ ```ruby
44
+ batch_id = account.send_message( to: "07777111222", body: "Saying hello to the world with the help of Esendex")
45
+ ```
46
+
47
+ Multiple messages are sent by passing an array of `Messages` to the send_messages method
48
+
49
+ ```ruby
50
+ batch_id = account.send_messages([Message.new("07777111222", "Hello"), Message.new("07777111333", "Hi")])
51
+ ```
52
+
53
+ ### Testing Configuration
54
+
55
+ The Esendex Gem ships with a couple of rake tasks that allow you to simply validate that all is well.
56
+
57
+ rake esendex:validate['<username>,'<password>','<account_reference>']
58
+
59
+ This will confirm that the credentials passed can access the account.
60
+
61
+ You can also send a message
62
+
63
+ rake esendex:send_message["<mobile_number>","<message_body>"]
64
+
65
+ You will need to set the credentials as enviroment variables which can also be done inline
66
+
67
+ rake esendex:send_message["<mobile_number>","<message_body>"] ESENDEX_USERNAME=<username> ESENDEX_PASSWORD=<password> ESENDEX_ACCOUNT=<account_reference>
68
+
69
+
70
+ ### Testing
71
+
72
+ bundle exec rspec
73
+
74
+ will run specs, ie those in the root of the test folder
75
+
76
+ ## Contributing
77
+
78
+ Please fork as you see fit and let us know when you have something that should be part of the gem.
79
+
80
+ ## Copyright
81
+
82
+ Copyright (c) 2011-13 Esendex Ltd. See LICENSE.txt for further details.
83
+
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ describe Account do
4
+ let(:account_reference) { random_string }
5
+ let(:account) { Account.new(account_reference) }
6
+ let(:messages_remaining) { random_integer }
7
+ let(:account_xml) {
8
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>
9
+ <accounts xmlns=\"http://api.esendex.com/ns/\">
10
+ <account id=\"2b4a326c-41de-4a57-a577-c7d742dc145c\" uri=\"http://api.esendex.com/v1.0/accounts/2b4a326c-41de-4a57-a577-c7d742dc145c\">
11
+ <balanceremaining domesticmessages=\"100\" internationalmessages=\"100\">$0.00</balanceremaining>
12
+ <reference>#{account_reference}</reference>
13
+ <address>447786204254</address>
14
+ <type>Professional</type>
15
+ <messagesremaining>#{messages_remaining}</messagesremaining>
16
+ <expireson>2015-12-31T00:00:00</expireson>
17
+ <role>PowerUser</role>
18
+ <defaultdialcode>44</defaultdialcode>
19
+ <settings uri=\"http://api.esendex.com/v1.0/accounts/2b4a326c-41de-4a57-a577-c7d742dc145c/settings\" />
20
+ </account>
21
+ </accounts>"
22
+ }
23
+ let(:api_connection) { mock("Connection", :get => mock('Response', :body => account_xml), :post => true )}
24
+
25
+ before(:each) do
26
+ account.stub(:api_connection) { api_connection}
27
+ end
28
+
29
+ describe "#messages_remaining" do
30
+
31
+ subject { account.messages_remaining }
32
+
33
+ it "should get the account resource" do
34
+ api_connection.should_receive(:get).with("/v1.0/accounts/#{account_reference}")
35
+ subject
36
+ end
37
+ it "should get the messages remaining from the documeny" do
38
+ subject.should eq(messages_remaining)
39
+ end
40
+ end
41
+
42
+ describe "#send_message" do
43
+ let(:batch_id) { random_string }
44
+ let(:send_response_xml) {
45
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>
46
+ <messageheaders batchid=\"#{batch_id}\" xmlns=\"http://api.esendex.com/ns/\">
47
+ <messageheader\ uri=\"http://api.esendex.com/v1.0/MessageHeaders/00000000-0000-0000-0000-000000000000\" id=\"00000000-0000-0000-0000-000000000000\" />
48
+ </messageheaders>"
49
+ }
50
+
51
+ before(:each) do
52
+ api_connection.stub(:post) { mock('Response', :body => send_response_xml) }
53
+ end
54
+
55
+ subject { account.send_message(to: "447815777555", body: "Hello from the Esendex Ruby Gem") }
56
+
57
+ it "posts to the message dispatcher resource" do
58
+ api_connection.should_receive(:post).with("/v1.0/messagedispatcher", anything)
59
+ subject
60
+ end
61
+ it "should return the batch_id in the result" do
62
+ subject.should eq(batch_id)
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+
3
+ describe ApiConnection do
4
+ let(:api_connection) { ApiConnection.new }
5
+
6
+ before(:each) do
7
+ @connection = Nestful::Connection.new Esendex::API_HOST
8
+ Nestful::Connection.stub(:new) { @connection }
9
+ @connection.stub(:get) {}
10
+ @connection.stub(:post) {}
11
+ Esendex.configure do |config|
12
+ config.username = random_string
13
+ config.password = random_string
14
+ end
15
+ end
16
+
17
+ describe "#initialise" do
18
+
19
+ subject { ApiConnection.new }
20
+
21
+ it "should set the username" do
22
+ subject
23
+ @connection.user.should eq(Esendex.username)
24
+ end
25
+ it "should set the password" do
26
+ subject
27
+ @connection.password.should eq(Esendex.password)
28
+ end
29
+ it "should set the auth to basic" do
30
+ subject
31
+ @connection.auth_type.should eq(:basic)
32
+ end
33
+
34
+ end
35
+
36
+
37
+ describe "#get" do
38
+ let(:url) { random_string }
39
+
40
+ subject { api_connection.get url }
41
+
42
+ it "should call get with headers" do
43
+ @connection.should_receive(:get).with(url, api_connection.default_headers)
44
+ subject
45
+ end
46
+
47
+ context "when 403 raised" do
48
+ before(:each) do
49
+ @connection.stub(:get) { raise Nestful::ForbiddenAccess.new(nil) }
50
+ end
51
+ it "raises an Esendex::ForbiddenError" do
52
+ expect { subject }.to raise_error(Esendex::ForbiddenError)
53
+ end
54
+ end
55
+
56
+ end
57
+
58
+ describe "#post" do
59
+ let(:url) { random_string }
60
+ let(:body) { random_string }
61
+
62
+ subject { api_connection.post url, body }
63
+
64
+ it "should call post with headers" do
65
+ @connection.should_receive(:post).with(url, body, api_connection.default_headers)
66
+ subject
67
+ end
68
+
69
+ context "when 403 raised" do
70
+ before(:each) do
71
+ @connection.stub(:post) { raise Nestful::ForbiddenAccess.new(nil) }
72
+ end
73
+ it "raises an Esendex::ForbiddenError" do
74
+ expect { subject }.to raise_error(Esendex::ForbiddenError)
75
+ end
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe MessageBatchSubmission do
4
+ let(:account) { "EX1234556" }
5
+
6
+ describe "#xml_node" do
7
+ let(:messages) { [ Message.new(random_mobile, random_string), Message.new(random_mobile, random_string)] }
8
+ let(:message_batch) { MessageBatchSubmission.new(account, messages) }
9
+
10
+ subject { message_batch.xml_node }
11
+
12
+ it "should create message nodes" do
13
+ subject.xpath('//messages/message').count.should eq(messages.count)
14
+ end
15
+ it "should set the message to" do
16
+ (0..1).each do |i|
17
+ subject.xpath('//messages/message/to')[i].content.should eq(messages[i].to)
18
+ end
19
+ end
20
+ it "should set the message body" do
21
+ (0..1).each do |i|
22
+ subject.xpath('//messages/message/body')[i].content.should eq(messages[i].body)
23
+ end
24
+ end
25
+ context "when send_at set" do
26
+ let(:target_time) { Time.local(2011, 4, 7, 15, 0, 0) }
27
+
28
+ before(:each) do
29
+ message_batch.send_at = target_time
30
+ end
31
+
32
+ it "should create a properly formatted sendat node" do
33
+ subject.at_xpath('//messages/sendat').content.should eq("2011-04-07T15:00:00")
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe Message do
4
+ describe "#xml_node" do
5
+ let(:to) { random_mobile }
6
+ let(:body) { random_string }
7
+ let(:message) { Esendex::Message.new(to, body) }
8
+
9
+ subject { message.xml_node }
10
+
11
+ it "contains a to node" do
12
+ subject.at_xpath('//message/to').content.should eq(to)
13
+ end
14
+ it "contains a body node" do
15
+ subject.at_xpath('//message/body').content.should eq(body)
16
+ end
17
+
18
+ context "when from set" do
19
+ let(:from) { random_string }
20
+
21
+ before(:each) do
22
+ message.from = from
23
+ end
24
+
25
+ it "contains a from node" do
26
+ subject.at_xpath('//message/from').content.should eq(from)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,26 @@
1
+ require 'rake'
2
+ require 'rspec'
3
+
4
+ require "#{Rake.application.original_dir}/lib/esendex"
5
+
6
+ RSpec.configure do |config|
7
+ config.color = true
8
+ end
9
+
10
+ include Esendex
11
+
12
+ def random_string
13
+ (0...24).map{ ('a'..'z').to_a[rand(26)] }.join
14
+ end
15
+
16
+ def random_email
17
+ "#{random_string}@#{random_string}.com"
18
+ end
19
+
20
+ def random_integer
21
+ rand(9999)
22
+ end
23
+
24
+ def random_mobile
25
+ "447#{"%09d" % rand(999999999)}"
26
+ end
metadata CHANGED
@@ -1,259 +1,68 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: esendex
3
- version: !ruby/object:Gem::Version
4
- hash: 25
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 1
9
- - 1
10
- version: 0.1.1
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Adam Bird
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-05-05 00:00:00 +01:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
22
- requirement: &id001 !ruby/object:Gem::Requirement
23
- none: false
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- hash: 19
28
- segments:
29
- - 0
30
- - 0
31
- - 6
32
- version: 0.0.6
33
- name: nestful
34
- version_requirements: *id001
35
- prerelease: false
36
- type: :runtime
37
- - !ruby/object:Gem::Dependency
38
- requirement: &id002 !ruby/object:Gem::Requirement
39
- none: false
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- hash: 3
44
- segments:
45
- - 0
46
- version: "0"
47
- name: i18n
48
- version_requirements: *id002
49
- prerelease: false
50
- type: :runtime
51
- - !ruby/object:Gem::Dependency
52
- requirement: &id003 !ruby/object:Gem::Requirement
53
- none: false
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- hash: 15
58
- segments:
59
- - 1
60
- - 4
61
- - 4
62
- version: 1.4.4
63
- name: nokogiri
64
- version_requirements: *id003
65
- prerelease: false
66
- type: :runtime
67
- - !ruby/object:Gem::Dependency
68
- requirement: &id004 !ruby/object:Gem::Requirement
69
- none: false
70
- requirements:
71
- - - ">="
72
- - !ruby/object:Gem::Version
73
- hash: 3
74
- segments:
75
- - 0
76
- version: "0"
77
- name: shoulda
78
- version_requirements: *id004
79
- prerelease: false
80
- type: :development
81
- - !ruby/object:Gem::Dependency
82
- requirement: &id005 !ruby/object:Gem::Requirement
83
- none: false
84
- requirements:
85
- - - ~>
86
- - !ruby/object:Gem::Version
87
- hash: 23
88
- segments:
89
- - 1
90
- - 0
91
- - 0
92
- version: 1.0.0
93
- name: bundler
94
- version_requirements: *id005
95
- prerelease: false
96
- type: :development
97
- - !ruby/object:Gem::Dependency
98
- requirement: &id006 !ruby/object:Gem::Requirement
99
- none: false
100
- requirements:
101
- - - ~>
102
- - !ruby/object:Gem::Version
103
- hash: 7
104
- segments:
105
- - 1
106
- - 5
107
- - 2
108
- version: 1.5.2
109
- name: jeweler
110
- version_requirements: *id006
111
- prerelease: false
112
- type: :development
113
- - !ruby/object:Gem::Dependency
114
- requirement: &id007 !ruby/object:Gem::Requirement
115
- none: false
116
- requirements:
117
- - - ">="
118
- - !ruby/object:Gem::Version
119
- hash: 3
120
- segments:
121
- - 0
122
- version: "0"
123
- name: rcov
124
- version_requirements: *id007
125
- prerelease: false
126
- type: :development
127
- - !ruby/object:Gem::Dependency
128
- requirement: &id008 !ruby/object:Gem::Requirement
129
- none: false
130
- requirements:
131
- - - ">="
132
- - !ruby/object:Gem::Version
133
- hash: 35
134
- segments:
135
- - 0
136
- - 9
137
- - 12
138
- version: 0.9.12
139
- name: mocha
140
- version_requirements: *id008
141
- prerelease: false
142
- type: :development
143
- - !ruby/object:Gem::Dependency
144
- requirement: &id009 !ruby/object:Gem::Requirement
145
- none: false
146
- requirements:
147
- - - ">="
148
- - !ruby/object:Gem::Version
149
- hash: 15
150
- segments:
151
- - 1
152
- - 4
153
- - 4
154
- version: 1.4.4
155
- name: nokogiri
156
- version_requirements: *id009
157
- prerelease: false
158
- type: :runtime
159
- - !ruby/object:Gem::Dependency
160
- requirement: &id010 !ruby/object:Gem::Requirement
161
- none: false
162
- requirements:
163
- - - ">="
164
- - !ruby/object:Gem::Version
165
- hash: 3
166
- segments:
167
- - 0
168
- version: "0"
169
- name: i18n
170
- version_requirements: *id010
171
- prerelease: false
172
- type: :runtime
173
- - !ruby/object:Gem::Dependency
174
- requirement: &id011 !ruby/object:Gem::Requirement
175
- none: false
176
- requirements:
177
- - - ">="
178
- - !ruby/object:Gem::Version
179
- hash: 19
180
- segments:
181
- - 0
182
- - 0
183
- - 6
184
- version: 0.0.6
185
- name: nestful
186
- version_requirements: *id011
187
- prerelease: false
188
- type: :runtime
189
- description: ""
190
- email: support@esendex.com
12
+ date: 2013-02-19 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Gem for interacting with the Esendex API
15
+ email:
16
+ - support@esendex.com
191
17
  executables: []
192
-
193
18
  extensions: []
194
-
195
- extra_rdoc_files:
19
+ extra_rdoc_files:
196
20
  - LICENSE.txt
197
- - README.rdoc
198
- files:
199
- - .document
200
- - Gemfile
201
- - Gemfile.lock
202
- - LICENSE.txt
203
- - README.rdoc
204
- - Rakefile
205
- - VERSION
206
- - esendex.gemspec
207
- - lib/esendex.rb
21
+ - readme.md
22
+ files:
208
23
  - lib/esendex/account.rb
24
+ - lib/esendex/api_connection.rb
209
25
  - lib/esendex/exceptions.rb
210
26
  - lib/esendex/message.rb
211
27
  - lib/esendex/message_batch_submission.rb
28
+ - lib/esendex/railtie.rb
212
29
  - lib/esendex/version.rb
213
- - test/helper.rb
214
- - test/integration/test_account.rb
215
- - test/test_account.rb
216
- - test/test_message.rb
217
- - test/test_message_batch.rb
218
- - test/test_nokogiri.rb
219
- has_rdoc: true
220
- homepage: http://github.com/esendex/esendex.gem
221
- licenses:
222
- - MIT
30
+ - lib/esendex.rb
31
+ - LICENSE.txt
32
+ - readme.md
33
+ - spec/account_spec.rb
34
+ - spec/api_connection_spec.rb
35
+ - spec/message_batch_submission_spec.rb
36
+ - spec/message_spec.rb
37
+ - spec/spec_helper.rb
38
+ homepage: http://www.esendex.com
39
+ licenses: []
223
40
  post_install_message:
224
41
  rdoc_options: []
225
-
226
- require_paths:
42
+ require_paths:
227
43
  - lib
228
- required_ruby_version: !ruby/object:Gem::Requirement
44
+ required_ruby_version: !ruby/object:Gem::Requirement
229
45
  none: false
230
- requirements:
231
- - - ">="
232
- - !ruby/object:Gem::Version
233
- hash: 3
234
- segments:
235
- - 0
236
- version: "0"
237
- required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
238
51
  none: false
239
- requirements:
240
- - - ">="
241
- - !ruby/object:Gem::Version
242
- hash: 3
243
- segments:
244
- - 0
245
- version: "0"
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
246
56
  requirements: []
247
-
248
57
  rubyforge_project:
249
- rubygems_version: 1.6.2
58
+ rubygems_version: 1.8.24
250
59
  signing_key:
251
60
  specification_version: 3
252
- summary: for interacting with the Esendex API
253
- test_files:
254
- - test/helper.rb
255
- - test/integration/test_account.rb
256
- - test/test_account.rb
257
- - test/test_message.rb
258
- - test/test_message_batch.rb
259
- - test/test_nokogiri.rb
61
+ summary: Gem for interacting with the Esendex API
62
+ test_files:
63
+ - spec/account_spec.rb
64
+ - spec/api_connection_spec.rb
65
+ - spec/message_batch_submission_spec.rb
66
+ - spec/message_spec.rb
67
+ - spec/spec_helper.rb
68
+ has_rdoc:
data/.document DELETED
@@ -1,5 +0,0 @@
1
- lib/**/*.rb
2
- bin/*
3
- -
4
- features/**/*.feature
5
- LICENSE.txt
data/Gemfile DELETED
@@ -1,17 +0,0 @@
1
- source "http://rubygems.org"
2
- # Add dependencies required to use your gem here.
3
- # Example:
4
- # gem "activesupport", ">= 2.3.5"
5
- gem "nestful", ">= 0.0.6"
6
- gem "i18n"
7
- gem "nokogiri", ">=1.4.4"
8
-
9
- # Add dependencies to develop your gem here.
10
- # Include everything needed to run rake, tests, features, etc.
11
- group :development do
12
- gem "shoulda", ">= 0"
13
- gem "bundler", "~> 1.0.0"
14
- gem "jeweler", "~> 1.5.2"
15
- gem "rcov", ">= 0"
16
- gem "mocha", ">=0.9.12"
17
- end
data/Gemfile.lock DELETED
@@ -1,30 +0,0 @@
1
- GEM
2
- remote: http://rubygems.org/
3
- specs:
4
- activesupport (3.0.5)
5
- git (1.2.5)
6
- i18n (0.5.0)
7
- jeweler (1.5.2)
8
- bundler (~> 1.0.0)
9
- git (>= 1.2.5)
10
- rake
11
- mocha (0.9.12)
12
- nestful (0.0.6)
13
- activesupport (>= 3.0.0.beta)
14
- nokogiri (1.4.4)
15
- rake (0.8.7)
16
- rcov (0.9.9)
17
- shoulda (2.11.3)
18
-
19
- PLATFORMS
20
- ruby
21
-
22
- DEPENDENCIES
23
- bundler (~> 1.0.0)
24
- i18n
25
- jeweler (~> 1.5.2)
26
- mocha (>= 0.9.12)
27
- nestful (>= 0.0.6)
28
- nokogiri (>= 1.4.4)
29
- rcov
30
- shoulda
data/README.rdoc DELETED
@@ -1,49 +0,0 @@
1
- = esendex.gem
2
-
3
- Gem for interacting with the Esendex API
4
-
5
- This is in very early stages of development but supports sending one
6
-
7
- == Usage
8
-
9
- === Setting up
10
-
11
- gem install esendex
12
-
13
- === Sending Messages
14
-
15
- First instantiate an Account with your credentials
16
-
17
- account = Account.new("EX123456", "user@company.com", "yourpassword")
18
-
19
- then, call the send method on the account object with a message. The return value is a batch_id you can use to obtain the status of the messages you have sent.
20
-
21
- batch_id = account.send_message(Message.new("07777111222", "Saying hello to the world with the help of Esendex"))
22
-
23
- Multiple messages are sent by passing an array of Messages to the send_messages method
24
-
25
- batch_id = account.send_messages([Message.new("07777111222", "Hello"), Message.new("07777111333", "Hi")])
26
-
27
- == Building
28
-
29
- The plan is to publish this so you can perform gem install but if you can't wait then feel free to download
30
-
31
- === Testing
32
-
33
- rake test
34
-
35
- will run unit tests, ie those in the root of the test folder
36
-
37
- rake integration_test
38
-
39
- will run integration tests, ie only those in the /test/integration folder
40
-
41
- == Contributing
42
-
43
- Please fork as you see fit and let us know when you have something that should be part of the gem.
44
-
45
- == Copyright
46
-
47
- Copyright (c) 2011 Esendex Ltd. See LICENSE.txt for
48
- further details.
49
-
data/Rakefile DELETED
@@ -1,62 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'rake'
11
-
12
- require 'jeweler'
13
- require './lib/esendex/version'
14
- Jeweler::Tasks.new do |gem|
15
- # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
16
- gem.name = "esendex"
17
- gem.homepage = "http://github.com/esendex/esendex.gem"
18
- gem.license = "MIT"
19
- gem.summary = "for interacting with the Esendex API"
20
- gem.description = ""
21
- gem.email = "support@esendex.com"
22
- gem.authors = ["Adam Bird"]
23
- gem.version = Esendex::Version::STRING
24
- # Include your dependencies below. Runtime dependencies are required when using your gem,
25
- # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
26
- gem.add_dependency 'nokogiri', '>=1.4.4'
27
- gem.add_dependency 'i18n'
28
- gem.add_dependency 'nestful', '>= 0.0.6'
29
- end
30
- Jeweler::RubygemsDotOrgTasks.new
31
-
32
- require 'rake/testtask'
33
- Rake::TestTask.new(:test) do |test|
34
- test.libs << 'lib' << 'test'
35
- test.pattern = 'test/test_*.rb'
36
- test.verbose = true
37
- end
38
-
39
- Rake::TestTask.new(:integration_test) do |test|
40
- test.libs << 'lib' << 'test'
41
- test.pattern = 'test/integration/test_*.rb'
42
- test.verbose = true
43
- end
44
-
45
- require 'rcov/rcovtask'
46
- Rcov::RcovTask.new do |test|
47
- test.libs << 'test'
48
- test.pattern = 'test/**/test_*.rb'
49
- test.verbose = true
50
- end
51
-
52
- task :default => :test
53
-
54
- require 'rake/rdoctask'
55
- Rake::RDocTask.new do |rdoc|
56
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
57
-
58
- rdoc.rdoc_dir = 'rdoc'
59
- rdoc.title = "esendex #{version}"
60
- rdoc.rdoc_files.include('README*')
61
- rdoc.rdoc_files.include('lib/**/*.rb')
62
- end
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.1.0
data/esendex.gemspec DELETED
@@ -1,97 +0,0 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = %q{esendex}
8
- s.version = "0.1.1"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Adam Bird"]
12
- s.date = %q{2011-05-05}
13
- s.description = %q{}
14
- s.email = %q{support@esendex.com}
15
- s.extra_rdoc_files = [
16
- "LICENSE.txt",
17
- "README.rdoc"
18
- ]
19
- s.files = [
20
- ".document",
21
- "Gemfile",
22
- "Gemfile.lock",
23
- "LICENSE.txt",
24
- "README.rdoc",
25
- "Rakefile",
26
- "VERSION",
27
- "esendex.gemspec",
28
- "lib/esendex.rb",
29
- "lib/esendex/account.rb",
30
- "lib/esendex/exceptions.rb",
31
- "lib/esendex/message.rb",
32
- "lib/esendex/message_batch_submission.rb",
33
- "lib/esendex/version.rb",
34
- "test/helper.rb",
35
- "test/integration/test_account.rb",
36
- "test/test_account.rb",
37
- "test/test_message.rb",
38
- "test/test_message_batch.rb",
39
- "test/test_nokogiri.rb"
40
- ]
41
- s.homepage = %q{http://github.com/esendex/esendex.gem}
42
- s.licenses = ["MIT"]
43
- s.require_paths = ["lib"]
44
- s.rubygems_version = %q{1.6.2}
45
- s.summary = %q{for interacting with the Esendex API}
46
- s.test_files = [
47
- "test/helper.rb",
48
- "test/integration/test_account.rb",
49
- "test/test_account.rb",
50
- "test/test_message.rb",
51
- "test/test_message_batch.rb",
52
- "test/test_nokogiri.rb"
53
- ]
54
-
55
- if s.respond_to? :specification_version then
56
- s.specification_version = 3
57
-
58
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
59
- s.add_runtime_dependency(%q<nestful>, [">= 0.0.6"])
60
- s.add_runtime_dependency(%q<i18n>, [">= 0"])
61
- s.add_runtime_dependency(%q<nokogiri>, [">= 1.4.4"])
62
- s.add_development_dependency(%q<shoulda>, [">= 0"])
63
- s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
64
- s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
65
- s.add_development_dependency(%q<rcov>, [">= 0"])
66
- s.add_development_dependency(%q<mocha>, [">= 0.9.12"])
67
- s.add_runtime_dependency(%q<nokogiri>, [">= 1.4.4"])
68
- s.add_runtime_dependency(%q<i18n>, [">= 0"])
69
- s.add_runtime_dependency(%q<nestful>, [">= 0.0.6"])
70
- else
71
- s.add_dependency(%q<nestful>, [">= 0.0.6"])
72
- s.add_dependency(%q<i18n>, [">= 0"])
73
- s.add_dependency(%q<nokogiri>, [">= 1.4.4"])
74
- s.add_dependency(%q<shoulda>, [">= 0"])
75
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
76
- s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
77
- s.add_dependency(%q<rcov>, [">= 0"])
78
- s.add_dependency(%q<mocha>, [">= 0.9.12"])
79
- s.add_dependency(%q<nokogiri>, [">= 1.4.4"])
80
- s.add_dependency(%q<i18n>, [">= 0"])
81
- s.add_dependency(%q<nestful>, [">= 0.0.6"])
82
- end
83
- else
84
- s.add_dependency(%q<nestful>, [">= 0.0.6"])
85
- s.add_dependency(%q<i18n>, [">= 0"])
86
- s.add_dependency(%q<nokogiri>, [">= 1.4.4"])
87
- s.add_dependency(%q<shoulda>, [">= 0"])
88
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
89
- s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
90
- s.add_dependency(%q<rcov>, [">= 0"])
91
- s.add_dependency(%q<mocha>, [">= 0.9.12"])
92
- s.add_dependency(%q<nokogiri>, [">= 1.4.4"])
93
- s.add_dependency(%q<i18n>, [">= 0"])
94
- s.add_dependency(%q<nestful>, [">= 0.0.6"])
95
- end
96
- end
97
-
data/test/helper.rb DELETED
@@ -1,21 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler'
3
-
4
- begin
5
- Bundler.setup(:default, :development)
6
- rescue Bundler::BundlerError => e
7
- $stderr.puts e.message
8
- $stderr.puts "Run `bundle install` to install missing gems"
9
- exit e.status_code
10
- end
11
- require 'test/unit'
12
- require 'shoulda'
13
- require 'mocha'
14
-
15
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
16
- $LOAD_PATH.unshift(File.dirname(__FILE__))
17
-
18
- require 'esendex'
19
-
20
- class Test::Unit::TestCase
21
- end
@@ -1,26 +0,0 @@
1
- require 'helper'
2
- include Esendex
3
-
4
- class TestAccount < Test::Unit::TestCase
5
- should "validate account when a new one is created" do
6
- code_challenge_account = Account.new("EX0068832", "codechallenge@esendex.com", "c0d3cha113ng3")
7
-
8
- assert code_challenge_account.messages_remaining > 0
9
- end
10
-
11
- should "fail authorisation" do
12
- begin
13
- code_challenge_account = Account.new("EX0068832", "bilge", "bilge")
14
- rescue Esendex::ForbiddenError
15
- end
16
-
17
- end
18
-
19
- should "send a message" do
20
- code_challenge_account = Account.new("EX0068832", "codechallenge@esendex.com", "c0d3cha113ng3")
21
-
22
- batch_id = code_challenge_account.send_message(Message.new("447700900000", "Hello from the Esendex Ruby Gem"))
23
-
24
- assert batch_id
25
- end
26
- end
data/test/test_account.rb DELETED
@@ -1,63 +0,0 @@
1
- require 'helper'
2
- require 'nestful'
3
- include Esendex
4
-
5
- class TestAccount < Test::Unit::TestCase
6
-
7
- def raw_mock_connection
8
- @user = "codechallenge@esendex.com"
9
- @password = "c0d3cha113ng3"
10
- @account_reference = "EX0068832"
11
- connection = mock()
12
- connection.expects(:user=).with(@user)
13
- connection.expects(:password=).with(@password)
14
- connection.expects(:auth_type=).with(:basic)
15
- connection
16
- end
17
-
18
- def mock_connection
19
- connection = raw_mock_connection
20
- account_initialisation_response = mock()
21
- account_initialisation_response.expects(:body).returns("<?xml version=\"1.0\" encoding=\"utf-8\"?><accounts xmlns=\"http://api.esendex.com/ns/\"><account id=\"2b4a326c-41de-4a57-a577-c7d742dc145c\" uri=\"http://api.esendex.com/v1.0/accounts/2b4a326c-41de-4a57-a577-c7d742dc145c\"><balanceremaining domesticmessages=\"100\" internationalmessages=\"100\">$0.00</balanceremaining><reference>EX0068832</reference><address>447786204254</address><type>Professional</type><messagesremaining>100</messagesremaining><expireson>2015-12-31T00:00:00</expireson><role>PowerUser</role><defaultdialcode>44</defaultdialcode><settings uri=\"http://api.esendex.com/v1.0/accounts/2b4a326c-41de-4a57-a577-c7d742dc145c/settings\" /></account></accounts>")
22
-
23
- connection.expects(:get).with("/v0.1/accounts/#{@account_reference}", anything).returns(account_initialisation_response)
24
- connection
25
- end
26
-
27
- should "validate account when a new one is created" do
28
- connection = mock_connection
29
-
30
- code_challenge_account = Account.new(@account_reference, @user, @password, connection)
31
-
32
- assert_equal 100, code_challenge_account.messages_remaining
33
- end
34
-
35
- should "raise an ForbiddenError when a 403 is returned from API" do
36
- connection = raw_mock_connection
37
- connection.stubs(:get).raises(Nestful::ForbiddenAccess.new nil)
38
-
39
- begin
40
- account = Account.new(@account_reference, @user, @password, connection)
41
- rescue Esendex::ForbiddenError
42
- end
43
- end
44
-
45
- should "send a message" do
46
- connection = mock_connection
47
- batch_id = "2b4a326c-41de-4a57-a577-c7d742dc145c"
48
-
49
- message_send_response = mock()
50
- message_send_response.expects(:body).returns("<?xml version=\"1.0\" encoding=\"utf-8\"?> <messageheaders batchid=\"#{batch_id}\" xmlns=\"http://api.esendex.com/ns/\"> <messageheader\ uri=\"http://api.esendex.com/v1.0/MessageHeaders/00000000-0000-0000-0000-000000000000\" id=\"00000000-0000-0000-0000-000000000000\" /></messageheaders>")
51
- connection.expects(:post).with("/v1.0/messagedispatcher", anything, anything).returns(message_send_response)
52
-
53
- code_challenge_account = Account.new(@account_reference, @user, @password, connection)
54
-
55
- result = code_challenge_account.send_message(Message.new("447815777555", "Hello from the Esendex Ruby Gem"))
56
-
57
- assert_equal batch_id, result
58
- end
59
-
60
- should "return populated inbox" do
61
-
62
- end
63
- end
data/test/test_message.rb DELETED
@@ -1,24 +0,0 @@
1
- require 'helper'
2
-
3
- class TestMessage < Test::Unit::TestCase
4
- should "create a valid xml representation of a message" do
5
- target = Esendex::Message.new("07777111333", "Hello World")
6
-
7
- actual = target.xml_node
8
-
9
- assert_equal "07777111333", actual.at_xpath('//message/to').content
10
- assert_equal "Hello World", actual.at_xpath('//message/body').content
11
- end
12
-
13
- should "create a valid xml representation if from specified" do
14
- target = Esendex::Message.new("07777111333", "Hello World")
15
- target.from = "BilgeInc"
16
-
17
- actual = target.xml_node
18
-
19
- assert_equal "07777111333", actual.at_xpath('//message/to').content
20
- assert_equal "Hello World", actual.at_xpath('//message/body').content
21
- assert_equal "BilgeInc", actual.at_xpath('//message/from').content
22
-
23
- end
24
- end
@@ -1,22 +0,0 @@
1
- require 'helper'
2
-
3
- class TestMessageBatchSubmission < Test::Unit::TestCase
4
- should "format scheduled date time correctly" do
5
- # yyyy-MM-ddThh:mm:ss
6
-
7
- target_time = Time.local(2011, 4, 7, 15, 0, 0)
8
-
9
- submission = MessageBatchSubmission.new("EX1234556", [Message.new("0777111222", "I'm sending this in the future")])
10
- submission.send_at = target_time
11
-
12
- assert_equal "2011-04-07T15:00:00", submission.xml_node.at_xpath('//messages/sendat').content
13
- end
14
-
15
- should "contain multiple messages" do
16
- submission = MessageBatchSubmission.new("EX1234556", [Message.new("0777111222", "I'm sending this in the future"), Message.new("0777111333", "I'm sending this in the future")])
17
-
18
- message_elements = submission.xml_node.xpath('//messages/message')
19
-
20
- assert_equal 2, message_elements.count
21
- end
22
- end
@@ -1,19 +0,0 @@
1
- require 'helper'
2
- require 'Nokogiri'
3
-
4
- class TestNokogiri < Test::Unit::TestCase
5
- should "get same from Nokogiri using XPath or CSS syntax" do
6
-
7
- xml_source = "<?xml version=\"1.0\" encoding=\"utf-8\"?><accounts xmlns=\"http://api.esendex.com/ns/\"><account id=\"2b4a326c-41de-4a57-a577-c7d742dc145c\" uri=\"http://api.esendex.com/v1.0/accounts/2b4a326c-41de-4a57-a577-c7d742dc145c\"><messagesremaining>100</messagesremaining></account></accounts>"
8
-
9
- ndoc = Nokogiri::XML(xml_source)
10
-
11
- node_value = ndoc.css("accounts account messagesremaining").count
12
- assert_equal 1, node_value
13
-
14
- node_value = ndoc.xpath('//api:accounts/api:account/api:messagesremaining', 'api' => 'http://api.esendex.com/ns/').count
15
- assert_equal 1, node_value
16
-
17
- end
18
- end
19
-