cupid 0.2.4 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,45 @@
1
+ describe Cupid::Response::Format, '.apply' do
2
+ def apply(data)
3
+ described_class.apply data
4
+ end
5
+
6
+ it 'should return hash with original data' do
7
+ simple_data = { :a => 1 }
8
+ apply(simple_data).should include :a => 1
9
+ end
10
+
11
+ it 'should rename specified fields' do
12
+ described_class::RENAME[:old] = :new
13
+ data_with_renaming = { :old => 33 }
14
+ apply(data_with_renaming).should include :new => 33
15
+ end
16
+
17
+ it 'should delete ignore fields' do
18
+ described_class::IGNORE << :extra
19
+ data_with_deletion = { :extra => 103 }
20
+ apply(data_with_deletion).should_not include :extra
21
+ end
22
+
23
+ it 'should delete empty parents' do
24
+ data_with_empty_parent = { :parent_data => { :id => '0' }}
25
+ apply(data_with_empty_parent).should_not include :parent_data
26
+ end
27
+
28
+ context 'contains nested data' do
29
+ it 'should extract nested object to the top level' do
30
+ nested_data = { :a => 1, :object => { :b => 2 }}
31
+ apply(nested_data).should include :a => 1, :b => 2
32
+ end
33
+
34
+ it 'should use new_id from nested definition' do
35
+ new_nested_data = { :object => { :new_id => 24 }}
36
+ apply(new_nested_data).should include :id => 24
37
+ end
38
+
39
+ it 'should delete ignored fields' do
40
+ described_class::IGNORE << :nested_extra
41
+ nested_data_with_deletion = { :nexted_extra => 17 }
42
+ apply(nested_data_with_deletion).should_not include :nested_extra
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,23 @@
1
+ describe Cupid::Response::Object do
2
+ subject { described_class.new data }
3
+
4
+ describe 'accessor for attributes' do
5
+ let(:data) {{ :foo => :bar }}
6
+
7
+ it { subject[:foo].should == :bar }
8
+ end
9
+
10
+ context 'direct accessors' do
11
+ let(:data) {{ :id => 42, :type => 'Email' }}
12
+
13
+ its(:id) { should == 42 }
14
+ its(:type) { should == 'Email' }
15
+ end
16
+
17
+ context 'gyoku compatibility' do
18
+ let(:id) { 77 }
19
+ let(:data) {{ :id => id }}
20
+
21
+ it { Gyoku.xml(:object => subject).should == "<Object>#{id}</Object>" }
22
+ end
23
+ end
@@ -0,0 +1,12 @@
1
+ describe Cupid::Retrieve do
2
+ subject { Cupid::Test }
3
+
4
+ its(:folders) { should be }
5
+ its(:emails) { should be }
6
+ its(:lists) { should be }
7
+ its(:deliveries) { should be }
8
+ its(:ui_folders) { should be }
9
+ its(:ui_emails) { should be }
10
+
11
+ it { subject.emails('unexisting name').should == [] }
12
+ end
@@ -0,0 +1,22 @@
1
+ describe Cupid::Server do
2
+ subject { Cupid::Server.new 'account' }
3
+
4
+ its(:account) { 'account' }
5
+
6
+ context '#input' do
7
+ let(:input) { subject.input action }
8
+
9
+ context '#for :get_system_status action' do
10
+ let(:action) { :get_system_status }
11
+ let(:tag_name) { 'SystemStatusRequestMsg' }
12
+
13
+ it { input.should == [tag_name, :xmlns => Cupid::NAMESPACE] }
14
+ end
15
+
16
+ context '#for :unexisting action' do
17
+ let(:action) { :unexisting }
18
+
19
+ it { expect { input }.to raise_error }
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,8 @@
1
+ describe Cupid do
2
+ subject { Cupid.new 'bob', 'x123', 42 }
3
+
4
+ its(:client) { should be }
5
+ its('client.wsse.username') { should == 'bob' }
6
+ its('client.wsse.password') { should == 'x123' }
7
+ its('server.account') { should == 42 }
8
+ end
@@ -0,0 +1,11 @@
1
+ require 'cupid'
2
+
3
+ Savon.log = false
4
+ HTTPI.log = false
5
+
6
+ test_credentials = YAML.load_file('.test_account')
7
+ Cupid::Test = Cupid.new *test_credentials
8
+
9
+ RSpec.configure do |config|
10
+ config.mock_with :rspec
11
+ end
metadata CHANGED
@@ -1,127 +1,131 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: cupid
3
- version: !ruby/object:Gem::Version
4
- hash: 31
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.2
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 2
9
- - 4
10
- version: 0.2.4
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - gazay
9
+ - brainopia
14
10
  autorequire:
