almanack 1.0.5 → 1.1.0.beta1

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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/almanack.gemspec +1 -0
  4. data/example.ru +4 -4
  5. data/lib/almanack/base.rb +22 -0
  6. data/lib/almanack/calendar.rb +9 -27
  7. data/lib/almanack/configuration.rb +15 -4
  8. data/lib/almanack/event.rb +56 -5
  9. data/lib/almanack/event_source/ical_feed.rb +6 -2
  10. data/lib/almanack/event_source/meetup_group.rb +26 -5
  11. data/lib/almanack/event_source/static.rb +5 -1
  12. data/lib/almanack/representation/ical_feed.rb +59 -0
  13. data/lib/almanack/representation/json_feed.rb +55 -0
  14. data/lib/almanack/serialized_transformation.rb +53 -0
  15. data/lib/almanack/server/environment.rb +38 -0
  16. data/lib/almanack/server/helpers.rb +32 -28
  17. data/lib/almanack/server.rb +23 -37
  18. data/lib/almanack/themes/legacy/views/events.erb +2 -2
  19. data/lib/almanack/themes/starter/views/events.erb +2 -2
  20. data/lib/almanack/version.rb +1 -1
  21. data/lib/almanack.rb +4 -18
  22. data/spec/calendar_spec.rb +10 -3
  23. data/spec/configuration_spec.rb +10 -0
  24. data/spec/event_source/ical_feed_spec.rb +15 -2
  25. data/spec/event_source/meetup_group_spec.rb +23 -2
  26. data/spec/event_source/static_spec.rb +25 -7
  27. data/spec/event_spec.rb +80 -11
  28. data/spec/features/api_feature_spec.rb +24 -0
  29. data/spec/features/calendar_feature_spec.rb +3 -3
  30. data/spec/features/subscription_feature_spec.rb +5 -5
  31. data/spec/representation/json_feed_spec.rb +44 -0
  32. data/spec/serialized_transformation_spec.rb +45 -0
  33. data/spec/spec_helper.rb +2 -0
  34. data/spec/support/event_matchers.rb +1 -1
  35. data/templates/new/config.ru.tt +1 -1
  36. metadata +29 -4
@@ -1,3 +1,4 @@
1
+ require "rack/contrib"
1
2
  require "sinatra"
2
3
  require "sinatra/reloader"
3
4
  require "sass"
@@ -6,67 +7,52 @@ require "almanack"
6
7
  module Almanack
7
8
  class Server < Sinatra::Base
8
9
  require "almanack/server/helpers"
10
+ require "almanack/server/environment"
9
11
 
10
- configure :development do
11
- register Sinatra::Reloader
12
- end
12
+ include Almanack::ServerContext::Environment
13
13
 
14
14
  set :root, -> { Almanack.config.theme_root }
15
15
  set :protection, except: :frame_options
16
- set :feed_path, "feed.ics"
17
-
18
- not_found do
19
- status 404
20
- erb :error
21
- end
22
-
23
- error do
24
- status 500
25
- erb :error
26
- end
16
+ set :feed_path, "feed"
27
17
 
28
- def basename(file)
29
- Pathname(file).split.last.to_s.split(".", 2).first
30
- end
18
+ use Rack::JSONP
31
19
 
32
- def locate_asset(name, within: path)
33
- name = basename(name)
34
- path = settings.root.join(within)
35
- available = Pathname.glob(path.join("*"))
36
- asset = available.find { |path| basename(path) == name }
37
- raise "Could not find stylesheet #{name} inside #{available}" if asset.nil?
38
- asset
20
+ configure :development do
21
+ register Sinatra::Reloader
39
22
  end
40
23
 
41
- def auto_render_template(asset)
42
- renderer = asset.extname.split(".").last
43
- content = asset.read
44
- respond_to?(renderer) ? send(renderer, content) : content
24
+ helpers do
25
+ include Almanack::ServerContext::Helpers
45
26
  end
46
27
 
47
- def auto_render_asset(*args)
48
- auto_render_template locate_asset(*args)
28
+ before do
29
+ register_sass_loadpaths!
49
30
  end
50
31
 
51
- def theme_stylesheet_path
52
- settings.root.join('stylesheets')
32
+ not_found do
33
+ status 404
34
+ erb :error
53
35
  end
