dotmailer 0.0.1 → 0.0.2

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.
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ describe DotMailer::DataField do
4
+ describe 'Class' do
5
+ let(:client) { double 'client' }
6
+ let(:account) { double 'account', :client => client }
7
+
8
+ subject { DotMailer::DataField }
9
+
10
+ describe '.all' do
11
+ let(:data_fields) {
12
+ [
13
+ {
14
+ 'name' => 'FIRSTNAME',
15
+ 'type' => 'String',
16
+ 'visibility' => 'Public',
17
+ 'defaultValue' => 'John'
18
+ },
19
+ {
20
+ 'name' => 'CODE',
21
+ 'type' => 'String',
22
+ 'visibility' => 'Private',
23
+ 'defaultValue' => nil
24
+ }
25
+ ]
26
+ }
27
+
28
+ before(:each) do
29
+ client.stub :get => data_fields
30
+ end
31
+
32
+ it 'should get the fields from the client' do
33
+ client.should_receive(:get).with('/data-fields')
34
+
35
+ subject.all account
36
+ end
37
+
38
+ it 'should return a list of DataFields from the client' do
39
+ subject.all(account).should == data_fields.map { |df| subject.new(df) }
40
+ end
41
+ end
42
+
43
+ describe '.create' do
44
+ let(:name) { 'FIRSTNAME' }
45
+
46
+ let(:data_field) do
47
+ {
48
+ 'name' => name,
49
+ 'type' => 'String',
50
+ 'visibility' => 'Public',
51
+ 'defaultValue' => nil
52
+ }
53
+ end
54
+
55
+ before(:each) do
56
+ client.stub :post_json => data_field
57
+ end
58
+
59
+ it 'should call post_json on the client with the field' do
60
+ client.should_receive(:post_json).with('/data-fields', data_field)
61
+
62
+ subject.create account, name
63
+ end
64
+ end
65
+ end
66
+
67
+ let(:name) { 'FIRSTNAME' }
68
+ let(:type) { 'String' }
69
+ let(:visibility) { 'Public' }
70
+ let(:default) { 'John' }
71
+
72
+ let(:attributes) do
73
+ {
74
+ 'name' => name,
75
+ 'type' => type,
76
+ 'visibility' => visibility,
77
+ 'defaultValue' => default
78
+ }
79
+ end
80
+
81
+ subject { DotMailer::DataField.new(attributes) }
82
+
83
+ its(:name) { should == name }
84
+ its(:type) { should == type }
85
+ its(:visibility) { should == visibility }
86
+ its(:default) { should == default }
87
+
88
+ its(:to_s) { should == 'DotMailer::DataField name: "FIRSTNAME", type: "String", visibility: "Public", default: "John"' }
89
+
90
+ its(:to_json) { should == attributes.to_json }
91
+
92
+ describe '#==' do
93
+ specify { subject.should == DotMailer::DataField.new(attributes) }
94
+ end
95
+
96
+ describe '#date?' do
97
+ context 'when type is "Date"' do
98
+ let(:type) { 'Date' }
99
+
100
+ specify { subject.should be_date }
101
+ end
102
+
103
+ context 'when type is not "Date"' do
104
+ let(:type) { 'String' }
105
+
106
+ specify { subject.should_not be_date }
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe DotMailer::OptInType do
4
+ describe 'Class' do
5
+ subject { DotMailer::OptInType }
6
+
7
+ describe '.exists?' do
8
+ context 'when the opt in type exists' do
9
+ let(:opt_in_type) { DotMailer::OptInType::SINGLE }
10
+
11
+ specify { subject.exists?(opt_in_type).should be_true }
12
+ end
13
+
14
+ context 'when the opt in type doesnt exist' do
15
+ let(:opt_in_type) { 'Something Random' }
16
+
17
+ specify { subject.exists?(opt_in_type).should be_false }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe DotMailer::Suppression do
4
+ let(:client) { double 'client' }
5
+ let(:account) { double 'account', :client => client }
6
+ let(:contact_attributes) { double 'contact attributes' }
7
+ let(:date_removed) { '2013-03-01T15:30:45Z' }
8
+ let(:reason) { double 'reason' }
9
+ let(:contact) { double 'contact' }
10
+
11
+ subject do
12
+ DotMailer::Suppression.new(
13
+ account,
14
+ 'suppressedContact' => contact_attributes,
15
+ 'dateRemoved' => date_removed,
16
+ 'reason' => reason
17
+ )
18
+ end
19
+
20
+ before(:each) do
21
+ DotMailer::Contact.stub(:new).with(account, contact_attributes).and_return(contact)
22
+ end
23
+
24
+ its(:contact) { should == contact }
25
+ its(:date_removed) { should == Time.parse('1st March 2013 15:30:45 +00:00') }
26
+ its(:reason) { should == reason }
27
+
28
+ describe 'Class' do
29
+ subject { DotMailer::Suppression }
30
+
31
+ describe '.suppressed_since' do
32
+ let(:time) { Time.parse('1st February 2013 15:30:45 +00:00') }
33
+ let(:suppression) { double 'suppression' }
34
+
35
+ let(:attributes) do
36
+ {
37
+ 'suppressedContact' => contact_attributes,
38
+ 'dateRemoved' => date_removed,
39
+ 'reason' => reason
40
+ }
41
+ end
42
+
43
+ let(:response) { 3.times.map { attributes } }
44
+
45
+ before(:each) do
46
+ client.stub :get => response
47
+ subject.stub :new => suppression
48
+ end
49
+
50
+ it 'should call get on the client with a path containing the time in UTC XML schema format' do
51
+ client.should_receive(:get).with('/contacts/suppressed-since/2013-02-01T15:30:45Z')
52
+
53
+ subject.suppressed_since(account, time)
54
+ end
55
+
56
+ it 'should initialize some suppressions' do
57
+ subject.should_receive(:new).exactly(3).times.with(account, attributes)
58
+
59
+ subject.suppressed_since(account, time)
60
+ end
61
+
62
+ it 'should return the suppressions' do
63
+ subject.suppressed_since(account, time).should == 3.times.map { suppression }
64
+ end
65
+ end
66
+ end
67
+ end
@@ -7,7 +7,9 @@
7
7
 