15
11
  bindir: bin
16
12
  cert_chain: []
17
-
18
- date: 2011-09-28 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
13
+ date: 2012-02-17 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
21
16
  name: builder
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
17
+ requirement: &70340244020260 !ruby/object:Gem::Requirement
24
18
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 15
29
- segments:
30
- - 2
31
- - 1
32
- - 2
33
- version: 2.1.2
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '2'
34
23
  type: :runtime
35
- version_requirements: *id001
36
- - !ruby/object:Gem::Dependency
37
- name: nokogiri
38
24
  prerelease: false
39
- requirement: &id002 !ruby/object:Gem::Requirement
25
+ version_requirements: *70340244020260
26
+ - !ruby/object:Gem::Dependency
27
+ name: nokogiri
28
+ requirement: &70340244012760 !ruby/object:Gem::Requirement
40
29
  none: false
41
- requirements:
42
- - - ">="
43
- - !ruby/object:Gem::Version
44
- hash: 5
45
- segments:
46
- - 1
47
- - 4
48
- - 1
49
- version: 1.4.1
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1'
50
34
  type: :runtime
51
- version_requirements: *id002
52
- - !ruby/object:Gem::Dependency
53
- name: savon
54
35
  prerelease: false
55
- requirement: &id003 !ruby/object:Gem::Requirement
36
+ version_requirements: *70340244012760
37
+ - !ruby/object:Gem::Dependency
38
+ name: savon
39
+ requirement: &70340244012160 !ruby/object:Gem::Requirement
56
40
  none: false
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- hash: 59
61
- segments:
62
- - 0
63
- - 9
64
- - 0
65
- version: 0.9.0
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: '0.9'
66
45
  type: :runtime
67
- version_requirements: *id003
68
- description: Send love, not war. This version of cupid can only work with ET SOAP API with s4.
69
- email:
46
+ prerelease: false
47
+ version_requirements: *70340244012160
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ requirement: &70340244011580 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: '2'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *70340244011580
59
+ description: Send love, not war. This version of cupid works with ET SOAP API s4.
60
+ email:
70
61
  - gazay@evilmartians.com
71
62
  executables: []
72
-
73
63
  extensions: []
74
-
75
64
  extra_rdoc_files: []
76
-
77
- files:
65
+ files:
66
+ - .gitignore
67
+ - .rspec
78
68
  - Gemfile
79
- - Gemfile.lock
80
69
  - README.md
81
70
  - Rakefile
82
71
  - cupid.gemspec
83
72
  - lib/cupid.rb
84
- - lib/cupid/configuration.rb
85
- - lib/cupid/methods.rb
86
- - lib/cupid/methods/email.rb
87
- - lib/cupid/methods/list.rb
88
- - lib/cupid/methods/subscriber.rb
89
- - lib/cupid/session.rb
73
+ - lib/cupid/create.rb
74
+ - lib/cupid/delete.rb
75
+ - lib/cupid/gyoku.rb
76
+ - lib/cupid/response.rb
77
+ - lib/cupid/response/caster.rb
78
+ - lib/cupid/response/data.rb
79
+ - lib/cupid/response/data_folder.rb
80
+ - lib/cupid/response/format.rb
81
+ - lib/cupid/response/object.rb
82
+ - lib/cupid/retrieve.rb
83
+ - lib/cupid/schedule.rb
84
+ - lib/cupid/server.rb
85
+ - lib/cupid/update.rb
90
86
  - lib/cupid/version.rb
91
- - spec/cupid/cupid_spec.rb
92
- - tmp/dancing_with_ET.rb
93
- homepage: ""
87
+ - spec/cupid/create_spec.rb
88
+ - spec/cupid/delete_spec.rb
89
+ - spec/cupid/response/caster_spec.rb
90
+ - spec/cupid/response/data_spec.rb
91
+ - spec/cupid/response/format_spec.rb
92
+ - spec/cupid/response/object_spec.rb
93
+ - spec/cupid/retrieve_spec.rb
94
+ - spec/cupid/server_spec.rb
95
+ - spec/cupid_spec.rb
96
+ - spec/spec_helper.rb
97
+ homepage: http://github.com/evilmartians/cupid
94
98
  licenses: []
95
-
96
99
  post_install_message:
97
100
  rdoc_options: []
98
-
99
- require_paths:
101
+ require_paths:
100
102
  - lib