54
36
 
55
- before do
56
- if !Sass.load_paths.include?(theme_stylesheet_path)
57
- Sass.load_paths << theme_stylesheet_path
58
- end
37
+ error do
38
+ status 500
39
+ erb :error
59
40
  end
60
41
 
61
42
  get "/" do
62
43
  erb :events
63
44
  end
64
45
 
65
- get "/#{settings.feed_path}" do
46
+ get "/#{settings.feed_path}.ics" do
66
47
  content_type "text/calendar"
67
48
  Almanack.calendar.ical_feed
68
49
  end
69
50
 
51
+ get "/#{settings.feed_path}.json" do
52
+ content_type :json
53
+ Almanack.calendar.json_feed
54
+ end
55
+
70
56
  get "/stylesheets/:name" do
71
57
  content_type :css
72
58
  auto_render_asset params[:name], within: "stylesheets"
@@ -4,8 +4,8 @@
4
4
  <% calendar.events.each do |event| %>
5
5
  <div class="event">
6
6
  <div class="date">
7
- <div class="month"><%= event.start_date.strftime('%a') %></div>
8
- <div class="day"><%= event.start_date.strftime('%d') %></div>
7
+ <div class="month"><%= event.start_time.strftime('%a') %></div>
8
+ <div class="day"><%= event.start_time.strftime('%d') %></div>
9
9
  </div>
10
10
  <div class="details">
11
11
  <h3 class="title"><%= event.title %></h3>
@@ -4,8 +4,8 @@
4
4
  <% calendar.events.each do |event| %>
5
5
  <div class="event">
6
6
  <div class="date">
7
- <div class="month"><%= event.start_date.strftime('%a') %></div>
8
- <div class="day"><%= event.start_date.strftime('%d') %></div>
7
+ <div class="month"><%= event.start_time.strftime('%a') %></div>
8
+ <div class="day"><%= event.start_time.strftime('%d') %></div>
9
9
  </div>
10
10
  <div class="details">
11
11
  <h3 class="title"><%= event.title %></h3>
@@ -1,6 +1,6 @@
1
1
  module Almanack
2
2
  CODENAME = "Garlick"
3
- VERSION = "1.0.5"
3
+ VERSION = "1.1.0.beta1"
4
4
  HOMEPAGE = "https://github.com/Aupajo/almanack"
5
5
  ISSUES = "https://github.com/Aupajo/almanack/issues"
6
6
  end
data/lib/almanack.rb CHANGED
@@ -4,28 +4,14 @@ require "ri_cal"
4
4
  require "addressable/uri"
5
5
  require "faraday"
6
6
 
7
+ require "almanack/base"
7
8
  require "almanack/version"
8
9
  require "almanack/configuration"
9
10
  require "almanack/calendar"
11
+ require "almanack/serialized_transformation"
12
+ require "almanack/representation/ical_feed"
13
+ require "almanack/representation/json_feed"
10
14
  require "almanack/event"
11
15
  require "almanack/event_source/static"
12
16
  require "almanack/event_source/meetup_group"
13
17
  require "almanack/event_source/ical_feed"
14
-
15
- module Almanack
16
- class << self
17
- def config(&block)
18
- @config ||= Configuration.new
19
- yield @config if block_given?
20
- @config
21
- end
22
-
23
- def calendar
24
- @calendar ||= Calendar.new(config)
25
- end
26
-
27
- def reset!
28
- config.reset!
29
- end
30
- end
31
- end
@@ -42,9 +42,9 @@ module Almanack
42
42
 
43
43
  config = Configuration.new
44
44
  config.add_events [
45
- { title: 'Today', start_date: today },
46
- { title: 'Yesterday', start_date: yesterday },
47
- { title: 'Tomorrow', start_date: tomorrow },
45
+ { title: 'Today', start_time: today },
46
+ { title: 'Yesterday', start_time: yesterday },
47
+ { title: 'Tomorrow', start_time: tomorrow },
48
48
  ]
49
49
 
50
50
  calendar = Calendar.new(config)
@@ -60,5 +60,12 @@ module Almanack
60
60
  end
61
61
  end
62
62
 