8
8
  require 'webmock/rspec'
9
9
 
10
- require 'dotmailer'
10
+ require 'dot_mailer'
11
+
12
+ require 'support/assignable_attributes_helper'
11
13
 
12
14
  RSpec.configure do |config|
13
15
  config.treat_symbols_as_metadata_keys_with_true_values = true
@@ -19,4 +21,6 @@ RSpec.configure do |config|
19
21
  # the seed, which is printed after each run.
20
22
  # --seed 1234
21
23
  config.order = 'random'
24
+
25
+ config.include AssignableAttributesHelper
22
26
  end
@@ -0,0 +1,20 @@
1
+ require 'active_support/concern'
2
+
3
+ module AssignableAttributesHelper
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ # A helper method for checking if an Object has an assignable attribute
8
+ # (i.e. that object.foo = 'bar' changes object.foo to 'bar')
9
+ def it_should_have_assignable_attributes(*attributes)
10
+ attributes.each do |attribute|
11
+ let(:new_value) { double 'new value' }
12
+
13
+ specify do
14
+ expect { subject.public_send("#{attribute}=", new_value) }.to \
15
+ change { subject.public_send(attribute) }.to(new_value)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dotmailer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-22 00:00:00.000000000 Z
12
+ date: 2013-03-26 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
14
30
  - !ruby/object:Gem::Dependency
15
31
  name: rest-client
16
32
  requirement: !ruby/object:Gem::Requirement
@@ -70,15 +86,28 @@ files:
70
86
  - Gemfile
71
87
  - README.md
72
88
  - Rakefile
89
+ - TODO.md
73
90
  - dotmailer.gemspec
91
+ - lib/dot_mailer.rb
92
+ - lib/dot_mailer/account.rb
93
+ - lib/dot_mailer/client.rb
94
+ - lib/dot_mailer/contact.rb
95
+ - lib/dot_mailer/contact_import.rb
96
+ - lib/dot_mailer/data_field.rb
97
+ - lib/dot_mailer/exceptions.rb
98
+ - lib/dot_mailer/opt_in_type.rb
99
+ - lib/dot_mailer/suppression.rb
100
+ - lib/dot_mailer/version.rb
74
101
  - lib/dotmailer.rb
