dotmailer 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,173 @@
1
+ require 'spec_helper'
2
+
3
+ describe DotMailer::ContactImport do
4
+ let(:client) { double 'client' }
5
+ let(:account) { double 'account', :client => client }
6
+
7
+ let(:contacts) do
8
+ [
9
+ { 'Email' => 'john.doe@example.com' }
10
+ ]
11
+ end
12
+
13
+ describe 'Class' do
14
+ subject { DotMailer::ContactImport }
15
+
16
+ describe '.import' do
17
+ let(:contact_import) { double 'contact import', :start => double }
18
+
19
+ before(:each) do
20
+ subject.stub :new => contact_import
21
+ end
22
+
23
+ it 'should create a new instance with the account and contacts' do
24
+ subject.should_receive(:new).with(account, contacts)
25
+
26
+ subject.import account, contacts
27
+ end
28
+
29
+ it 'should start the new contact import' do
30
+ contact_import.should_receive :start
31
+
32
+ subject.import account, contacts
33
+ end
34
+
35
+ it 'should return the contact import' do
36
+ subject.import(account, contacts).should == contact_import
37
+ end
38
+ end
39
+ end
40
+
41
+ subject { DotMailer::ContactImport.new(account, contacts) }
42
+
43
+ its(:id) { should be_nil }
44
+
45
+ describe '#start' do
46
+ before(:each) do
47
+ account.stub :data_fields => [double('data field', :name => 'CODE')]
48
+ end
49
+
50
+ context 'when the contacts include a non existent data field' do
51
+ let(:data_field_name) { 'UNKNOWN' }
52
+
53
+ let(:contacts) do
54
+ [
55
+ { 'Email' => 'john.doe@example.com', data_field_name => 'some value' }
56
+ ]
57
+ end
58
+
59
+ it 'should raise an UnknownDataField error with the data field name' do
60
+ expect { subject.start }.to raise_error(DotMailer::UnknownDataField, data_field_name)
61
+ end
62
+ end
63
+
64
+ let(:contacts_csv) { "Email\njohn.doe@example.com\n" }
65
+ let(:id) { double 'id' }
66
+ let(:response) { { 'id' => id, 'status' => 'NotFinished' } }
67
+
68
+ before(:each) do
69
+ client.stub :post_csv => response
70
+ end
71
+
72
+ it 'should call post_csv on the client with the contacts in CSV format' do
73
+ client.should_receive(:post_csv).with('/contacts/import', contacts_csv)
74
+
75
+ subject.start
76
+ end
77
+
78
+ it 'should set the id from the response' do
79
+ subject.start
80
+ subject.id.should == id
81
+ end
82
+ end
83
+
84
+ describe '#status' do
85
+ before(:each) do
86
+ subject.stub :id => id
87
+ end
88
+
89
+ context 'when the import has not started' do
90
+ let(:id) { nil }
91
+
92
+ its(:status) { should == 'NotStarted' }
93
+ end
94
+
95
+ context 'when the import has started' do
96
+ let(:id) { '12345' }
97
+ let(:status) { double 'status' }
98
+ let(:response) { { 'id' => id, 'status' => status } }
99
+
100
+ before(:each) do
101
+ client.stub :get => response
102
+ end
103
+
104
+ it 'should get the status from the client' do
105
+ client.should_receive(:get).with("/contacts/import/#{id}")
106
+
107
+ subject.status
108
+ end
109
+
110
+ it 'should return the status from the client' do
111
+ subject.status.should == status
112
+ end
113
+ end
114
+ end
115
+
116
+ describe '#finished?' do
117
+ context 'when the import status is not "Finished"' do
118
+ before(:each) do
119
+ subject.stub :status => 'NotFinished'
120
+ end
121
+
122
+ specify { subject.should_not be_finished }
123
+ end
124
+
125
+ context 'when the import status is "Finished"' do
126
+ before(:each) do
127
+ subject.stub :status => 'Finished'
128
+ end
129
+
130
+ specify { subject.should be_finished }
131
+ end
132
+ end
133
+
134
+ describe '#errors' do
135
+ let(:id) { '12345' }
136
+
137
+ before(:each) do
138
+ subject.stub :id => id
139
+ end
140
+
141
+ context 'when the import has no yet finished' do
142
+ before(:each) do
143
+ subject.stub :finished? => false
144
+ end
145
+
146
+ it 'should raise an ImportNotFinished error' do
147
+ expect { subject.errors }.to raise_error(DotMailer::ImportNotFinished)
148
+ end
149
+ end
150
+
151
+ context 'when the import has finished' do
152
+ before(:each) do
153
+ subject.stub :finished? => true
154
+ end
155
+
156
+ let(:errors) { double 'errors' }
157
+
158
+ before(:each) do
159
+ client.stub :get_csv => errors
160
+ end
161
+
162
+ it 'should call get_csv on the client with the import id in the path' do
163
+ client.should_receive(:get_csv).with("/contacts/import/#{id}/report-faults")
164
+
165
+ subject.errors
166
+ end
167
+
168
+ it 'should return the status from the client' do
169
+ subject.errors.should == errors
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,303 @@
1
+ require 'spec_helper'
2
+
3
+ describe DotMailer::Contact do
4
+ let(:client) { double 'client' }
5
+ let(:account) { double 'account', :client => client }
6
+
7
+ describe 'Class' do
8
+ subject { DotMailer::Contact }
9
+
10
+ describe '.find_by_email' do
11
+ let(:email) { 'john.doe@example.com' }
12
+ let(:response) { double 'response' }
13
+ let(:contact) { double 'contact' }
14
+
15
+ before(:each) do
16
+ client.stub :get => response
17
+ subject.stub :new => contact
18
+ end
19
+
20
+ it 'should get the contact from the client' do
21
+ client.should_receive(:get).with("/contacts/#{email}")
22
+
23
+ subject.find_by_email account, email
24
+ end
25
+
26
+ it 'should initialize a new Contact with the response from the client' do
27
+ subject.should_receive(:new).with(account, response)
28
+
29
+ subject.find_by_email account, email
30
+ end
31
+
32
+ it 'should return the new Contact object' do
33
+ subject.find_by_email(account, email).should == contact
34
+ end
35
+
36
+ context 'when the contact doesnt exist' do
37
+ before(:each) do
38
+ client.stub(:get).and_raise(DotMailer::NotFound)
39
+ end
40
+
41
+ it 'should return nil' do
42
+ subject.find_by_email(account, email).should be_nil
43
+ end
44
+ end
45
+ end
46
+
47
+ describe '.find_by_id' do
48
+ let(:id) { 123 }
49
+ let(:contact) { double 'contact' }
50
+
51
+ before(:each) do
52
+ subject.stub :find_by_email => contact
53
+ end
54
+
55
+ it 'should call find_by_email with the id' do
56
+ subject.should_receive(:find_by_email).with(account, id)
57
+
58
+ subject.find_by_id account, id
59
+ end
60
+
61
+ it 'should return the contact from find_by_email' do
62
+ subject.find_by_id(account, id).should == contact
63
+ end
64
+ end
65
+
66
+ describe '.modified_since' do
67
+ let(:time) { Time.parse('1st March 2013 15:30:45 +00:00') }
68
+ let(:attributes) { double 'attributes' }
69
+ let(:response) { 3.times.map { attributes } }
70
+ let(:contact) { double 'contact' }
71
+
72
+ before(:each) do
73
+ client.stub :get => response
74
+ subject.stub :new => contact
75
+ end
76
+
77
+ it 'should call get on the client with a path containing the time in UTC XML schema format' do
78
+ client.should_receive(:get).with('/contacts/modified-since/2013-03-01T15:30:45Z')
79
+
80
+ subject.modified_since(account, time)
81
+ end
82
+
83
+ it 'should initialize some contacts' do
84
+ subject.should_receive(:new).exactly(3).times.with(account, attributes)
85
+
86
+ subject.modified_since(account, time)
87
+ end
88
+
89
+ it 'should return the contacts' do
90
+ subject.modified_since(account, time).should == 3.times.map { contact }
91
+ end
92
+ end
93
+ end
94
+
95
+ let(:id) { double 'id' }
96
+ let(:email) { double 'email' }
97
+ let(:opt_in_type) { double 'opt in type' }
98
+ let(:email_type) { double 'email type' }
99
+ let(:status) { double 'status' }
100
+
101
+ let(:attributes) do
102
+ {
103
+ 'id' => id,
104
+ 'email' => email,
105
+ 'optInType' => opt_in_type,
106
+ 'emailType' => email_type,
107
+ 'status' => status
108
+ }
109
+ end
110
+
111
+ subject { DotMailer::Contact.new(account, attributes) }
112
+
113
+ its(:id) { should == id }
114
+ its(:email) { should == email }
115
+ its(:opt_in_type) { should == opt_in_type }
116
+ its(:email_type) { should == email_type }
117
+ its(:status) { should == status }
118
+
119
+ it_should_have_assignable_attributes :email, :email_type
120
+
121
+ describe '#opt_in_type=' do
122
+ let(:value) { 'some opt in type' }
123
+
124
+ context 'when the opt in type exists' do
125
+ before(:each) do
126
+ DotMailer::OptInType.stub :exists? => true
127
+ end
128
+
129
+ it 'should change the opt in type' do
130
+ expect { subject.opt_in_type = value }.to \
131
+ change { subject.opt_in_type }.to(value)
132
+ end
133
+ end
134
+
135
+ context 'when the opt in type doesnt exist' do
136
+ before(:each) do
137
+ DotMailer::OptInType.stub :exists? => false
138
+ end
139
+
140
+ it 'should raise an UnknownOptInType error with the value' do
141
+ expect { subject.opt_in_type = value }.to \
142
+ raise_error(DotMailer::UnknownOptInType, value)
143
+ end
144
+ end
145
+ end
146
+
147
+ describe '#[]' do
148
+ let(:data_fields) { {} }
149
+
150
+ before(:each) do
151
+ subject.stub :data_fields => data_fields
152
+ end
153
+
154
+ context 'when the data field doesnt exist' do
155
+ let(:key) { 'UNKNOWN' }
156
+
157
+ it 'should raise an UnknownDataField error' do
158
+ expect { subject[key] }.to raise_error(DotMailer::UnknownDataField)
159
+ end
160
+ end
161
+
162
+ context 'when the data field does exist' do
163
+ let(:key) { double 'key' }
164
+ let(:value) { double 'value' }
165
+ let(:data_fields) { { key => value } }
166
+
167
+ specify { subject[key].should == value }
168
+ end
169
+ end
170
+
171
+ describe '#[]=' do
172
+ let(:new_value) { double 'new value' }
173
+
174
+ let(:data_fields) { {} }
175
+
176
+ before(:each) do
177
+ subject.stub :data_fields => data_fields
178
+ end
179
+
180
+ context 'when the data field doesnt exist' do
181
+ let(:key) { 'UNKNOWN' }
182
+
183
+ it 'should raise an UnknownDataField error' do
184
+ expect { subject[key] = new_value }.to raise_error(DotMailer::UnknownDataField)
185
+ end
186
+ end
187
+
188
+ context 'when the data field does exist' do
189
+ let(:key) { double 'key' }
190
+ let(:old_value) { double 'old value' }
191
+ let(:data_fields) { { key => old_value } }
192
+
193
+ specify do
194
+ expect { subject[key] = new_value }.to \
195
+ change { subject[key] }.from(old_value).to(new_value)
196
+ end
197
+ end
198
+ end
199
+
200
+ describe '#save' do
201
+ let(:id) { '12345' }
202
+ let(:key) { double 'key' }
203
+ let(:value) { 'some value' }
204
+ let(:data_fields) { { key => value } }
205
+
206
+ before(:each) do
207
+ client.stub :put_json
208
+ subject.stub :data_fields => data_fields
209
+ end
210
+
211
+ it 'should call put_json on the client with the id path' do
212
+ client.should_receive(:put_json).with("/contacts/#{id}", anything)
213
+
214
+ subject.save
215
+ end
216
+
217
+ it 'should call put_json on the client with the attributes in the correct format' do
218
+ client.should_receive(:put_json).with(anything, {
219
+ 'id' => id,
220
+ 'email' => email,
221
+ 'optInType' => opt_in_type,
222
+ 'emailType' => email_type,
223
+ 'status' => status,
224
+ 'dataFields' => [
225
+ { 'key' => key, 'value' => value }
226
+ ]
227
+ })
228
+
229
+ subject.save
230
+ end
231
+ end
232
+
233
+ describe '#subscribed?' do
234
+ context 'when the status is the SUBSCRIBED_STATUS' do
235
+ let(:status) { DotMailer::SUBSCRIBED_STATUS }
236
+
237
+ it { should be_subscribed }
238
+ end
239
+
240
+ context 'when the status is not the SUBSCRIBED_STATUS' do
241
+ let(:status) { 'Unsubscribed' }
242
+
243
+ it { should_not be_subscribed }
244
+ end
245
+ end
246
+
247
+ describe '#resubscribe' do
248
+ let(:return_url) { 'some return url' }
249
+ let(:client) { double 'client' }
250
+
251
+ before(:each) do
252
+ subject.stub :client => client
253
+ end
254
+
255
+ context 'when the contact is already subscribed' do
256
+ before(:each) do
257
+ subject.stub :subscribed? => true
258
+ end
259
+
260
+ it 'should not call put_json on the client' do
261
+ client.should_not_receive(:put_json)
262
+
263
+ subject.resubscribe return_url
264
+ end
265
+
266
+ it 'should return false' do
267
+ subject.resubscribe(return_url).should be_false
268
+ end
269
+ end
270
+
271
+ context 'when the contact is not subscribed' do
272
+ before(:each) do
273
+ client.stub :post_json
274
+ subject.stub :subscribed? => false
275
+ end
276
+
277
+ it 'should call post_json on the client with the correct path' do
278
+ client.should_receive(:post_json).with("/contacts/resubscribe", anything)
279
+
280
+ subject.resubscribe return_url
281
+ end
282
+
283
+ it 'should call post_json on the client with the contacts id and email address' do
284
+ client.should_receive(:post_json).with anything, hash_including(
285
+ 'UnsubscribedContact' => {
286
+ 'id' => id,
287
+ 'Email' => email
288
+ }
289
+ )
290
+
291
+ subject.resubscribe return_url
292
+ end
293
+
294
+ it 'should call post_json on the client with the return url' do
295
+ client.should_receive(:post_json).with anything, hash_including(
296
+ 'ReturnUrlToUseIfChallenged' => return_url
297
+ )
298
+
299
+ subject.resubscribe return_url
300
+ end
301
+ end
302
+ end
303
+ end