63
+ describe "#feed_lookahead" do
64
+ it "delegates to the configuration's feed_lookahead" do
65
+ config = double(feed_lookahead: :delegated)
66
+ expect(Calendar.new(config).feed_lookahead).to eq(:delegated)
67
+ end
68
+ end
69
+
63
70
  end
64
71
  end
@@ -37,6 +37,16 @@ module Almanack
37
37
  end
38
38
  end
39
39
 
40
+ describe "#feed_lookahead" do
41
+ specify { expect(Configuration.new.feed_lookahead).to eq(365) }
42
+
43
+ specify "it can be set" do
44
+ config = Configuration.new
45
+ config.feed_lookahead = 30
46
+ expect(config.feed_lookahead).to eq(30)
47
+ end
48
+ end
49
+
40
50
  describe "#add_events" do
41
51
  it "adds a simple event collection event source" do
42
52
  config = Configuration.new
@@ -16,10 +16,23 @@ module Almanack::EventSource
16
16
  end
17
17
  end
18
18
 
19
- start_dates = events.map(&:start_date)
19
+ start_times = events.map(&:start_time)
20
20
 
21
21
  expect(events.length).to eq(15)
22
- expect(events).to all_have_properties(:title, :start_date, :end_date, :description, :location)
22
+ expect(events).to all_have_properties(:title, :start_time, :end_time, :description, :location)
23
+ end
24
+ end
25
+
26
+ describe "#serialized_between" do
27
+ it "returns a hash containing attributes" do
28
+ source = IcalFeed.new 'url'
29
+
30
+ events = [double(serialized: :serialized_event)]
31
+ expect(source).to receive(:events_between).with(:date_range) { events }
32
+
33
+ expect(source.serialized_between(:date_range)).to eq({
34
+ events: [:serialized_event]
35
+ })
23
36
  end
24
37
  end
25
38
 
@@ -17,10 +17,10 @@ module Almanack::EventSource
17
17
  end
18
18
  end
19
19
 
20
- start_dates = events.map(&:start_date)
20
+ start_times = events.map(&:start_time)
21
21
 
22
22
  expect(events.length).to eq(5)
23
- expect(events).to all_have_properties(:title, :start_date, :end_date, :description, :location)
23
+ expect(events).to all_have_properties(:title, :start_time, :end_time, :description, :location)
24
24
  end
25
25
 
26
26
  it "handles a missing location" do
@@ -38,5 +38,26 @@ module Almanack::EventSource
38
38
  end
39
39
  end
40
40
 
41
+ describe "#serialized_between" do
42
+ it "returns a hash containing attributes" do
43
+ feed = MeetupGroup.new(group_urlname: 'The-Foundation-Christchurch',
44
+ key: 'secrettoken',
45
+ connection: Faraday.new)
46
+ serialized = nil
47
+
48
+ Timecop.freeze(2014, 5, 24) do
49
+ VCR.use_cassette('meetup') do
50
+ from = Time.now
51
+ to = from + 30 * 24 * 60 * 60
52
+ serialized = feed.serialized_between(from..to)
53
+ end
54
+ end
55
+
56
+ expect(serialized[:events].length).to eq 5
57
+ expect(serialized[:name]).to eq("The Foundation")
58
+ expect(serialized[:url]).to eq("http://www.meetup.com/The-Foundation-Christchurch")
59
+ end
60
+ end
61
+
41
62
  end
42
63
  end
@@ -2,16 +2,20 @@ require 'spec_helper'
2
2
 
3
3
  module Almanack::EventSource
4
4
  describe Static do
5
+ let(:yesterday) { now - 1 }
6
+ let(:now) { Time.now }
7
+ let(:tomorrow) { now + 1 }
8
+
9
+ around do |test|
10
+ Timecop.freeze(now, &test)
11
+ end
12
+
5
13
  describe "#events_between" do
6
14
  it "returns events between two dates" do
7
- now = Time.now
8
- yesterday = now - 1
9
- tomorrow = now + 1
10
-
11
15
  source = Static.new [
12
- { title: 'Yesterday', start_date: yesterday },
13
- { title: 'Today', start_date: now },
14
- { title: 'Tomorrow', start_date: tomorrow }
16
+ { title: 'Yesterday', start_time: yesterday },
17
+ { title: 'Today', start_time: now },
18
+ { title: 'Tomorrow', start_time: tomorrow }
15
19
  ]
