newslettre 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/features/recipients.feature +11 -14
- data/features/scheduling.feature +20 -0
- data/features/step_definitions/recipients_steps.rb +10 -10
- data/features/step_definitions/scheduling_steps.rb +30 -0
- data/features/support/env.rb +3 -1
- data/lib/newslettre/api.rb +7 -7
- data/lib/newslettre/letter.rb +81 -0
- data/lib/newslettre/version.rb +1 -1
- data/newslettre.gemspec +3 -2
- data/spec/high_level_api_spec.rb +34 -0
- data/spec/low_level_spec.rb +32 -3
- data/spec/spec_helper.rb +2 -0
- metadata +53 -16
data/features/recipients.feature
CHANGED
@@ -1,20 +1,17 @@
|
|
1
1
|
Feature: Managing Recipients for Newsletters
|
2
2
|
Background:
|
3
|
-
Given there is no Newsletter named
|
4
|
-
And there is no
|
5
|
-
And there is no identity named
|
3
|
+
Given there is no Newsletter named "Superior Soy Beans Discount!"
|
4
|
+
And there is no "Junk-food addicts" Recipient List
|
5
|
+
And there is no identity named "Hidden"
|
6
|
+
And I add the "Hidden" Identity
|
7
|
+
And I add a Newsletter named "Superior Soy Beans Discount!" written by "Hidden"
|
8
|
+
And I add a Recipient List named "Junk-food addicts"
|
6
9
|
@sendgrid_adding_recipients
|
7
10
|
Scenario: Adding a Recipient List to a Newsletter
|
8
|
-
|
9
|
-
|
10
|
-
And I add a Recipient List named 'Junk-food addicts'
|
11
|
-
When I add 'Junk-food addicts' to 'Superior Soy Beans Discount!'
|
12
|
-
Then 'Junk-food addicts' will be notified when 'Superior Soy Beans Discount!' is delivered
|
11
|
+
When I add "Junk-food addicts" to "Superior Soy Beans Discount!"
|
12
|
+
Then "Junk-food addicts" will be notified when "Superior Soy Beans Discount!" is delivered
|
13
13
|
@sendgrid_removing_recipients
|
14
14
|
Scenario: Removing a Recipient List from a Newsletter
|
15
|
-
Given I add
|
16
|
-
|
17
|
-
|
18
|
-
And I add 'Junk-food addicts' to 'Superior Soy Beans Discount!'
|
19
|
-
When I remove 'Junk-food addicts' from 'Superior Soy Beans Discount!'
|
20
|
-
Then no one will be notified when 'Superior Soy Beans Discount!' is delivered
|
15
|
+
Given I add "Junk-food addicts" to "Superior Soy Beans Discount!"
|
16
|
+
When I remove "Junk-food addicts" from "Superior Soy Beans Discount!"
|
17
|
+
Then no one will be notified when "Superior Soy Beans Discount!" is delivered
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: Scheduling
|
2
|
+
Background:
|
3
|
+
Given there is no Newsletter named "Superior Soy Beans Discount!"
|
4
|
+
And there is no "Junk-food addicts" Recipient List
|
5
|
+
And there is no identity named "Hidden"
|
6
|
+
And I add the "Hidden" Identity
|
7
|
+
And I add a Newsletter named "Superior Soy Beans Discount!" written by "Hidden"
|
8
|
+
And I add a Recipient List named "Junk-food addicts"
|
9
|
+
And "Joe" subscribes to "Junk-food addicts"
|
10
|
+
And I add "Junk-food addicts" to "Superior Soy Beans Discount!"
|
11
|
+
And "Superior Soy Beans Discount!" is not scheduled
|
12
|
+
@sendgrid_scheduling_newsletter
|
13
|
+
Scenario: Scheduling a Newsletter
|
14
|
+
When I schedule "Superior Soy Beans Discount!" for "tomorrow"
|
15
|
+
Then it should deliver "Superior Soy Beans Discount!" at "tomorrow"
|
16
|
+
@sendgrid_descheduling_newsletter
|
17
|
+
Scenario: Deschedule a Newsletter
|
18
|
+
Given I schedule "Superior Soy Beans Discount!" for "tomorrow"
|
19
|
+
When I deschedule "Superior Soy Beans Discount!"
|
20
|
+
Then it should not deliver "Superior Soy Beans Discount!"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
Given /^there is no Newsletter named
|
1
|
+
Given /^there is no Newsletter named "([^"]+)"$/ do |name|
|
2
2
|
begin
|
3
3
|
newslettre.newsletters.delete name
|
4
4
|
rescue Newslettre::API::ClientFailure
|
@@ -6,7 +6,7 @@ Given /^there is no Newsletter named '([^']+)'$/ do |name|
|
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
-
Given /^there is no
|
9
|
+
Given /^there is no "([^"]+)" Recipient List$/ do |list|
|
10
10
|
begin
|
11
11
|
newslettre.lists.delete list
|
12
12
|
rescue Newslettre::API::ClientFailure
|
@@ -14,7 +14,7 @@ Given /^there is no '([^']+)' Recipient List$/ do |list|
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
Given /^there is no identity named
|
17
|
+
Given /^there is no identity named "([^"]+)"$/ do |identity|
|
18
18
|
begin
|
19
19
|
newslettre.identities.delete identity
|
20
20
|
rescue Newslettre::API::ClientFailure
|
@@ -22,11 +22,11 @@ Given /^there is no identity named '([^']+)'$/ do |identity|
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
Given /^I add the
|
25
|
+
Given /^I add the "([^"]+)" Identity$/ do |identity|
|
26
26
|
newslettre.identities.add identity, NEWSLETTRE_CONFIG['identity']
|
27
27
|
end
|
28
28
|
|
29
|
-
Given /^I add a Newsletter named
|
29
|
+
Given /^I add a Newsletter named "([^"]+)" written by "([^"]+)"$/ do |name, identity|
|
30
30
|
newslettre.newsletters.add name,
|
31
31
|
:identity => identity,
|
32
32
|
:subject => name,
|
@@ -34,22 +34,22 @@ Given /^I add a Newsletter named '([^']+)' written by '([^']+)'$/ do |name, iden
|
|
34
34
|
:html => "<h1>meow</h1>"
|
35
35
|
end
|
36
36
|
|
37
|
-
Given /^I add a Recipient List named
|
37
|
+
Given /^I add a Recipient List named "([^"]+)"$/ do |list|
|
38
38
|
newslettre.lists.add list
|
39
39
|
end
|
40
40
|
|
41
|
-
When /^I add
|
41
|
+
When /^I add "([^"]+)" to "([^"]+)"$/ do |list, name|
|
42
42
|
newslettre.newsletters.get(name).recipients.add list
|
43
43
|
end
|
44
44
|
|
45
|
-
When /^I remove
|
45
|
+
When /^I remove "([^"]+)" from "([^"]+)"$/ do |list, name|
|
46
46
|
newslettre.newsletters.get(name).recipients.delete list
|
47
47
|
end
|
48
48
|
|
49
|
-
Then /^
|
49
|
+
Then /^"([^"]+)" will be notified when "([^"]+)" is delivered$/ do |list, name|
|
50
50
|
newslettre.newsletters.get(name).recipients.to_a.should =~ [{ "list" => list }]
|
51
51
|
end
|
52
52
|
|
53
|
-
Then /^no one will be notified when
|
53
|
+
Then /^no one will be notified when "([^"]+)" is delivered$/ do |name|
|
54
54
|
newslettre.newsletters.get(name).recipients.to_a.should be_empty
|
55
55
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
Given /^"([^"]*)" subscribes to "([^"]*)"$/ do |name, list|
|
2
|
+
user = NEWSLETTRE_CONFIG['users'][name]
|
3
|
+
|
4
|
+
newslettre.lists.get(list).emails.add user
|
5
|
+
end
|
6
|
+
|
7
|
+
When /^I schedule "([^"]*)" for "([^"]*)"$/ do |letter, date|
|
8
|
+
time = Chronic.parse date
|
9
|
+
newslettre.newsletters.get(letter).schedule! :at => time
|
10
|
+
end
|
11
|
+
|
12
|
+
Then /^it should deliver "([^"]*)" at "([^"]*)"$/ do |letter, date|
|
13
|
+
newslettre.newsletters.get(letter).schedule.should == Chronic.parse(date)
|
14
|
+
end
|
15
|
+
|
16
|
+
Given /^"([^"]*)" is not scheduled$/ do |letter|
|
17
|
+
begin
|
18
|
+
newslettre.newsletters.get(letter).deschedule!
|
19
|
+
rescue Newslettre::API::ClientFailure
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
When /^I deschedule "([^"]*)"$/ do |letter|
|
25
|
+
newslettre.newsletters.get(letter).deschedule!
|
26
|
+
end
|
27
|
+
|
28
|
+
Then /^it should not deliver "([^"]*)"$/ do |letter|
|
29
|
+
newslettre.newsletters.get(letter).should_not be_scheduled
|
30
|
+
end
|
data/features/support/env.rb
CHANGED
@@ -2,6 +2,7 @@ NEWSLETTRE_CONFIG = YAML.load_file File.dirname(__FILE__) + "/../../config/newsl
|
|
2
2
|
|
3
3
|
require 'vcr'
|
4
4
|
require 'newslettre'
|
5
|
+
require 'chronic'
|
5
6
|
|
6
7
|
VCR.config do |c|
|
7
8
|
c.stub_with :webmock
|
@@ -12,7 +13,8 @@ VCR.config do |c|
|
|
12
13
|
end
|
13
14
|
|
14
15
|
VCR.cucumber_tags do |t|
|
15
|
-
t.tags '@sendgrid_adding_recipients', '@sendgrid_removing_recipients'
|
16
|
+
t.tags '@sendgrid_adding_recipients', '@sendgrid_removing_recipients', '@sendgrid_scheduling_newsletter',
|
17
|
+
'@sendgrid_descheduling_newsletter'
|
16
18
|
end
|
17
19
|
|
18
20
|
class OuterWorld
|
data/lib/newslettre/api.rb
CHANGED
@@ -19,12 +19,12 @@ class Newslettre::API
|
|
19
19
|
params ||= {}
|
20
20
|
options ||= {}
|
21
21
|
|
22
|
-
response, status = request url_for(m, options), params
|
22
|
+
response, status, body = request url_for(m, options), params
|
23
23
|
|
24
|
-
raise ClientFailure if status > 399 and status < 500
|
25
|
-
raise EndpointFailure if status > 499
|
24
|
+
raise ClientFailure, body if status > 399 and status < 500
|
25
|
+
raise EndpointFailure, body if status > 499
|
26
26
|
|
27
|
-
respond
|
27
|
+
respond body
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -57,11 +57,11 @@ class Newslettre::API
|
|
57
57
|
|
58
58
|
curl.http_post(*fields)
|
59
59
|
|
60
|
-
[curl, curl.response_code]
|
60
|
+
[curl, curl.response_code, curl.body_str]
|
61
61
|
end
|
62
62
|
|
63
|
-
def respond
|
64
|
-
JSON.load
|
63
|
+
def respond body
|
64
|
+
JSON.load body
|
65
65
|
end
|
66
66
|
|
67
67
|
def url_for path, options = {}
|
data/lib/newslettre/letter.rb
CHANGED
@@ -19,9 +19,35 @@ class Newslettre::Letter < Newslettre::APIModule
|
|
19
19
|
data
|
20
20
|
end
|
21
21
|
|
22
|
+
def schedule
|
23
|
+
scheduler.get
|
24
|
+
end
|
25
|
+
|
26
|
+
def deschedule!
|
27
|
+
scheduler.delete
|
28
|
+
end
|
29
|
+
|
30
|
+
def schedule! options = {}
|
31
|
+
scheduler.deliver options
|
32
|
+
end
|
33
|
+
|
34
|
+
def scheduled?
|
35
|
+
begin
|
36
|
+
!!schedule
|
37
|
+
rescue NotScheduledFailure
|
38
|
+
false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
22
42
|
def recipients
|
23
43
|
@recipients ||= Newslettre::APIModuleProxy.new self, Recipients.new(self.name, self.api)
|
24
44
|
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def scheduler
|
49
|
+
@scheduler ||= Schedule.new self.name, self.api
|
50
|
+
end
|
25
51
|
end
|
26
52
|
|
27
53
|
def list
|
@@ -44,6 +70,61 @@ class Newslettre::Letter < Newslettre::APIModule
|
|
44
70
|
request 'edit', data
|
45
71
|
end
|
46
72
|
|
73
|
+
class Schedule < Newslettre::APIModule
|
74
|
+
attr_reader :letter
|
75
|
+
|
76
|
+
def initialize letter, api
|
77
|
+
@letter = letter
|
78
|
+
@api = api
|
79
|
+
end
|
80
|
+
|
81
|
+
def deliver options = {}
|
82
|
+
require 'time'
|
83
|
+
data = { :name => letter }
|
84
|
+
at = options.delete :at
|
85
|
+
unless at.nil?
|
86
|
+
data[:at] = at.iso8601
|
87
|
+
end
|
88
|
+
request :add, data
|
89
|
+
end
|
90
|
+
|
91
|
+
def delete
|
92
|
+
request :delete, :name => letter
|
93
|
+
|
94
|
+
true
|
95
|
+
end
|
96
|
+
|
97
|
+
def get
|
98
|
+
require 'time'
|
99
|
+
begin
|
100
|
+
date = request(:get, :name => letter)["date"]
|
101
|
+
rescue Newslettre::API::ClientFailure
|
102
|
+
raise NotScheduledFailure, "not found"
|
103
|
+
end
|
104
|
+
|
105
|
+
unless date.nil? or date.size.zero?
|
106
|
+
parse_utc_date date
|
107
|
+
else
|
108
|
+
raise NotScheduledFailure, "invalid date"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
protected
|
113
|
+
|
114
|
+
def parse_utc_date date
|
115
|
+
date, time = date.split(" ")
|
116
|
+
|
117
|
+
year, month, day = date.split "-"
|
118
|
+
hour, minute, second = time.split ":"
|
119
|
+
|
120
|
+
Time.utc year, month, day, hour, minute, second
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
class NotScheduledFailure < Newslettre::API::ClientFailure; end
|
126
|
+
|
127
|
+
|
47
128
|
class Recipients < Newslettre::APIModule
|
48
129
|
attr_reader :letter
|
49
130
|
|
data/lib/newslettre/version.rb
CHANGED
data/newslettre.gemspec
CHANGED
@@ -20,8 +20,6 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
22
|
s.add_dependency "yajl-ruby", "~> 0.8"
|
23
|
-
#s.add_dependency "typhoeus", "~> 0.2"
|
24
|
-
#s.add_dependency "faraday", "~> 0.7"
|
25
23
|
s.add_dependency "curb", "~> 0.7"
|
26
24
|
|
27
25
|
s.add_development_dependency "rake", "~> 0.9"
|
@@ -29,4 +27,7 @@ Gem::Specification.new do |s|
|
|
29
27
|
s.add_development_dependency "webmock", "~> 1.7"
|
30
28
|
s.add_development_dependency "vcr", "~> 1.11"
|
31
29
|
s.add_development_dependency "cucumber", "~> 1"
|
30
|
+
s.add_development_dependency "chronic", "~> 0.6"
|
31
|
+
s.add_development_dependency "timecop", "~> 0.3"
|
32
|
+
s.add_development_dependency "rspec-spies", "~> 2.0"
|
32
33
|
end
|
data/spec/high_level_api_spec.rb
CHANGED
@@ -86,4 +86,38 @@ describe "The higher-level API" do
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
89
|
+
|
90
|
+
context Newslettre::Letter::Schedule do
|
91
|
+
subject { @client }
|
92
|
+
|
93
|
+
it "should schedule a newsletter" do
|
94
|
+
Timecop.freeze do
|
95
|
+
Newslettre::Letter::Schedule.any_instance.should_receive(:deliver).with(:at => Time.now)
|
96
|
+
subject.newsletters.get('test-letter').schedule! :at => Time.now
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should fetch schedule for newsletter" do
|
101
|
+
Newslettre::Letter::Schedule.any_instance.should_receive(:get).and_return(Time.now)
|
102
|
+
subject.newsletters.get('test-letter').schedule.should be_kind_of(Time)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should delete schedule for newsletter" do
|
106
|
+
Newslettre::Letter::Schedule.any_instance.should_receive(:delete).and_return(true)
|
107
|
+
|
108
|
+
subject.newsletters.get('test-letter').deschedule!.should be_true
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should tell me 'test-letter' is not scheduled" do
|
112
|
+
Newslettre::API.any_instance.should_receive(:get).and_raise(Newslettre::API::ClientFailure)
|
113
|
+
|
114
|
+
subject.newsletters.get('test-letter').should_not be_scheduled
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should tell me 'test-letter' is scheduled" do
|
118
|
+
Newslettre::Letter::Schedule.any_instance.should_receive(:get).and_return(Time.now)
|
119
|
+
|
120
|
+
subject.newsletters.get('test-letter').should be_scheduled
|
121
|
+
end
|
122
|
+
end
|
89
123
|
end
|
data/spec/low_level_spec.rb
CHANGED
@@ -188,9 +188,7 @@ describe Newslettre do
|
|
188
188
|
it "should create an HTML mail" do
|
189
189
|
data = NEWSLETTRE_CONFIG['letter']
|
190
190
|
data["html"] = File.read File.dirname(__FILE__) + "/fixtures/test-letter.html"
|
191
|
-
|
192
|
-
# <!doctype html>\n<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->\n<!--[if lt IE 7]> <html class=\"no-js ie6 oldie\" lang=\"en\"> <![endif]-->\n<!--[if IE 7]> <html class=\"no-js ie7 oldie\" lang=\"en\"> <![endif]-->\n<!--[if IE 8]> <html class=\"no-js ie8 oldie\" lang=\"en\"> <![endif]-->\n<!-- Consider adding a manifest.appcache: h5bp.com/d/Offline -->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\"> <!--<![endif]-->\n<head>\n <meta charset=\"utf-8\">\n\n <!-- Use the .htaccess and remove these lines to avoid edge case issues.\n More info: h5bp.com/b/378 -->\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n\n <title></title>\n <meta name=\"description\" content=\"\">\n <meta name=\"author\" content=\"\">\n\n <!-- Mobile viewport optimized: j.mp/bplateviewport -->\n <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n\n <!-- Place favicon.ico and apple-touch-icon.png in the root directory: mathiasbynens.be/notes/touch-icons -->\n\n <link rel=\"stylesheet\" href=\"css/style.css\">\n \n <!-- More ideas for your <head> here: h5bp.com/d/head-Tips -->\n\n <!-- All JavaScript at the bottom, except this Modernizr build incl. Respond.js\n Respond is a polyfill for min/max-width media queries. Modernizr enables HTML5 elements & feature detects; \n for optimal performance, create your own custom Modernizr build: www.modernizr.com/download/ -->\n <script src=\"js/libs/modernizr-2.0.6.min.js\"></script>\n</head>\n\n<body>\n <header>\n\n </header>\n <div role=\"main\">\n\n </div>\n <footer>\n\n </footer>\n\n\n <!-- JavaScript at the bottom for fast page loading -->\n\n <!-- Grab Google CDN's jQuery, with a protocol relative URL; fall back to local if offline -->\n <script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js\"></script>\n <script>window.jQuery || document.write('<script src=\"js/libs/jquery-1.6.4.min.js\"><\\/script>')</script>\n\n\n <!-- scripts concatenated and minified via build script -->\n <script defer src=\"js/plugins.js\"></script>\n <script defer src=\"js/script.js\"></script>\n <!-- end scripts -->\n\n\n <!-- Asynchronous Google Analytics snippet. Change UA-XXXXX-X to be your site's ID.\n mathiasbynens.be/notes/async-analytics-snippet -->\n <script>\n var _gaq=[['_setAccount','UA-XXXXX-X'],['_trackPageview'],['_trackPageLoadTime']];\n (function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];\n g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';\n s.parentNode.insertBefore(g,s)}(document,'script'));\n </script>\n\n <!-- Prompt IE 6 users to install Chrome Frame. Remove this if you want to support IE 6.\n chromium.org/developers/how-tos/chrome-frame-getting-started -->\n <!--[if lt IE 7 ]>\n <script defer src=\"//ajax.googleapis.com/ajax/libs/chrome-frame/1.0.3/CFInstall.min.js\"></script>\n <script defer>window.attachEvent('onload',function(){CFInstall.check({mode:'overlay'})})</script>\n <![endif]-->\n\n</body>\n</html>\n
|
193
|
-
# HTML
|
191
|
+
|
194
192
|
@newsletter.add 'test-html', data
|
195
193
|
|
196
194
|
@newsletter.get("test-html").to_hash["html"].should_not be_empty
|
@@ -203,4 +201,35 @@ describe Newslettre do
|
|
203
201
|
|
204
202
|
end
|
205
203
|
|
204
|
+
describe Newslettre::Letter::Schedule do
|
205
|
+
before :each do
|
206
|
+
@schedule = Newslettre::Letter::Schedule.new 'test-letter', @api
|
207
|
+
end
|
208
|
+
|
209
|
+
it "should call the API when delivering" do
|
210
|
+
@api.should_receive(:add).with({ :name => 'test-letter', :at => '2012-01-15T02:11:25Z'}, { :prefix => "/schedule" })
|
211
|
+
@schedule.deliver :at => Time.utc(2012,"jan", 15, 2, 11, 25)
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should call the API when requesting delivery time" do
|
215
|
+
@api.should_receive(:get).with({ :name => 'test-letter'} , { :prefix => "/schedule" }).and_return({"date" => "2012-01-15 02:11:25"})
|
216
|
+
@schedule.get
|
217
|
+
end
|
218
|
+
|
219
|
+
context "#delete" do
|
220
|
+
before :each do
|
221
|
+
@api.stub! :delete
|
222
|
+
end
|
223
|
+
|
224
|
+
it "should call the API when unscheduling delivery" do
|
225
|
+
@schedule.delete
|
226
|
+
@api.should have_received(:delete).with({ :name => 'test-letter'}, { :prefix => "/schedule" })
|
227
|
+
end
|
228
|
+
|
229
|
+
it "should return `true`" do
|
230
|
+
@schedule.delete.should be_true
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
end
|
206
235
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: newslettre
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,12 +9,12 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-09-
|
12
|
+
date: 2011-09-23 00:00:00.000000000 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: yajl-ruby
|
17
|
-
requirement: &
|
17
|
+
requirement: &2152125080 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ~>
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: '0.8'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *2152125080
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: curb
|
28
|
-
requirement: &
|
28
|
+
requirement: &2152123780 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: '0.7'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *2152123780
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: rake
|
39
|
-
requirement: &
|
39
|
+
requirement: &2152122980 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ~>
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
version: '0.9'
|
45
45
|
type: :development
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *2152122980
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: rspec
|
50
|
-
requirement: &
|
50
|
+
requirement: &2152121980 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - ~>
|
@@ -55,10 +55,10 @@ dependencies:
|
|
55
55
|
version: '2'
|
56
56
|
type: :development
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *2152121980
|
59
59
|
- !ruby/object:Gem::Dependency
|
60
60
|
name: webmock
|
61
|
-
requirement: &
|
61
|
+
requirement: &2152121340 !ruby/object:Gem::Requirement
|
62
62
|
none: false
|
63
63
|
requirements:
|
64
64
|
- - ~>
|
@@ -66,10 +66,10 @@ dependencies:
|
|
66
66
|
version: '1.7'
|
67
67
|
type: :development
|
68
68
|
prerelease: false
|
69
|
-
version_requirements: *
|
69
|
+
version_requirements: *2152121340
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: vcr
|
72
|
-
requirement: &
|
72
|
+
requirement: &2152120560 !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
75
|
- - ~>
|
@@ -77,10 +77,10 @@ dependencies:
|
|
77
77
|
version: '1.11'
|
78
78
|
type: :development
|
79
79
|
prerelease: false
|
80
|
-
version_requirements: *
|
80
|
+
version_requirements: *2152120560
|
81
81
|
- !ruby/object:Gem::Dependency
|
82
82
|
name: cucumber
|
83
|
-
requirement: &
|
83
|
+
requirement: &2152119820 !ruby/object:Gem::Requirement
|
84
84
|
none: false
|
85
85
|
requirements:
|
86
86
|
- - ~>
|
@@ -88,7 +88,40 @@ dependencies:
|
|
88
88
|
version: '1'
|
89
89
|
type: :development
|
90
90
|
prerelease: false
|
91
|
-
version_requirements: *
|
91
|
+
version_requirements: *2152119820
|
92
|
+
- !ruby/object:Gem::Dependency
|
93
|
+
name: chronic
|
94
|
+
requirement: &2152119020 !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ~>
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0.6'
|
100
|
+
type: :development
|
101
|
+
prerelease: false
|
102
|
+
version_requirements: *2152119020
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: timecop
|
105
|
+
requirement: &2152118220 !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.3'
|
111
|
+
type: :development
|
112
|
+
prerelease: false
|
113
|
+
version_requirements: *2152118220
|
114
|
+
- !ruby/object:Gem::Dependency
|
115
|
+
name: rspec-spies
|
116
|
+
requirement: &2152117500 !ruby/object:Gem::Requirement
|
117
|
+
none: false
|
118
|
+
requirements:
|
119
|
+
- - ~>
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '2.0'
|
122
|
+
type: :development
|
123
|
+
prerelease: false
|
124
|
+
version_requirements: *2152117500
|
92
125
|
description: Create and Manage Newsletters using the Sendgrid API
|
93
126
|
email:
|
94
127
|
- l@melzer.it
|
@@ -102,7 +135,9 @@ files:
|
|
102
135
|
- README.md
|
103
136
|
- Rakefile
|
104
137
|
- features/recipients.feature
|
138
|
+
- features/scheduling.feature
|
105
139
|
- features/step_definitions/recipients_steps.rb
|
140
|
+
- features/step_definitions/scheduling_steps.rb
|
106
141
|
- features/support/env.rb
|
107
142
|
- lib/newslettre.rb
|
108
143
|
- lib/newslettre/api.rb
|
@@ -145,7 +180,9 @@ specification_version: 3
|
|
145
180
|
summary: Sendgrid Newsletter API Client
|
146
181
|
test_files:
|
147
182
|
- features/recipients.feature
|
183
|
+
- features/scheduling.feature
|
148
184
|
- features/step_definitions/recipients_steps.rb
|
185
|
+
- features/step_definitions/scheduling_steps.rb
|
149
186
|
- features/support/env.rb
|
150
187
|
- spec/fixtures/test-letter.html
|
151
188
|
- spec/high_level_api_spec.rb
|