75
- - lib/dotmailer/client.rb
76
- - lib/dotmailer/data_field.rb
77
- - lib/dotmailer/exceptions.rb
78
- - lib/dotmailer/version.rb
79
- - spec/dotmailer/client_spec.rb
80
- - spec/dotmailer/data_field_spec.rb
102
+ - spec/dot_mailer/account_spec.rb
103
+ - spec/dot_mailer/client_spec.rb
104
+ - spec/dot_mailer/contact_import_spec.rb
105
+ - spec/dot_mailer/contact_spec.rb
106
+ - spec/dot_mailer/data_field_spec.rb
107
+ - spec/dot_mailer/opt_in_type_spec.rb
108
+ - spec/dot_mailer/suppression_spec.rb
81
109
  - spec/spec_helper.rb
110
+ - spec/support/assignable_attributes_helper.rb
82
111
  homepage: https://github.com/econsultancy/dotmailer
83
112
  licenses: []
84
113
  post_install_message:
@@ -1,78 +0,0 @@
1
- require 'cgi'
2
- require 'json'
3
- require 'csv'
4
- require 'restclient'
5
-
6
- module Dotmailer
7
- class Client
8
- def initialize(api_user, api_pass)
9
- self.api_user = api_user
10
- self.api_pass = api_pass
11
- end
12
-
13
- def get_data_fields
14
- fields = get 'data-fields'
15
-
16
- fields.map { |attributes| DataField.new(attributes) }
17
- end
18
-
19
- def create_data_field(name, options = {})
20
- options[:type] ||= 'String'
21
- options[:visibility] ||= 'Public'
22
-
23
- post_json(
24
- 'data-fields',
25
- 'name' => name,
26
- 'type' => options[:type],
27
- 'visibility' => options[:visibility],
28
- 'defaultValue' => options[:default]
29
- )
30
-
31
- true
32
- rescue RestClient::BadRequest
33
- raise DuplicateDataField
34
- end
35
-
36
- def import_contacts(headers, contacts)
37
- csv = CSV.generate do |csv|
38
- csv << headers
39
-
40
- contacts.each do |contact|
41
- csv << headers.map { |header| contact[header] }
42
- end
43
- end
44
-
45
- post 'contacts/import', csv, :content_type => :csv
46
- end
47
-
48
- def import_status(import_id)
49
- response = get "contacts/import/#{import_id}"
50
-
51
- response['status']
52
- end
53
-
54
- private
55
- attr_accessor :api_user, :api_pass
56
-
57
- def get(path)
58
- JSON.parse RestClient.get url(path), :accept => :json
59
- end
60
-
61
- def post_json(path, params)
62
- post path, params.to_json, :content_type => :json
63
- end
64
-
65
- def post(path, data, options = {})
66
- JSON.parse RestClient.post url(path), data, options.merge(:accept => :json)
67
- end
68
-
69
- def url(path)
70
- URI::Generic.build(
71
- :scheme => 'https',
72
- :userinfo => "#{CGI.escape(api_user)}:#{api_pass}",
73
- :host => 'api.dotmailer.com',
74
- :path => "/v2/#{path}"
75
- ).to_s
76
- end
77
- end
78
- end
@@ -1,4 +0,0 @@
1
- module Dotmailer
2
- class DuplicateDataField < Exception
3
- end
4
- end
@@ -1,3 +0,0 @@
1
- module Dotmailer
2
- VERSION = "0.0.1"
3
- end
@@ -1,159 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Dotmailer::Client do
4
- let(:api_user) { 'john_doe' }
5
- let(:api_pass) { 's3cr3t' }
6
- let(:api_base_url) { "https://#{api_user}:#{api_pass}@api.dotmailer.com" }
7
-
8
- subject { Dotmailer::Client.new(api_user, api_pass) }
9
-
10
- context 'data fields' do
11
- let(:data_fields_endpoint) do
12
- "#{api_base_url}/v2/data-fields"
13
- end
14
-
15
- describe '#get_data_fields' do
16
- let(:data_fields) do
17
- [
18
- Dotmailer::DataField.new(
19
- 'name' => 'FIRSTNAME',
20
- 'type' => 'String',
21
- 'visibility' => 'Public',
22
- 'defaultValue' => 'John'
23
- ),
24
- Dotmailer::DataField.new(
25
- 'name' => 'CODE',
26
- 'type' => 'String',
27
- 'visibility' => 'Private',
28
- 'defaultValue' => nil
29
- )
30
- ]
31
- end
32
-
33
- before(:each) do
34
- stub_request(:get, data_fields_endpoint).to_return(:body => data_fields.to_json)
35
- end
36
-
37
- it 'should get the fields from the data fields endpoint' do
38
- subject.get_data_fields
39
-
40
- WebMock.should have_requested(:get, data_fields_endpoint).with(
41
- :headers => { 'Accept' => 'application/json' }
42
- )
43
- end
44
-
45
- it 'should return the data fields from the data fields endpoint' do
46
- subject.get_data_fields.should == data_fields
47
- end
48
- end
49
-
50
- describe '#create_data_field' do
51
- let(:name) { 'FIRSTNAME' }
52
-
53
- let(:data_field_json) do
54
- {
55
- 'name' => name,
56
- 'type' => 'String',
57
- 'visibility' => 'Public',
58
- 'defaultValue' => nil
59
- }.to_json
60
- end
61
-
62
- before(:each) do
63
- stub_request(:post, data_fields_endpoint).to_return(:body => data_field_json)
64
- end
65
-
66
- it 'should post the field to the data fields endpoint' do
67
- subject.create_data_field name
68
-
69
- WebMock.should have_requested(:post, data_fields_endpoint).with(
70
- :body => data_field_json,
71
- :headers => {
72
- 'Accept' => 'application/json',
73
- 'Content-Type' => 'application/json'
74
- }
75
- )
76
- end
77
-
78
- context 'when the field doesnt exist' do
79
- it 'should return true' do
80
- subject.create_data_field(name).should == true
81
- end
82
- end
83
-
84
- context 'when the field already exists' do
85
- before(:each) do
86
- stub_request(:post, data_fields_endpoint).to_return(:status => 400)
87
- end
88
-
89
- it 'should raise an error' do
90
- expect { subject.create_data_field(name) }.to raise_error(Dotmailer::DuplicateDataField)
91
- end
92
- end
93
- end
94
- end
95
-
96
- context 'contacts' do
97
- describe '#import_contacts' do
98
- let(:contact_import_endpoint) do
99
- "#{api_base_url}/v2/contacts/import"
100
- end
101
-
102
- let(:headers) { ['Email'] }
103
-
104
- let(:contacts) do
105
- [
106
- { 'Email' => 'john.doe@example.com' }
107
- ]
108
- end
109
-
110
- let(:contacts_csv) { "Email\njohn.doe@example.com\n" }
111
-
112
- let(:response) { { 'id' => '123', 'status' => 'Finished' } }
113
-
114
- before(:each) do
115
- stub_request(:post, contact_import_endpoint).to_return(:body => response.to_json)
116
- end
117
-
118
- it 'should post the contacts in CSV format to the contact import endpoint' do
119
- subject.import_contacts ['Email'], contacts
120
-
121
- WebMock.should have_requested(:post, contact_import_endpoint).with(
122
- :body => contacts_csv,
123
- :headers => {
124
- 'Accept' => 'application/json',
125
- 'Content-Type' => 'text/csv'
126
- }
127
- )
128
- end
129
- end
130
-
131
- describe '#import_status' do
132
- let(:import_id) { 123 }
133
-
134
- let(:import_status_endpoint) do
135
- "#{api_base_url}/v2/contacts/import/#{import_id}"
136
- end
137
-
138
- let(:status) { 'Finished' }
139
-
140
- let(:response) { { 'id' => import_id, 'status' => status } }
141
-
142
- before(:each) do
143
- stub_request(:get, import_status_endpoint).to_return(:body => response.to_json )
144
- end
145
-
146
- it 'should get the import status from the import status endpoint' do
147
- subject.import_status import_id
148
-
149
- WebMock.should have_requested(:get, import_status_endpoint).with(
150
- :headers => { 'Accept' => 'application/json' }
151
- )
152
- end
153
-
154
- it 'should return the status from the import status endpoint' do
155
- subject.import_status(import_id).should == status
156
- end
157
- end
158
- end
159
- end