16
20
 
17
21
  expect(source.events_between(yesterday..tomorrow).map(&:title)).to eq(%w( Yesterday Today Tomorrow ))
@@ -19,5 +23,19 @@ module Almanack::EventSource
19
23
  expect(source.events_between(yesterday..now).map(&:title)).to eq(%w( Yesterday Today ))
20
24
  end
21
25
  end
26
+
27
+ describe "#serialized_between" do
28
+ it "returns a hash containing attributes" do
29
+ source = Static.new []
30
+ date_range = yesterday..tomorrow
31
+
32
+ events = [double(serialized: :serialized_event)]
33
+ expect(source).to receive(:events_between).with(date_range) { events }
34
+
35
+ expect(source.serialized_between(date_range)).to eq({
36
+ events: [:serialized_event]
37
+ })
38
+ end
39
+ end
22
40
  end
23
41
  end
data/spec/event_spec.rb CHANGED
@@ -8,14 +8,14 @@ module Almanack
8
8
  expect(event.title).to eq("Music with rocks in")
9
9
  end
10
10
 
11
- it "has a start date" do
12
- event = Event.new(start_date: Time.new(2014, 01, 01))
13
- expect(event.start_date).to eq_time(Time.new(2014, 01, 01))
11
+ it "has a start time" do
12
+ event = Event.new(start_time: Time.new(2014, 01, 01))
13
+ expect(event.start_time).to eq_time(Time.new(2014, 01, 01))
14
14
  end
15
15
 
16
- it "has a end date" do
17
- event = Event.new(end_date: Time.new(2014, 01, 02))
18
- expect(event.end_date).to eq_time(Time.new(2014, 01, 02))
16
+ it "has a end time" do
17
+ event = Event.new(end_time: Time.new(2014, 01, 02))
18
+ expect(event.end_time).to eq_time(Time.new(2014, 01, 02))
19
19
  end
20
20
 
21
21
  it "has a location" do
@@ -30,23 +30,92 @@ module Almanack
30
30
 
31
31
  describe "#formatted_date" do
32
32
  it "handles events without an end date" do
33
- event = Event.new(start_date: Time.parse("2014-07-06 06:24:00 UTC"))
33
+ event = Event.new(start_time: Time.parse("2014-07-06 06:24:00 UTC"))
34
34
  expect(event.formatted_date).to eq("July 6 2014 at 6:24am")
35
35
  end
36
36
 
37
37
  it "handles events with an end date on the same day" do
38
- event = Event.new(start_date: Time.parse("2014-07-06 06:24:00 UTC"),
39
- end_date: Time.parse("2014-07-06 13:20:00 UTC"))
38
+ event = Event.new(start_time: Time.parse("2014-07-06 06:24:00 UTC"),
39
+ end_time: Time.parse("2014-07-06 13:20:00 UTC"))
40
40
  expect(event.formatted_date).to eq("July 6 2014 at 6:24am to 1:20pm")
41
41
  end
42
42
 
43
43
  it "handles events with an end date on a different day" do
44
- event = Event.new(start_date: Time.parse("2014-07-06 06:00:00 UTC"),
45
- end_date: Time.parse("2014-08-07 10:00:00 UTC"))
44
+ event = Event.new(start_time: Time.parse("2014-07-06 06:00:00 UTC"),
45
+ end_time: Time.parse("2014-08-07 10:00:00 UTC"))
46
46
  expect(event.formatted_date).to eq("July 6 2014 at 6:00am to August 7 2014 at 10:00am")
47
47
  end
48
48
  end
49
49
 
