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.
@@ -1,20 +1,17 @@
1
1
  Feature: Managing Recipients for Newsletters
2
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 'Bourne'
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
- Given I add the 'Bourne' Identity
9
- And I add a Newsletter named 'Superior Soy Beans Discount!' written by 'Bourne'
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 the 'Bourne' Identity
16
- And I add a Newsletter named 'Superior Soy Beans Discount!' written by 'Bourne'
17
- And I add a Recipient List named 'Junk-food addicts'
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 '([^']+)'$/ do |name|
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 '([^']+)' Recipient List$/ do |list|
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 '([^']+)'$/ do |identity|
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 '([^']+)' Identity$/ do |identity|
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 '([^']+)' written by '([^']+)'$/ do |name, identity|
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 '([^']+)'$/ do |list|
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 '([^']+)' to '([^']+)'$/ do |list, name|
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 '([^']+)' from '([^']+)'$/ do |list, name|
45
+ When /^I remove "([^"]+)" from "([^"]+)"$/ do |list, name|
46
46
  newslettre.newsletters.get(name).recipients.delete list
47
47
  end
48
48
 
49
- Then /^'([^']+)' will be notified when '([^']+)' is delivered$/ do |list, name|
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 '([^']+)' is delivered$/ do |name|
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
@@ -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
@@ -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 response
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 response
64
- JSON.load response.body_str
63
+ def respond body
64
+ JSON.load body
65
65
  end
66
66
 
67
67
  def url_for path, options = {}
@@ -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
 
@@ -1,3 +1,3 @@
1
1
  module Newslettre
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
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
@@ -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
@@ -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
- #html = <<-HTML
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
@@ -1,6 +1,8 @@
1
1
  require File.dirname(__FILE__) + '/../lib/newslettre'
2
2
 
3
3
  require 'vcr'
4
+ require 'rspec-spies'
5
+ require 'timecop'
4
6
 
5
7
  NEWSLETTRE_CONFIG = YAML.load_file File.dirname(__FILE__) + "/../config/newslettre.yml"
6
8
 
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.1.1
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-21 00:00:00.000000000 +02:00
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: &2153070980 !ruby/object:Gem::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: *2153070980
25
+ version_requirements: *2152125080
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: curb
28
- requirement: &2153067480 !ruby/object:Gem::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: *2153067480
36
+ version_requirements: *2152123780
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: rake
39
- requirement: &2153055680 !ruby/object:Gem::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: *2153055680
47
+ version_requirements: *2152122980
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: rspec
50
- requirement: &2153044700 !ruby/object:Gem::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: *2153044700
58
+ version_requirements: *2152121980
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: webmock
61
- requirement: &2153031300 !ruby/object:Gem::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: *2153031300
69
+ version_requirements: *2152121340
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: vcr
72
- requirement: &2153027260 !ruby/object:Gem::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: *2153027260
80
+ version_requirements: *2152120560
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: cucumber
83
- requirement: &2153018380 !ruby/object:Gem::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: *2153018380
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