createsend 4.0.2 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/HISTORY.md +4 -0
- data/LICENSE +1 -1
- data/createsend.gemspec +1 -0
- data/lib/createsend.rb +3 -0
- data/lib/createsend/transactional_classic_email.rb +32 -0
- data/lib/createsend/transactional_smart_email.rb +31 -0
- data/lib/createsend/transactional_timeline.rb +45 -0
- data/lib/createsend/version.rb +1 -1
- data/test/fixtures/tx_classicemail_groups.json +14 -0
- data/test/fixtures/tx_message_details.json +36 -0
- data/test/fixtures/tx_message_details_with_statistics.json +72 -0
- data/test/fixtures/tx_messages.json +38 -0
- data/test/fixtures/tx_messages_classic.json +15 -0
- data/test/fixtures/tx_messages_smart.json +15 -0
- data/test/fixtures/tx_resend_message.json +6 -0
- data/test/fixtures/tx_send_multiple.json +12 -0
- data/test/fixtures/tx_send_single.json +7 -0
- data/test/fixtures/tx_smartemail_details.json +23 -0
- data/test/fixtures/tx_smartemails.json +15 -0
- data/test/fixtures/tx_statistics_classic.json +14 -0
- data/test/fixtures/tx_statistics_smart.json +14 -0
- data/test/transactional_classic_email_test.rb +60 -0
- data/test/transactional_smart_email_test.rb +83 -0
- data/test/transactional_timeline_test.rb +110 -0
- metadata +52 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83c11f38273068f99455b389075f882b24d9a17b
|
4
|
+
data.tar.gz: cfcd57555d0656ceddd52d6fc64f5762bbd00820
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 790ac1bd3644138ca49adda8c2ad284cb7d222fb84cb831a82704cf5a36a89142902b73f3f824908a82e848d17af34bbd03ea0887f5895330a5b12110b196c03
|
7
|
+
data.tar.gz: 57df8eeda52d4aba84e938b3165ef14592027fc7deafd1881ca255baf59223309148853fcdc5554dd1bb35d560e9eb56d92c7add1d5bfe4541eb3d73e89a4b15
|
data/.travis.yml
CHANGED
data/HISTORY.md
CHANGED
data/LICENSE
CHANGED
data/createsend.gemspec
CHANGED
@@ -13,6 +13,7 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.add_development_dependency 'shoulda-context', '~> 1.2'
|
14
14
|
s.add_development_dependency 'simplecov', '~> 0'
|
15
15
|
s.add_development_dependency 'coveralls', '~> 0'
|
16
|
+
s.add_development_dependency 'test-unit', '~>3.0'
|
16
17
|
s.name = "createsend"
|
17
18
|
s.author = "James Dennes"
|
18
19
|
s.description = %q{Implements the complete functionality of the Campaign Monitor API.}
|
data/lib/createsend.rb
CHANGED
@@ -11,3 +11,6 @@ require 'createsend/subscriber'
|
|
11
11
|
require 'createsend/template'
|
12
12
|
require 'createsend/person'
|
13
13
|
require 'createsend/administrator'
|
14
|
+
require 'createsend/transactional_classic_email'
|
15
|
+
require 'createsend/transactional_smart_email'
|
16
|
+
require 'createsend/transactional_timeline'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module CreateSend
|
2
|
+
module Transactional
|
3
|
+
class ClassicEmail < CreateSend
|
4
|
+
attr_accessor :options
|
5
|
+
|
6
|
+
def initialize(auth, client_id = nil)
|
7
|
+
@auth = auth
|
8
|
+
@client_id = client_id
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def send(options)
|
13
|
+
response = post "/transactional/classicemail/send", { :body => options.to_json , :query => client_id }
|
14
|
+
response.map{|item| Hashie::Mash.new(item)}
|
15
|
+
end
|
16
|
+
|
17
|
+
def groups
|
18
|
+
response = get "/transactional/classicemail/groups", :query => client_id
|
19
|
+
response.map{|item| Hashie::Mash.new(item)}
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def client_id
|
25
|
+
{:clientID => @client_id} if @client_id
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module CreateSend
|
2
|
+
module Transactional
|
3
|
+
class SmartEmail < CreateSend
|
4
|
+
attr_reader :smart_email_id
|
5
|
+
|
6
|
+
def self.list(auth, options = nil)
|
7
|
+
cs = CreateSend.new auth
|
8
|
+
response = cs.get "/transactional/smartemail", :query => options
|
9
|
+
response.map{|item| Hashie::Mash.new(item)}
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(auth, smart_email_id)
|
13
|
+
@auth = auth
|
14
|
+
@smart_email_id = smart_email_id
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
def details
|
19
|
+
response = get "/transactional/smartemail/#{@smart_email_id}"
|
20
|
+
Hashie::Mash.new(response)
|
21
|
+
end
|
22
|
+
|
23
|
+
def send(options)
|
24
|
+
response = post "/transactional/smartemail/#{@smart_email_id}/send", { :body => options.to_json }
|
25
|
+
response.map{|item| Hashie::Mash.new(item)}
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module CreateSend
|
2
|
+
module Transactional
|
3
|
+
class Timeline < CreateSend
|
4
|
+
attr_reader :client_id
|
5
|
+
|
6
|
+
def initialize(auth, client_id = nil)
|
7
|
+
@auth = auth
|
8
|
+
@client_id = client_id
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def messages(options = {})
|
13
|
+
options = add_client_id(options)
|
14
|
+
response = get "/transactional/messages", { :query => options }
|
15
|
+
response.map{|item| Hashie::Mash.new(item)}
|
16
|
+
end
|
17
|
+
|
18
|
+
def statistics(options = {})
|
19
|
+
options = add_client_id(options)
|
20
|
+
response = get "/transactional/statistics", { :query => options }
|
21
|
+
Hashie::Mash.new(response)
|
22
|
+
end
|
23
|
+
|
24
|
+
def details(message_id, options = {})
|
25
|
+
options = add_client_id(options)
|
26
|
+
response = get "/transactional/messages/#{message_id}", { :query => options }
|
27
|
+
Hashie::Mash.new(response)
|
28
|
+
end
|
29
|
+
|
30
|
+
def resend(message_id)
|
31
|
+
response = post "/transactional/messages/#{message_id}/resend"
|
32
|
+
response.map{|item| Hashie::Mash.new(item)}
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def add_client_id(options)
|
38
|
+
options['clientID'] = @client_id if @client_id
|
39
|
+
options
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
data/lib/createsend/version.rb
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"Group": "Password Reset",
|
4
|
+
"CreatedAt": "2015-03-28T09:41:36+11:00"
|
5
|
+
},
|
6
|
+
{
|
7
|
+
"Group": "Credit card expired",
|
8
|
+
"CreatedAt": "2015-05-04T22:24:12+10:00"
|
9
|
+
},
|
10
|
+
{
|
11
|
+
"Group": "Order shipped",
|
12
|
+
"CreatedAt": "2015-03-29T11:11:52+11:00"
|
13
|
+
}
|
14
|
+
]
|
@@ -0,0 +1,36 @@
|
|
1
|
+
{
|
2
|
+
"MessageID": "ddc697c7-0788-4df3-a71a-a7cb935f00bd",
|
3
|
+
"Status": "Delivered",
|
4
|
+
"SentAt": "2014-01-15T16:09:19-05:00",
|
5
|
+
"SmartEmailID": "c0da9c4c-e7e4-11e4-a74d-6c4008bc7468",
|
6
|
+
"CanBeResent": true,
|
7
|
+
"Recipient": "Joe Smith <joesmith@example.com>",
|
8
|
+
"Message": {
|
9
|
+
"From": "Team Webapp <team@webapp123.com",
|
10
|
+
"Subject": "Thanks for signing up to web app 123",
|
11
|
+
"To": [
|
12
|
+
"Joe Smith <joesmith@example.com>",
|
13
|
+
"jamesmith@example.com"
|
14
|
+
],
|
15
|
+
"CC": [
|
16
|
+
"Joe Smith <joesmith@example.com>"
|
17
|
+
],
|
18
|
+
"BCC": "joesmith@example.com",
|
19
|
+
"Attachments": [
|
20
|
+
{
|
21
|
+
"Name": "Invoice.pdf",
|
22
|
+
"Type": "application/pdf"
|
23
|
+
}
|
24
|
+
],
|
25
|
+
"Body": {
|
26
|
+
"Html": "...",
|
27
|
+
"Text": "..."
|
28
|
+
},
|
29
|
+
"Data": {
|
30
|
+
"new_password_url": "https://www.mywebapp.com/newpassword?uid=jguf45hf74hbf74gf"
|
31
|
+
}
|
32
|
+
},
|
33
|
+
"TotalOpens": 1,
|
34
|
+
"TotalClicks": 1
|
35
|
+
}
|
36
|
+
|
@@ -0,0 +1,72 @@
|
|
1
|
+
{
|
2
|
+
"MessageID": "ddc697c7-0788-4df3-a71a-a7cb935f00bd",
|
3
|
+
"Status": "Delivered",
|
4
|
+
"SentAt": "2014-01-15T16:09:19-05:00",
|
5
|
+
"SmartEmailID": "c0da9c4c-e7e4-11e4-a74d-6c4008bc7468",
|
6
|
+
"CanBeResent": true,
|
7
|
+
"Recipient": "Joe Smith <joesmith@example.com>",
|
8
|
+
"Message": {
|
9
|
+
"From": "Team Webapp <team@webapp123.com",
|
10
|
+
"Subject": "Thanks for signing up to web app 123",
|
11
|
+
"To": [
|
12
|
+
"Joe Smith <joesmith@example.com>",
|
13
|
+
"jamesmith@example.com"
|
14
|
+
],
|
15
|
+
"CC": [
|
16
|
+
"Joe Smith <joesmith@example.com>"
|
17
|
+
],
|
18
|
+
"BCC": "joesmith@example.com",
|
19
|
+
"Attachments": [
|
20
|
+
{
|
21
|
+
"Name": "Invoice.pdf",
|
22
|
+
"Type": "application/pdf"
|
23
|
+
}
|
24
|
+
],
|
25
|
+
"Body": {
|
26
|
+
"Html": "...",
|
27
|
+
"Text": "..."
|
28
|
+
},
|
29
|
+
"Data": {
|
30
|
+
"new_password_url": "https://www.mywebapp.com/newpassword?uid=jguf45hf74hbf74gf"
|
31
|
+
}
|
32
|
+
},
|
33
|
+
"TotalOpens": 1,
|
34
|
+
"TotalClicks": 1,
|
35
|
+
"Opens": [
|
36
|
+
{
|
37
|
+
"EmailAddress": "jamesmith@example.com",
|
38
|
+
"Date": "2009-05-18 16:45:00",
|
39
|
+
"IPAddress": "192.168.0.1",
|
40
|
+
"Geolocation": {
|
41
|
+
"Latitude": -33.8683,
|
42
|
+
"Longitude": 151.2086,
|
43
|
+
"City": "Sydney",
|
44
|
+
"Region": "New South Wales",
|
45
|
+
"CountryCode": "AU",
|
46
|
+
"CountryName": "Australia"
|
47
|
+
},
|
48
|
+
"MailClient": {
|
49
|
+
"Name": "Apple Mail",
|
50
|
+
"OS": "OS X",
|
51
|
+
"Device": "Desktop"
|
52
|
+
}
|
53
|
+
}
|
54
|
+
],
|
55
|
+
"Clicks": [
|
56
|
+
{
|
57
|
+
"EmailAddress": "jamesmith@example.com",
|
58
|
+
"Date": "2009-05-18 16:45:00",
|
59
|
+
"IPAddress": "192.168.0.1",
|
60
|
+
"URL": "http://www.myexammple.com/index.html",
|
61
|
+
"Geolocation": {
|
62
|
+
"Latitude": -33.8683,
|
63
|
+
"Longitude": 151.2086,
|
64
|
+
"City": "Sydney",
|
65
|
+
"Region": "New South Wales",
|
66
|
+
"CountryCode": "AU",
|
67
|
+
"CountryName": "Australia"
|
68
|
+
}
|
69
|
+
}
|
70
|
+
]
|
71
|
+
}
|
72
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"MessageID": "ddc697c7-0788-4df3-a71a-a7cb935f00bd",
|
4
|
+
"Status": "Delivered",
|
5
|
+
"SentAt": "2014-01-15T16:09:19-05:00",
|
6
|
+
"Recipient": "Joe Smith <joesmith@example.com>",
|
7
|
+
"From": "Team <team@company.com>",
|
8
|
+
"Subject": "Ungrouped message",
|
9
|
+
"TotalOpens": 2,
|
10
|
+
"TotalClicks": 4,
|
11
|
+
"CanBeResent": true
|
12
|
+
},
|
13
|
+
{
|
14
|
+
"MessageID": "ddc697c7-0788-4df3-a71a-a7cb935f00bd",
|
15
|
+
"Status": "Delivered",
|
16
|
+
"SentAt": "2014-01-15T16:09:19-05:00",
|
17
|
+
"Recipient": "Joe Smith <joesmith@example.com>",
|
18
|
+
"From": "Team <team@company.com>",
|
19
|
+
"Subject": "Your password has been reset",
|
20
|
+
"TotalOpens": 2,
|
21
|
+
"TotalClicks": 4,
|
22
|
+
"CanBeResent": true,
|
23
|
+
"Group": "Password Reset"
|
24
|
+
},
|
25
|
+
{
|
26
|
+
"MessageID": "ddc697c7-0788-4df3-a71a-a7cb935f00bd",
|
27
|
+
"Status": "Delivered",
|
28
|
+
"SentAt": "2014-01-15T16:09:19-05:00",
|
29
|
+
"Recipient": "Joe Smith <joesmith@example.com>",
|
30
|
+
"From": "Team <team@company.com>",
|
31
|
+
"Subject": "Your credit card has expired",
|
32
|
+
"TotalOpens": 2,
|
33
|
+
"TotalClicks": 4,
|
34
|
+
"CanBeResent": true,
|
35
|
+
"SmartEmailID": "21dab350-f484-11e4-ad38-6c4008bc7468"
|
36
|
+
}
|
37
|
+
]
|
38
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"MessageID": "ddc697c7-0788-4df3-a71a-a7cb935f00bd",
|
4
|
+
"Status": "Delivered",
|
5
|
+
"SentAt": "2014-01-15T16:09:19-05:00",
|
6
|
+
"Recipient": "Joe Smith <joesmith@example.com>",
|
7
|
+
"From": "Team <team@company.com>",
|
8
|
+
"Subject": "Your password has been reset",
|
9
|
+
"TotalOpens": 2,
|
10
|
+
"TotalClicks": 4,
|
11
|
+
"CanBeResent": true,
|
12
|
+
"Group": "Password Reset"
|
13
|
+
}
|
14
|
+
]
|
15
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"MessageID": "ddc697c7-0788-4df3-a71a-a7cb935f00bd",
|
4
|
+
"Status": "Delivered",
|
5
|
+
"SentAt": "2014-01-15T16:09:19-05:00",
|
6
|
+
"Recipient": "Joe Smith <joesmith@example.com>",
|
7
|
+
"From": "Team <team@company.com>",
|
8
|
+
"Subject": "Your credit card has expired",
|
9
|
+
"TotalOpens": 2,
|
10
|
+
"TotalClicks": 4,
|
11
|
+
"CanBeResent": true,
|
12
|
+
"SmartEmailID": "21dab350-f484-11e4-ad38-6c4008bc7468"
|
13
|
+
}
|
14
|
+
]
|
15
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"MessageID": "0cfe150d-d507-11e4-84a7-c31e5b59881d",
|
4
|
+
"Recipient": "\"Bob Sacamano\" <bob@example.com>",
|
5
|
+
"Status": "Received"
|
6
|
+
},
|
7
|
+
{
|
8
|
+
"MessageID": "0cfe150d-d507-11e4-b579-a64eb0d9c74d",
|
9
|
+
"Recipient": "\"Newman\" <newman@example.com>",
|
10
|
+
"Status": "Received"
|
11
|
+
}
|
12
|
+
]
|
@@ -0,0 +1,23 @@
|
|
1
|
+
{
|
2
|
+
"SmartEmailID": "bb4a6ebb-663d-42a0-bdbe-60512cf30a01",
|
3
|
+
"Name": "Reset Password",
|
4
|
+
"CreatedAt": "2015-03-31T16:06:35+11:00",
|
5
|
+
"Status": "active",
|
6
|
+
"Properties": {
|
7
|
+
"From": "\"Team\" <team@example.com>",
|
8
|
+
"ReplyTo": "joe@example.com",
|
9
|
+
"Subject": "[username], your password has been reset!",
|
10
|
+
"Content": {
|
11
|
+
"HTML": "Content managed in Email Builder",
|
12
|
+
"Text": "Content managed in Email Builder",
|
13
|
+
"EmailVariables": [
|
14
|
+
"username",
|
15
|
+
"reset_token"
|
16
|
+
],
|
17
|
+
"InlineCss": true
|
18
|
+
},
|
19
|
+
"TextPreviewUrl": "https://philoye.devcreatesend.com/t/r-9A7A28EE76054977/T",
|
20
|
+
"HtmlPreviewUrl": "https://philoye.devcreatesend.com/t/r-9A7A28EE76054977/"
|
21
|
+
},
|
22
|
+
"AddRecipientsToList": true
|
23
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"ID": "1e654df2-f484-11e4-970c-6c4008bc7468",
|
4
|
+
"Name": "Welcome email",
|
5
|
+
"CreatedAt": "2015-05-15T16:09:19-05:00",
|
6
|
+
"Status": "Active"
|
7
|
+
},
|
8
|
+
{
|
9
|
+
"ID": "21dab350-f484-11e4-ad38-6c4008bc7468",
|
10
|
+
"Name": "Order shipped",
|
11
|
+
"CreatedAt": "2015-05-15T13:29:49-05:00",
|
12
|
+
"Status": "Active"
|
13
|
+
}
|
14
|
+
]
|
15
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TransactionalClassicEmailTest < Test::Unit::TestCase
|
4
|
+
multiple_contexts "authenticated_using_oauth_context", "authenticated_using_api_key_context" do
|
5
|
+
setup do
|
6
|
+
@client_id = "87y8d7qyw8d7yq8w7ydwqwd"
|
7
|
+
@email = CreateSend::Transactional::ClassicEmail.new @auth, @client_id
|
8
|
+
end
|
9
|
+
|
10
|
+
should "send classic email to one recipient" do
|
11
|
+
stub_post(@auth, "transactional/classicemail/send", "tx_send_single.json")
|
12
|
+
email = {
|
13
|
+
"From" => "George <george@example.com>",
|
14
|
+
"Subject" => "Thanks for signing up to Vandelay Industries",
|
15
|
+
"To" => "Bob Sacamano <bob@example.com>",
|
16
|
+
"HTML" => "<h1>Welcome</h1><a href='http://example.com/'>Click here</a>",
|
17
|
+
"Group" => 'Ruby test group'
|
18
|
+
}
|
19
|
+
response = CreateSend::Transactional::ClassicEmail.new(@auth).send(email)
|
20
|
+
response.length.should == 1
|
21
|
+
response[0].Recipient.should == "\"Bob Sacamano\" <bob@example.com>"
|
22
|
+
end
|
23
|
+
|
24
|
+
should "send classic email to with all the options" do
|
25
|
+
stub_post(@auth, "transactional/classicemail/send", "tx_send_multiple.json")
|
26
|
+
email = {
|
27
|
+
"From" => "T-Bone <tbone@example.com>",
|
28
|
+
"ReplyTo" => "george@example.com",
|
29
|
+
"Subject" => "Thanks for signing up to Vandelay Industries",
|
30
|
+
"To" => [
|
31
|
+
"Bob Sacamano <bob@example.com>",
|
32
|
+
"Newman <newman@example.com>",
|
33
|
+
],
|
34
|
+
"CC" => [],
|
35
|
+
"BCC" => [],
|
36
|
+
"HTML" => "<h1>Welcome</h1><a href='http://example.com/'>Click here</a>",
|
37
|
+
"Text" => "Instead of using the auto-generated text from the HTML, you can supply your own.",
|
38
|
+
"Attachments" => [
|
39
|
+
"Name" => "filename.gif",
|
40
|
+
"Type" => "image/gif",
|
41
|
+
"Content" => "R0lGODlhIAAgAKIAAP8AAJmZADNmAMzMAP//AAAAAP///wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMwMTQgNzkuMTU2Nzk3LCAyMDE0LzA4LzIwLTA5OjUzOjAyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxNCAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowNzZGOUNGOUVDRDIxMUU0ODM2RjhGMjNCMTcxN0I2RiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowNzZGOUNGQUVDRDIxMUU0ODM2RjhGMjNCMTcxN0I2RiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjA3NkY5Q0Y3RUNEMjExRTQ4MzZGOEYyM0IxNzE3QjZGIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjA3NkY5Q0Y4RUNEMjExRTQ4MzZGOEYyM0IxNzE3QjZGIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAAIfkEAAAAAAAsAAAAACAAIAAAA5loutz+MKpSpIWU3r1KCBW3eYQmWgWhmiemEgPbNqk6xDOd1XGYV77UzTfbTWC4nAHYQRKLu1VSuXxlpsodAFDAZrfcIbXDFXqhNacoQ3vZpuxHSJZ2zufyTqcunugdd00vQ0F4chQCAgYCaTcxiYuMMhGJFG89kYpFl5MzkoRPnpJskFSaDqctRoBxHEQsdGs0f7Qjq3utDwkAOw=="
|
42
|
+
],
|
43
|
+
"Group" => "Ruby test group",
|
44
|
+
"AddRecipientsToListID" => "6d0366fcee146ab9bdaf3247446bbfdd"
|
45
|
+
}
|
46
|
+
response = CreateSend::Transactional::ClassicEmail.new(@auth).send(email)
|
47
|
+
response.length.should == 2
|
48
|
+
response[1].Recipient.should == "\"Newman\" <newman@example.com>"
|
49
|
+
end
|
50
|
+
|
51
|
+
should "get the list of classic groups" do
|
52
|
+
stub_get(@auth, "transactional/classicemail/groups", "tx_classicemail_groups.json")
|
53
|
+
response = CreateSend::Transactional::ClassicEmail.new(@auth).groups
|
54
|
+
response.length.should == 3
|
55
|
+
response[0].Group.should == "Password Reset"
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TransactionalSmartEmailTest < Test::Unit::TestCase
|
4
|
+
multiple_contexts "authenticated_using_oauth_context", "authenticated_using_api_key_context" do
|
5
|
+
setup do
|
6
|
+
@client_id = "87y8d7qyw8d7yq8w7ydwqwd"
|
7
|
+
@smart_email_id = "bcf40510-f968-11e4-ab73-bf67677cc1f4"
|
8
|
+
@email = CreateSend::Transactional::SmartEmail.new @auth, @smart_email_id
|
9
|
+
end
|
10
|
+
|
11
|
+
should "get the list of smart emails" do
|
12
|
+
stub_get(@auth, "transactional/smartemail", "tx_smartemails.json")
|
13
|
+
response = CreateSend::Transactional::SmartEmail.list(@auth)
|
14
|
+
response.length.should == 2
|
15
|
+
response[0].ID.should == "1e654df2-f484-11e4-970c-6c4008bc7468"
|
16
|
+
response[0].Name.should == "Welcome email"
|
17
|
+
response[0].Status.should == "Active"
|
18
|
+
end
|
19
|
+
|
20
|
+
should "get the list of active smart emails using a client ID" do
|
21
|
+
stub_get(@auth, "transactional/smartemail?status=active&client=#{@client_id}", "tx_smartemails.json")
|
22
|
+
response = CreateSend::Transactional::SmartEmail.list(@auth, { :client => @client_id, :status => 'active'} )
|
23
|
+
response.length.should == 2
|
24
|
+
response[0].ID.should == "1e654df2-f484-11e4-970c-6c4008bc7468"
|
25
|
+
response[0].Name.should == "Welcome email"
|
26
|
+
response[0].Status.should == "Active"
|
27
|
+
end
|
28
|
+
|
29
|
+
should "get the details of smart email" do
|
30
|
+
stub_get(@auth, "transactional/smartemail/#{@smart_email_id}", "tx_smartemail_details.json")
|
31
|
+
response = CreateSend::Transactional::SmartEmail.new(@auth, @smart_email_id).details
|
32
|
+
response.Name.should == "Reset Password"
|
33
|
+
response.Status.should == "active"
|
34
|
+
response.Properties.ReplyTo.should == "joe@example.com"
|
35
|
+
end
|
36
|
+
|
37
|
+
should "send smart email to one recipient" do
|
38
|
+
stub_post(@auth, "transactional/smartemail/#{@smart_email_id}/send", "tx_send_single.json")
|
39
|
+
email = {
|
40
|
+
"To" => "Bob Sacamano <bob@example.com>",
|
41
|
+
"Data" => {
|
42
|
+
"anEmailVariable" => 'foo',
|
43
|
+
"anotherEmailVariable" => 'bar'
|
44
|
+
}
|
45
|
+
}
|
46
|
+
response = CreateSend::Transactional::SmartEmail.new(@auth, @smart_email_id).send(email)
|
47
|
+
response.length.should == 1
|
48
|
+
response[0].MessageID.should == "0cfe150d-d507-11e4-84a7-c31e5b59881d"
|
49
|
+
response[0].Recipient.should == "\"Bob Sacamano\" <bob@example.com>"
|
50
|
+
response[0].Status.should == "Received"
|
51
|
+
end
|
52
|
+
|
53
|
+
should "send smart email to multiple recipients with all the options" do
|
54
|
+
stub_post(@auth, "transactional/smartemail/#{@smart_email_id}/send", "tx_send_multiple.json")
|
55
|
+
email = {
|
56
|
+
"To" => [
|
57
|
+
"Bob Sacamano <bob@example.com>",
|
58
|
+
"Newman <newman@example.com>",
|
59
|
+
],
|
60
|
+
"CC" => [],
|
61
|
+
"BCC" => [],
|
62
|
+
"Data" => {
|
63
|
+
"anEmailVariable" => 'foo',
|
64
|
+
"anotherEmailVariable" => 'bar'
|
65
|
+
},
|
66
|
+
"Attachments" => [
|
67
|
+
"Name" => "filename.gif",
|
68
|
+
"Type" => "image/gif",
|
69
|
+
"Content" => "R0lGODlhIAAgAKIAAP8AAJmZADNmAMzMAP//AAAAAP///wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMwMTQgNzkuMTU2Nzk3LCAyMDE0LzA4LzIwLTA5OjUzOjAyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxNCAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowNzZGOUNGOUVDRDIxMUU0ODM2RjhGMjNCMTcxN0I2RiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowNzZGOUNGQUVDRDIxMUU0ODM2RjhGMjNCMTcxN0I2RiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjA3NkY5Q0Y3RUNEMjExRTQ4MzZGOEYyM0IxNzE3QjZGIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjA3NkY5Q0Y4RUNEMjExRTQ4MzZGOEYyM0IxNzE3QjZGIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAAIfkEAAAAAAAsAAAAACAAIAAAA5loutz+MKpSpIWU3r1KCBW3eYQmWgWhmiemEgPbNqk6xDOd1XGYV77UzTfbTWC4nAHYQRKLu1VSuXxlpsodAFDAZrfcIbXDFXqhNacoQ3vZpuxHSJZ2zufyTqcunugdd00vQ0F4chQCAgYCaTcxiYuMMhGJFG89kYpFl5MzkoRPnpJskFSaDqctRoBxHEQsdGs0f7Qjq3utDwkAOw=="
|
70
|
+
],
|
71
|
+
"AddRecipientsToListID" => true
|
72
|
+
}
|
73
|
+
response = CreateSend::Transactional::SmartEmail.new(@auth, @smart_email_id).send(email)
|
74
|
+
response.length.should == 2
|
75
|
+
response[1].MessageID.should == "0cfe150d-d507-11e4-b579-a64eb0d9c74d"
|
76
|
+
response[1].Recipient.should == "\"Newman\" <newman@example.com>"
|
77
|
+
response[1].Status.should == "Received"
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TransactionalTimelineTest < Test::Unit::TestCase
|
4
|
+
multiple_contexts "authenticated_using_oauth_context", "authenticated_using_api_key_context" do
|
5
|
+
setup do
|
6
|
+
@client_id = "87y8d7qyw8d7yq8w7ydwqwd"
|
7
|
+
@message_id = "ddc697c7-0788-4df3-a71a-a7cb935f00bd"
|
8
|
+
@before_id = 'e2e270e6-fbce-11e4-97fc-a7cf717ca157'
|
9
|
+
@after_id = 'e96fc6ca-fbce-11e4-949f-c3ccd6a68863'
|
10
|
+
@smart_email_id = 'bb4a6ebb-663d-42a0-bdbe-60512cf30a01'
|
11
|
+
end
|
12
|
+
|
13
|
+
should "get statistics with the default parameters" do
|
14
|
+
stub_get(@auth, "transactional/statistics", "tx_statistics_classic.json")
|
15
|
+
response = CreateSend::Transactional::Timeline.new(@auth).statistics
|
16
|
+
response.Sent.should == 1000
|
17
|
+
response.Opened.should == 300
|
18
|
+
end
|
19
|
+
|
20
|
+
should "get statistics filtered by date and classic group" do
|
21
|
+
stub_get(@auth, "transactional/statistics?from=2015-01-01&to=2015-06-30&timezone=client&group=Password%20Reset", "tx_statistics_classic.json")
|
22
|
+
response = CreateSend::Transactional::Timeline.new(@auth).statistics(
|
23
|
+
"from" => "2015-01-01",
|
24
|
+
"to" => "2015-06-30",
|
25
|
+
"timezone" => "client",
|
26
|
+
"group" => "Password Reset"
|
27
|
+
)
|
28
|
+
response.Query.TimeZone.should == "(GMT+10:00) Canberra, Melbourne, Sydney"
|
29
|
+
response.Query.Group.should == "Password Reset"
|
30
|
+
response.Sent.should == 1000
|
31
|
+
end
|
32
|
+
|
33
|
+
should "get statistics filtered by date and smart email" do
|
34
|
+
stub_get(@auth, "transactional/statistics?from=2015-01-01&to=2015-06-30&timezone=utc&smartEmailID=#{@smart_email_id}", "tx_statistics_smart.json")
|
35
|
+
response = CreateSend::Transactional::Timeline.new(@auth).statistics(
|
36
|
+
"from" => "2015-01-01",
|
37
|
+
"to" => "2015-06-30",
|
38
|
+
"timezone" => "utc",
|
39
|
+
"smartEmailID" => "bb4a6ebb-663d-42a0-bdbe-60512cf30a01"
|
40
|
+
)
|
41
|
+
response.Query.TimeZone.should == "UTC"
|
42
|
+
response.Query.SmartEmailID.should == "bb4a6ebb-663d-42a0-bdbe-60512cf30a01"
|
43
|
+
response.Sent.should == 1000
|
44
|
+
end
|
45
|
+
|
46
|
+
should "get the message timeline with default parameters" do
|
47
|
+
stub_get(@auth, "transactional/messages", "tx_messages.json")
|
48
|
+
response = CreateSend::Transactional::Timeline.new(@auth).messages
|
49
|
+
response.length.should == 3
|
50
|
+
response[0].MessageID.should == "ddc697c7-0788-4df3-a71a-a7cb935f00bd"
|
51
|
+
response[0].Status.should == "Delivered"
|
52
|
+
end
|
53
|
+
|
54
|
+
should "get the message timeline for a smart email" do
|
55
|
+
stub_get(@auth, "transactional/messages?status=all&count=200&sentBeforeID=#{@before_id}&sentAfterID=#{@after_id}&smartEmailID=#{@smart_email_id}&clientID=#{@client_id}", "tx_messages_smart.json")
|
56
|
+
response = CreateSend::Transactional::Timeline.new(@auth).messages(
|
57
|
+
"status" => 'all',
|
58
|
+
"count" => 200,
|
59
|
+
"sentBeforeID" => @before_id,
|
60
|
+
"sentAfterID" => @after_id,
|
61
|
+
"smartEmailID" => @smart_email_id,
|
62
|
+
"clientID" => @client_id
|
63
|
+
)
|
64
|
+
response.length.should == 1
|
65
|
+
response[0].MessageID.should == "ddc697c7-0788-4df3-a71a-a7cb935f00bd"
|
66
|
+
response[0].Status.should == "Delivered"
|
67
|
+
end
|
68
|
+
|
69
|
+
should "get the message timeline for a classic group" do
|
70
|
+
stub_get(@auth, "transactional/messages?status=all&count=200&sentBeforeID=#{@before_id}&sentAfterID=#{@after_id}&group=Password%20Reset&clientID=#{@client_id}", "tx_messages_classic.json")
|
71
|
+
response = CreateSend::Transactional::Timeline.new(@auth).messages(
|
72
|
+
"status" => 'all',
|
73
|
+
"count" => 200,
|
74
|
+
"sentBeforeID" => @before_id,
|
75
|
+
"sentAfterID" => @after_id,
|
76
|
+
"group" => 'Password Reset',
|
77
|
+
"clientID" => @client_id
|
78
|
+
)
|
79
|
+
response.length.should == 1
|
80
|
+
response[0].Group.should == "Password Reset"
|
81
|
+
response[0].Status.should == "Delivered"
|
82
|
+
end
|
83
|
+
|
84
|
+
should "get the message details" do
|
85
|
+
stub_get(@auth, "transactional/messages/#{@message_id}", "tx_message_details.json")
|
86
|
+
response = CreateSend::Transactional::Timeline.new(@auth).details(@message_id)
|
87
|
+
response.TotalOpens.should == 1
|
88
|
+
response.TotalClicks.should == 1
|
89
|
+
end
|
90
|
+
|
91
|
+
should "get the message details with statistics" do
|
92
|
+
stub_get(@auth, "transactional/messages/#{@message_id}?statistics=true", "tx_message_details_with_statistics.json")
|
93
|
+
response = CreateSend::Transactional::Timeline.new(@auth).details(@message_id, :statistics => true)
|
94
|
+
response.Opens.length == 1
|
95
|
+
response.Clicks.length == 1
|
96
|
+
end
|
97
|
+
|
98
|
+
should "resend a message" do
|
99
|
+
stub_post(@auth, "transactional/messages/#{@message_id}/resend", "tx_send_single.json")
|
100
|
+
response = CreateSend::Transactional::Timeline.new(@auth).resend(@message_id)
|
101
|
+
response.length.should == 1
|
102
|
+
response[0].MessageID.should == "0cfe150d-d507-11e4-84a7-c31e5b59881d"
|
103
|
+
response[0].Recipient.should == "\"Bob Sacamano\" <bob@example.com>"
|
104
|
+
response[0].Status.should == "Received"
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: createsend
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Dennes
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-08-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -136,6 +136,20 @@ dependencies:
|
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: test-unit
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '3.0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '3.0'
|
139
153
|
description: Implements the complete functionality of the Campaign Monitor API.
|
140
154
|
email:
|
141
155
|
- jdennes@gmail.com
|
@@ -165,6 +179,9 @@ files:
|
|
165
179
|
- lib/createsend/segment.rb
|
166
180
|
- lib/createsend/subscriber.rb
|
167
181
|
- lib/createsend/template.rb
|
182
|
+
- lib/createsend/transactional_classic_email.rb
|
183
|
+
- lib/createsend/transactional_smart_email.rb
|
184
|
+
- lib/createsend/transactional_timeline.rb
|
168
185
|
- lib/createsend/version.rb
|
169
186
|
- test/administrator_test.rb
|
170
187
|
- test/campaign_test.rb
|
@@ -235,6 +252,19 @@ files:
|
|
235
252
|
- test/fixtures/templates.json
|
236
253
|
- test/fixtures/timezones.json
|
237
254
|
- test/fixtures/transfer_credits.json
|
255
|
+
- test/fixtures/tx_classicemail_groups.json
|
256
|
+
- test/fixtures/tx_message_details.json
|
257
|
+
- test/fixtures/tx_message_details_with_statistics.json
|
258
|
+
- test/fixtures/tx_messages.json
|
259
|
+
- test/fixtures/tx_messages_classic.json
|
260
|
+
- test/fixtures/tx_messages_smart.json
|
261
|
+
- test/fixtures/tx_resend_message.json
|
262
|
+
- test/fixtures/tx_send_multiple.json
|
263
|
+
- test/fixtures/tx_send_single.json
|
264
|
+
- test/fixtures/tx_smartemail_details.json
|
265
|
+
- test/fixtures/tx_smartemails.json
|
266
|
+
- test/fixtures/tx_statistics_classic.json
|
267
|
+
- test/fixtures/tx_statistics_smart.json
|
238
268
|
- test/fixtures/unconfirmed_subscribers.json
|
239
269
|
- test/fixtures/unsubscribed_subscribers.json
|
240
270
|
- test/fixtures/update_custom_field.json
|
@@ -244,6 +274,9 @@ files:
|
|
244
274
|
- test/segment_test.rb
|
245
275
|
- test/subscriber_test.rb
|
246
276
|
- test/template_test.rb
|
277
|
+
- test/transactional_classic_email_test.rb
|
278
|
+
- test/transactional_smart_email_test.rb
|
279
|
+
- test/transactional_timeline_test.rb
|
247
280
|
homepage: http://campaignmonitor.github.io/createsend-ruby/
|
248
281
|
licenses:
|
249
282
|
- MIT
|
@@ -264,7 +297,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
264
297
|
version: 1.3.6
|
265
298
|
requirements: []
|
266
299
|
rubyforge_project:
|
267
|
-
rubygems_version: 2.2.
|
300
|
+
rubygems_version: 2.2.3
|
268
301
|
signing_key:
|
269
302
|
specification_version: 4
|
270
303
|
summary: A library which implements the complete functionality of the Campaign Monitor
|
@@ -339,6 +372,19 @@ test_files:
|
|
339
372
|
- test/fixtures/templates.json
|
340
373
|
- test/fixtures/timezones.json
|
341
374
|
- test/fixtures/transfer_credits.json
|
375
|
+
- test/fixtures/tx_classicemail_groups.json
|
376
|
+
- test/fixtures/tx_message_details.json
|
377
|
+
- test/fixtures/tx_message_details_with_statistics.json
|
378
|
+
- test/fixtures/tx_messages.json
|
379
|
+
- test/fixtures/tx_messages_classic.json
|
380
|
+
- test/fixtures/tx_messages_smart.json
|
381
|
+
- test/fixtures/tx_resend_message.json
|
382
|
+
- test/fixtures/tx_send_multiple.json
|
383
|
+
- test/fixtures/tx_send_single.json
|
384
|
+
- test/fixtures/tx_smartemail_details.json
|
385
|
+
- test/fixtures/tx_smartemails.json
|
386
|
+
- test/fixtures/tx_statistics_classic.json
|
387
|
+
- test/fixtures/tx_statistics_smart.json
|
342
388
|
- test/fixtures/unconfirmed_subscribers.json
|
343
389
|
- test/fixtures/unsubscribed_subscribers.json
|
344
390
|
- test/fixtures/update_custom_field.json
|
@@ -348,4 +394,6 @@ test_files:
|
|
348
394
|
- test/segment_test.rb
|
349
395
|
- test/subscriber_test.rb
|
350
396
|
- test/template_test.rb
|
351
|
-
|
397
|
+
- test/transactional_classic_email_test.rb
|
398
|
+
- test/transactional_smart_email_test.rb
|
399
|
+
- test/transactional_timeline_test.rb
|