50
+ describe "#start_date" do
51
+ it "returns start_time for legacy reasons" do
52
+ event = Event.new(start_time: Time.new(2014, 01, 01))
53
+ result = nil
54
+ expect { result = event.start_date }.to output(/deprecated/i).to_stderr
55
+ expect(result).to eq_time(Time.new(2014, 01, 01))
56
+ end
57
+
58
+ it "can be set via start_date for legacy reasons" do
59
+ event = Event.new(start_date: Time.new(2014, 01, 01))
60
+ result = nil
61
+ expect { result = event.start_time }.to output(/deprecated/i).to_stderr
62
+ expect(result).to eq_time(Time.new(2014, 01, 01))
63
+ end
64
+
65
+ it "raises an error when both start_date and start_time are given" do
66
+ event = Event.new(start_date: Time.new(2014, 01, 01),
67
+ start_time: Time.new(2014, 01, 02))
68
+ expect { event.start_date }.to raise_error
69
+ expect { event.start_time }.to raise_error
70
+ end
71
+ end
72
+
73
+ describe "#end_date" do
74
+ it "returns end_time for legacy reasons" do
75
+ event = Event.new(end_time: Time.new(2014, 01, 01))
76
+ result = nil
77
+ expect { result = event.end_date }.to output(/deprecated/i).to_stderr
78
+ expect(result).to eq_time(Time.new(2014, 01, 01))
79
+ end
80
+
81
+ it "can be set via end_date for legacy reasons" do
82
+ event = Event.new(end_date: Time.new(2014, 01, 01))
83
+ result = nil
84
+ expect { result = event.end_time }.to output(/deprecated/i).to_stderr
85
+ expect(result).to eq_time(Time.new(2014, 01, 01))
86
+ end
87
+
88
+ it "raises an error when both end_date and end_time are given" do
89
+ event = Event.new(end_date: Time.new(2014, 01, 01),
90
+ end_time: Time.new(2014, 01, 02))
91
+ expect { event.end_date }.to raise_error
92
+ expect { event.end_time }.to raise_error
93
+ end
94
+
95
+ it "does not output a deprecation warning when using end_time if neither end_date or end_time is set" do
96
+ event = Event.new
97
+ expect { event.end_time }.not_to output.to_stderr
98
+ end
99
+ end
100
+
101
+ describe "#serialized" do
102
+ it "returns attributes as a hash" do
103
+ wed = Time.new(2014, 01, 01)
104
+ thu = Time.new(2014, 01, 02)
105
+
106
+ event = Event.new(title: "Hogswatch",
107
+ start_time: wed,
108
+ end_time: thu,
109
+ arbitrary: true)
110
+
111
+ expect(event.serialized).to eq({
112
+ title: "Hogswatch",
113
+ start_time: wed.iso8601,
114
+ end_time: thu.iso8601,
115
+ arbitrary: true
116
+ })
117
+ end
118
+ end
50
119
 
51
120
  end
52
121
  end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe "API", :feature do
4
+ before { Almanack.reset! }
5
+
6
+ describe "/feed.json" do
7
+ it "has a JSON content-type" do
8
+ get '/feed.json'
9
+ expect(last_response['Content-Type']).to eq 'application/json'
10
+ end
11
+
12
+ it "returns the JSON feed" do
13
+ allow(Almanack.calendar).to receive(:json_feed) { "feed" }
14
+ get '/feed.json'
15
+ expect(last_response.body).to eq("feed")
16
+ end
17
+
18
+ it "supports JSONP" do
19
+ allow(Almanack.calendar).to receive(:json_feed) { "feed" }
20
+ get '/feed.json?callback=custom'
21
+ expect(last_response.body).to include("custom(feed)")
22
+ end
23
+ end
24
+ end
@@ -7,9 +7,9 @@ describe "Viewing a calendar", :feature do
7
7
  now = Time.now
8
8
 
9
9
  Almanack.config.add_events [
10
- { title: "Hogswatch", start_date: now },
11
- { title: "Soul Cake Tuesday", start_date: now + 10 * 24 * 60 * 60 },
12
- { title: "Eve of Small Gods", start_date: now + 30 * 24 * 60 * 60 },
10
+ { title: "Hogswatch", start_time: now },
11
+ { title: "Soul Cake Tuesday", start_time: now + 10 * 24 * 60 * 60 },
12
+ { title: "Eve of Small Gods", start_time: now + 30 * 24 * 60 * 60 },
13
13
  ]
14
14
 
15
15
  Timecop.freeze(now) do
@@ -12,13 +12,13 @@ describe "Consolidated iCal feed", :feature do
12
12
  Almanack.reset!
13
13
 
