newslettre 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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