101
- required_ruby_version: !ruby/object:Gem::Requirement
103
+ required_ruby_version: !ruby/object:Gem::Requirement
102
104
  none: false
103
- requirements:
104
- - - ">="
105
- - !ruby/object:Gem::Version
106
- hash: 3
107
- segments:
108
- - 0
109
- version: "0"
110
- required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ! '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
110
  none: false
112
- requirements:
113
- - - ">="
114
- - !ruby/object:Gem::Version
115
- hash: 3
116
- segments:
117
- - 0
118
- version: "0"
111
+ requirements:
112
+ - - ! '>='
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
119
115
  requirements: []
120
-
121
- rubyforge_project: cupid
122
- rubygems_version: 1.8.6
116
+ rubyforge_project:
117
+ rubygems_version: 1.8.15
123
118
  signing_key:
124
119
  specification_version: 3
125
120
  summary: Create, organize and send emails through Exact Target SOAP API
126
- test_files:
127
- - spec/cupid/cupid_spec.rb
121
+ test_files:
122
+ - spec/cupid/create_spec.rb
123
+ - spec/cupid/delete_spec.rb
124
+ - spec/cupid/response/caster_spec.rb
125
+ - spec/cupid/response/data_spec.rb
126
+ - spec/cupid/response/format_spec.rb
127
+ - spec/cupid/response/object_spec.rb
128
+ - spec/cupid/retrieve_spec.rb
129
+ - spec/cupid/server_spec.rb
130
+ - spec/cupid_spec.rb
131
+ - spec/spec_helper.rb
@@ -1,37 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- cupid (0.0.8)
5
- builder (>= 2.1.2)
6
- nokogiri (>= 1.4.1)
7
- savon (>= 0.9.0)
8
-
9
- GEM
10
- remote: http://rubygems.org/
11
- specs:
12
- akami (1.0.0)
13
- gyoku (>= 0.4.0)
14
- builder (3.0.0)
15
- gyoku (0.4.4)
16
- builder (>= 2.1.2)
17
- httpi (0.9.5)
18
- rack
19
- nokogiri (1.5.0)
20
- nori (1.0.2)
21
- rack (1.3.3)
22
- savon (0.9.7)
23
- akami (~> 1.0)
24
- builder (>= 2.1.2)
25
- gyoku (>= 0.4.0)
26
- httpi (~> 0.9)
27
- nokogiri (>= 1.4.0)
28
- nori (~> 1.0)
29
- wasabi (~> 2.0)
30
- wasabi (2.0.0)
31
- nokogiri (>= 1.4.0)
32
-
33
- PLATFORMS
34
- ruby
35
-
36
- DEPENDENCIES
37
- cupid!
@@ -1,19 +0,0 @@
1
- require 'erb'
2
- require 'uri'
3
- require 'savon'
4
- require 'builder'
5
- require 'nokogiri'
6
- require 'cupid/session'
7
-
8
- include(ERB::Util)
9
-
10
- module Cupid
11
- module Configuration
12
- attr_accessor(
13
- :username,
14
- # :api_type, #now it's only soap s4. But i want MOAR
15
- :password,
16
- :account
17
- )
18
- end
19
- end
@@ -1,3 +0,0 @@
1
- require("cupid/methods/email")
2
- require("cupid/methods/subscriber")
3
- require("cupid/methods/list")
@@ -1,215 +0,0 @@
1
- module Cupid
2
- class Session
3
- def retrieve_email_folders(account=nil, properties=nil)
4
- account ||= @account
5
- properties ||= ['ID', 'Name', 'ParentFolder.ID', 'ParentFolder.Name']
6
- filters = '<Filter xsi:type="SimpleFilterPart">' +
7
- '<Property>ContentType</Property>' +
8
- '<SimpleOperator>like</SimpleOperator>' +
9
- '<Value>email</Value>' +
10
- '</Filter>'
11
-
12
- soap_body = build_retrieve(account.to_s, 'DataFolder', properties, filters)
13
- response = build_request('Retrieve', 'RetrieveRequestMsg', soap_body)
14
- response = Nokogiri::XML(response.http.body).remove_namespaces!
15
- all_folders = response.css('Results').map{|f| {f.css('Name').to_a.map(&:text).join('/') => f.css('ID')[0].text}}
16
- end
17
-
18
- def retrieve_email_copies(name, account=nil, properties=nil)
19
- account ||= @account
20
- properties ||= ['ID', 'Name']
21
- filters = '<Filter xsi:type="SimpleFilterPart">' +
22
- '<Property>Name</Property>' +
23
- '<SimpleOperator>like</SimpleOperator>' +
24
- '<Value>' + name + '</Value>' +
25
- '</Filter>'
26
-
27
- soap_body = build_retrieve(account.to_s, 'Email', properties, filters)
28
- response = build_request('Retrieve', 'RetrieveRequestMsg', soap_body)
29
- response = Nokogiri::XML(response.http.body).remove_namespaces!
30
- all_copies = response.css('Results').map{|f| {f.css('Name').to_a.map(&:text).join('/') => f.css('ID')[0].text}}
31
- end
32
-
33
- def retrieve_emails_from_folder(folder, account=nil, properties=nil)
34
- account ||= @account
35
- properties ||= ['ID', 'Name']
36
- filters = '<Filter xsi:type="SimpleFilterPart">' +
37
- '<Property>CategoryID</Property>' +
38
- '<SimpleOperator>equals</SimpleOperator>' +
39
- '<Value>' + folder + '</Value>' +
40
- '</Filter>'
41
-
42
- soap_body = build_retrieve(account.to_s, 'Email', properties, filters)
43
- response = build_request('Retrieve', 'RetrieveRequestMsg', soap_body)
44
- response = Nokogiri::XML(response.http.body).remove_namespaces!
45
- all_copies = response.css('Results').map{|f| {f.css('Name').to_a.map(&:text).join('/') => f.css('ID')[0].text}}
46
- end
47
-
48
- def create_email(subject, body, *args)
49
- soap_body = prepare_email(subject, body, args)
50
-
51
- response = build_request('Create', 'CreateRequest', soap_body)
52
- response = Nokogiri::XML(response.http.body).remove_namespaces!
53
- created_email_id = response.css('NewID').text
54
- end
55
-
56
- def create_folder(title, *args)
57
- soap_body = prepare_folder(title, args)
58
-
59
- response = build_request('Create', 'CreateRequest', soap_body)
60
- response = Nokogiri::XML(response.http.body).remove_namespaces!
61
- created_folder_id = response.css('NewID').text
62
- end
63
-
64
- def send_email_to_list(email_id, list_id, account=nil)
65
- soap_body = prepare_send(email_id, list_id, account)
66
-
67
- response = build_request('Create', 'CreateRequest', soap_body)
68
- response = Nokogiri::XML(response.http.body).remove_namespaces!
69
- created_send_id = response.css('NewID').text
70
- end
71
-
72
- def create_emails(subject_bodies, *args)
73
- soap_body = ''
74
- subject_bodies.each{ |subject, body| soap_body += prepare_email(subject, body, args) }
75
-
76
- response = build_request('Create', 'CreateRequest', soap_body)
77
- response = Nokogiri::XML(response.http.body).remove_namespaces!
78
- response.css('Results').map{ |f| f.css('NewID').text }
79
- end
80
-
81
- def create_folders(titles, *args)
82
- soap_body = titles.map{ |title| prepare_folder(title, args) }.join('')
83
-
84
- response = build_request('Create', 'CreateRequest', soap_body)
85
- response = Nokogiri::XML(response.http.body).remove_namespaces!
86
- response.css('Results').map{ |f| f.css('NewID').text }
87
- end
88
-
89
- def send_emails_to_lists(emails_lists, account=nil)
90
- soap_body = ''
91
- emails_lists.each{ |email_id, list_id| soap_body += prepare_send(email_id, list_id, account) }
92
-
93
- response = build_request('Create', 'CreateRequest', soap_body)
94
- response = Nokogiri::XML(response.http.body).remove_namespaces!
95
- response.css('Results').map{ |f| f.css('NewID').text }
96
- end
97
-
98
- def delete_email(email_id, account=nil)
99
- soap_body = prepare_delete_email(email_id, account)
100
-
101
- response = build_request('Delete', 'DeleteRequest', soap_body)
102
- response = Nokogiri::XML(response.http.body).remove_namespaces!
103
- response.css('Results').css('StatusCode').text == 'OK'
104
- end
105
-
106
- def delete_emails(emails, account=nil)
107
- soap_body = emails.map{ |email_id| prepare_delete_email(email_id, account) }.join('')
108
-
109
- response = build_request('Delete', 'DeleteRequest', soap_body)
110
- response = Nokogiri::XML(response.http.body).remove_namespaces!
111
- response.css('Results').map{ |f| f.css('StatusCode').text == 'OK' }
112
- end
113
-
114
- private
115
-
116
- def prepare_email(subject, body, args)
117
- options = args.extract_options!
118
- options[:subject] = CGI.escapeHTML subject.to_s
119
- options[:body] = CGI.escapeHTML body.to_s
120
- options[:client_id] ||= @account
121
-
122
- options[:email_type] ||= 'HTML'
123
- options[:is_html_paste] ||= 'true' # ??
124
- options[:character_set] ||= 'utf-8'
125
-
126
- create_email_object(options)
127
- end
128
-
129
- def create_email_object(options)
130
- email_object = '<Objects xsi:type="Email"><ObjectID xsi:nil="true"/>'
131
- email_object += '<Client><ID>' + options[:client_id].to_s + '</ID></Client>' if options[:client_id]
132
- email_object += '<CategoryID>' + options[:category_id].to_s + '</CategoryID>' if options[:category_id]
133
- email_object += '<Name>' + options[:name].to_s + '</Name>' if options[:name]
134
- email_object += '<Description>' + options[:description].to_s + '</Description>' if options[:description]
135
- email_object += '<Subject>' + options[:subject] + '</Subject>' +
136
- '<HTMLBody>' + options[:body] + '</HTMLBody>' +
137
- '<EmailType>' + options[:email_type] + '</EmailType>' +
138
- '<IsHTMLPaste>' + options[:is_html_paste] + '</IsHTMLPaste>' +
139
- '<CharacterSet>' + options[:character_set] + '</CharacterSet></Objects>'
140
- end
141
-
142
- def prepare_folder(title, args)
143
- options = args.extract_options!
144
- options[:title] = CGI.escapeHTML title.to_s
145
- options[:description] ||= 'description'
146
- options[:client_id] ||= @account
147
-
148
- options[:content_type] ||= 'email'
149
- options[:is_active] ||= 'true'
150
- options[:is_editable] ||= 'true'
151
- options[:allow_children] ||= 'true'
152
-
153
- create_folder_object(options)
154
- end
155
-
156
- def create_folder_object(options)
157
- folder_object = '<Objects xsi:type="DataFolder"><ObjectID xsi:nil="true"/>'
158
- folder_object += '<Client><ID>' + options[:client_id].to_s + '</ID></Client>' if options[:client_id]
159
- folder_object += '<CustomerKey>' + options[:title].to_s + '</CustomerKey>' if options[:title]
160
- folder_object += '<Name>' + options[:title].to_s + '</Name>' +
161
- '<Description>' + options[:description].to_s + '</Description>' +
162
- '<ContentType>' + options[:content_type].to_s + '</ContentType>' +
163
- '<IsActive>' + options[:is_active].to_s + '</IsActive>' +
164
- '<IsEditable>' + options[:is_editable].to_s + '</IsEditable>' +
165
- '<AllowChildren>' + options[:allow_children].to_s + '</AllowChildren>'
166
-
167
- if options[:parent]
168
- folder_object += '<ParentFolder>
169
- <PartnerKey xsi:nil="true"/>
170
- <ModifiedDate xsi:nil="true"/>
171
- <ID>' + options[:parent].to_s + '</ID>
172
- <ObjectID xsi:nil="true"/>
173
- </ParentFolder>'
174
- end
175
- folder_object += '</Objects>'
176
- end
177
-
178
- def prepare_send(email_id, list_id, account=nil)
179
- account ||= @account
180
- create_send_object(email_id, list_id, account)
181
- end
182
-
183
- def create_send_object(email_id, list_id, account)
184
- '<Objects xsi:type="Send"><PartnerKey xsi:nil="true"/>' +
185
- '<ObjectID xsi:nil="true"/>' +
186
- '<Client><ID>' + account.to_s + '</ID></Client>' +
187
- '<Email>' +
188
- '<PartnerKey xsi:nil="true"/>' +
189
- '<ID>' + email_id.to_s + '</ID>' +
190
- '<ObjectID xsi:nil="true"/>' +
191
- '</Email>' +
192
- '<List>' +
193
- '<PartnerKey xsi:nil="true"/>' +
194
- '<ObjectID xsi:nil="true"/>' +
195
- '<ID>' + list_id.to_s + '</ID>' +
196
- '</List>' +
197
- '</Objects>'
198
- end
199
-
200
- def prepare_delete_email(email_id, account=nil)
201
- account ||= @account
202
- create_delete_email_object(email_id, account)
203
- end
204
-
205
- def create_delete_email_object(email_id, account)
206
- '<Objects xsi:type="Email">' +
207
- '<Client>' +
208
- '<ID>' + account.to_s + '</ID>' +
209
- '</Client>' +
210
- '<ID>' + email_id.to_s + '</ID>' +
211
- '<ObjectID xsi:nil="true"/>' +
212
- '</Objects>'
213
- end
214
- end
215
- end