14
14
  Almanack.config.add_events [
15
- { title: "Basic", start_date: now },
16
- { title: "Almost a year away", start_date: now + 364 * 24 * 60 * 60 },
17
- { title: "Over a year away", start_date: now + 366 * 24 * 60 * 60 },
15
+ { title: "Basic", start_time: now },
16
+ { title: "Almost a year away", start_time: now + 364 * 24 * 60 * 60 },
17
+ { title: "Over a year away", start_time: now + 366 * 24 * 60 * 60 },
18
18
  {
19
19
  title: "Complex",
20
- start_date: now,
21
- end_date: now + 30 * 24 * 60 * 60,
20
+ start_time: now,
21
+ end_time: now + 30 * 24 * 60 * 60,
22
22
  description: "Body",
23
23
  location: "CA"
24
24
  }
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ module Almanack::Representation
4
+ describe JSONFeed do
5
+
6
+ let(:calendar) { Almanack.calendar }
7
+ let(:parsed_json) { JSON.parse JSONFeed.from(calendar).to_s }
8
+
9
+ before do
10
+ Almanack.reset!
11
+ end
12
+
13
+ describe ".from" do
14
+ around do |test|
15
+ Timecop.freeze(Time.now, &test)
16
+ end
17
+
18
+ it "returns empty event sources by default" do
19
+ expect(parsed_json).to eq({ "eventSources" => [] })
20
+ end
21
+
22
+ it "returns event sources" do
23
+ Almanack.config.add_events [
24
+ { title: "Basic event", start_time: Time.now, custom_data: 'present' }
25
+ ]
26
+
27
+ expect(parsed_json).to eq({
28
+ "eventSources" => [
29
+ {
30
+ "events" => [
31
+ {
32
+ "title" => "Basic event",
33
+ "startTime" => Time.now.iso8601,
34
+ "customData" => 'present'
35
+ }
36
+ ]
37
+ }
38
+ ]
39
+ })
40
+ end
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ module Almanack
4
+ describe SerializedTransformation do
5
+ let(:fact_book) do
6
+ {
7
+ title: "Facts of the World",
8
+ countries: [
9
+ { name: "New Zealand", population: "4 mil" },
10
+ { name: "America", population: "320 mil" }
11
+ ]
12
+ }
13
+ end
14
+
15
+ let(:transformation) { described_class.new(fact_book) }
16
+
17
+ describe "#apply" do
18
+ it "returns an unmodified structure by default" do
19
+ expect(transformation.apply).to eq fact_book
20
+ end
21
+
22
+ it "can apply changes to keys" do
23
+ transformation.key { |key| key.to_s }
24
+ expect(transformation.apply).to eq({
25
+ "title" => "Facts of the World",
26
+ "countries" => [
27
+ { "name" => "New Zealand", "population" => "4 mil" },
28
+ { "name" => "America", "population" => "320 mil" }
29
+ ]
30
+ })
31
+ end
32
+
33
+ it "can apply changes to values" do
34
+ transformation.value { |value| value.upcase }
35
+ expect(transformation.apply).to eq({
36
+ title: "FACTS OF THE WORLD",
37
+ countries: [
38
+ { name: "NEW ZEALAND", population: "4 MIL" },
39
+ { name: "AMERICA", population: "320 MIL" }
40
+ ]
41
+ })
42
+ end
43
+ end
44
+ end
45
+ end
data/spec/spec_helper.rb CHANGED
@@ -21,3 +21,5 @@ VCR.configure do |config|
21
21
  config.ignore_hosts 'codeclimate.com'
22
22
  config.hook_into :webmock
23
23
  end
24
+
25
+ WebMock.disable_net_connect!(:allow => "codeclimate.com")
@@ -29,7 +29,7 @@ module EventMatchers
29
29
 
30
30
  matcher :be_in_order do
31
31
  match do |events|
32
- events == events.sort_by(&:start_date)
32
+ events == events.sort_by(&:start_time)
33
33
  end
34
34
 
35
35
  failure_message do |events|
@@ -17,7 +17,7 @@ Almanack.config do |c|
17
17
  {
18
18
  title: "Edit my calendar's settings",
19
19
  description: "Edit the configuration at #{__FILE__}",
20
- start_date: Time.now + 30 * 60
20
+ start_time: Time.now + 30 * 60
21
21
  }
22
22
  ]
23
23
  end