newslettre 0.1.1 → 0.2.0
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.
- 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
|