event_calendar_engine 0.1.11 → 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/Gemfile.lock +39 -35
- data/VERSION +1 -1
- data/app/controllers/event_revisions_controller.rb +1 -1
- data/app/controllers/events_controller.rb +21 -36
- data/app/controllers/links_controller.rb +62 -0
- data/app/helpers/event_calendar/application_helper.rb +73 -4
- data/app/models/event.rb +21 -43
- data/app/models/event_instance_methods.rb +40 -9
- data/app/models/link.rb +19 -0
- data/app/views/event_revisions/_list_group.html.erb +1 -1
- data/app/views/events/_details.html.erb +2 -1
- data/app/views/events/_event.html.erb +2 -0
- data/app/views/events/_event_details.html.erb +22 -17
- data/app/views/events/_form.html.erb +47 -3
- data/app/views/events/_list_group.html.erb +1 -1
- data/app/views/events/_one_day_list_event.html.erb +1 -1
- data/app/views/events/edit.html.erb +1 -1
- data/app/views/links/_form.html.erb +18 -0
- data/app/views/links/_link.html.erb +6 -0
- data/app/views/links/_links.html.erb +6 -0
- data/app/views/links/create.js.rjs +14 -0
- data/app/views/links/edit.html.erb +3 -0
- data/app/views/links/new.html.erb +3 -0
- data/app/views/links/show.html.erb +3 -0
- data/app/views/links/update.js.rjs +15 -0
- data/config/routes.rb +1 -56
- data/db/migrate/20110204223256_add_presenters_facilitators_to_events.rb +11 -0
- data/db/migrate/20110206000427_create_event_calendar_links.rb +23 -0
- data/db/schema.rb +18 -1
- data/public/javascripts/event_calendar/event_calendar.js +7 -0
- data/public/javascripts/event_calendar/event_calendar_behaviors.js +92 -23
- data/public/stylesheets/event_calendar/blueprint/screen.css +1 -0
- data/spec/controllers/events_controller_spec.rb +4 -2
- data/spec/controllers/links_controller_spec.rb +140 -0
- data/spec/fixtures/event_calendar_events.yml +12 -2
- data/spec/fixtures/event_calendar_events_links.yml +3 -0
- data/spec/fixtures/event_calendar_links.yml +4 -0
- data/spec/helpers/event_calendar/application_helper_spec.rb +4 -4
- data/spec/models/event_instance_methods_spec.rb +58 -0
- data/spec/models/event_revision_spec.rb +11 -10
- data/spec/models/event_spec.rb +31 -65
- data/spec/models/link_spec.rb +31 -0
- data/spec/spec_helpers/helpers.rb +15 -0
- metadata +29 -6
- data/app/views/events/_times.html.erb +0 -5
data/db/schema.rb
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
#
|
11
11
|
# It's strongly recommended to check this file into your version control system.
|
12
12
|
|
13
|
-
ActiveRecord::Schema.define(:version =>
|
13
|
+
ActiveRecord::Schema.define(:version => 20110206000427) do
|
14
14
|
|
15
15
|
create_table "event_calendar_attendees", :force => true do |t|
|
16
16
|
t.integer "event_id"
|
@@ -41,6 +41,23 @@ ActiveRecord::Schema.define(:version => 20101223233354) do
|
|
41
41
|
t.datetime "revisable_deleted_at"
|
42
42
|
t.boolean "revisable_is_current", :default => true
|
43
43
|
t.string "timezone"
|
44
|
+
t.text "presenters"
|
45
|
+
t.text "facilitators"
|
46
|
+
end
|
47
|
+
|
48
|
+
create_table "event_calendar_events_links", :id => false, :force => true do |t|
|
49
|
+
t.integer "event_id"
|
50
|
+
t.integer "link_id"
|
51
|
+
end
|
52
|
+
|
53
|
+
add_index "event_calendar_events_links", ["event_id", "link_id"], :name => "index_event_calendar_events_links_on_event_id_and_link_id"
|
54
|
+
|
55
|
+
create_table "event_calendar_links", :force => true do |t|
|
56
|
+
t.string "name"
|
57
|
+
t.string "url"
|
58
|
+
t.text "description"
|
59
|
+
t.datetime "created_at"
|
60
|
+
t.datetime "updated_at"
|
44
61
|
end
|
45
62
|
|
46
63
|
end
|
@@ -14,6 +14,13 @@ jQuery(function($) {
|
|
14
14
|
$('ul.events').attach(Collapsible);
|
15
15
|
$('a.show_hide_link').attach(ShowHideLink);
|
16
16
|
$('a.view_events').attach(EventView);
|
17
|
+
$('div.links').attach(MagicButtons);
|
18
|
+
$('div.links').attach(QuickZoom);
|
19
|
+
$('div.event').attach(QuickZoom);
|
20
|
+
$('ul.events').attach(QuickZoom);
|
21
|
+
$('div.links').attach(DynamicForm, {
|
22
|
+
formElement: $('#link_dynamic_form')
|
23
|
+
});
|
17
24
|
});
|
18
25
|
|
19
26
|
/*
|
@@ -132,32 +132,63 @@ ShowHideLink = $.klass({
|
|
132
132
|
|
133
133
|
DynamicForm = $.klass({
|
134
134
|
initialize: function(options) {
|
135
|
-
this.
|
136
|
-
this.
|
137
|
-
this.
|
138
|
-
this.
|
139
|
-
this.
|
140
|
-
this.
|
135
|
+
this.formElement = options.formElement;
|
136
|
+
this.resourceType = this.formElement.attr('id').replace('_dynamic_form', '');
|
137
|
+
this.resourceInputs = this.formElement.find(':input[id^="'+this.resourceType+'"]');
|
138
|
+
this.resourcePlural = this.element.attr('id');
|
139
|
+
this.originalAction = this.formElement.attr('action');
|
140
|
+
this.formElement.remove();
|
141
141
|
},
|
142
|
-
onclick:
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
142
|
+
onclick: $.delegate({
|
143
|
+
'.new': function(clickedElement, event) {
|
144
|
+
event.preventDefault();
|
145
|
+
$('#'+this.formElement.attr('id')).remove();
|
146
|
+
this.formElement.clearForm();
|
147
|
+
this.formElement.attr('action', this.originalAction);
|
148
|
+
this.formElement.find(':input[name="_method"]').attr('value', 'post');
|
149
|
+
this.formElement.insertAfter(clickedElement);
|
150
|
+
this.formElement.attach(Remote.Form);
|
151
|
+
this.formElement.show();
|
152
|
+
},
|
153
|
+
'.cancel': function(clickedElement, event) {
|
154
|
+
event.preventDefault();
|
155
|
+
this.formElement.clearForm();
|
156
|
+
this.formElement.attr('action', this.originalAction);
|
157
|
+
this.formElement.find(':input[name="_method"]').attr('value', 'post');
|
158
|
+
$('#'+this.formElement.attr('id')).remove();
|
159
|
+
},
|
160
|
+
'.edit': function(clickedElement, event) {
|
161
|
+
event.preventDefault();
|
162
|
+
$('#'+this.formElement.attr('id')).remove();
|
163
|
+
|
164
|
+
var resourceContainer = clickedElement.parents('.' + this.resourceType);
|
165
|
+
var resourceId = /\d+/.exec(resourceContainer.attr('id'))[0];
|
166
|
+
|
167
|
+
// append resourceId to current form action
|
168
|
+
this.formElement.attr("action", this.originalAction + "/" + resourceId);
|
169
|
+
this.formElement.find(':input[name="_method"]').attr('value', 'put');
|
170
|
+
|
171
|
+
// clear form input values
|
172
|
+
this.formElement.clearForm();
|
173
|
+
// move form to resource
|
174
|
+
this.formElement.insertBefore(clickedElement);
|
175
|
+
|
176
|
+
this.resourceInputs.each(function() {
|
177
|
+
if( this.type != 'submit' ) {
|
178
|
+
// get resource attr names from form input ids
|
179
|
+
var resourceAttrContainer = resourceContainer.find('.'+this.id);
|
180
|
+
// get resource attr vals from w/in resource container
|
181
|
+
this.value = $.trim(resourceAttrContainer.text());
|
182
|
+
}
|
183
|
+
});
|
184
|
+
|
185
|
+
this.formElement.attach(Remote.Form);
|
186
|
+
this.formElement.show();
|
187
|
+
}
|
188
|
+
})
|
158
189
|
});
|
159
190
|
|
160
|
-
EventView = $.klass({
|
191
|
+
var EventView = $.klass({
|
161
192
|
onclick: function(e) {
|
162
193
|
if( this.element.hasClass('calendar') ) {
|
163
194
|
$('#event_list').hide();
|
@@ -169,6 +200,40 @@ EventView = $.klass({
|
|
169
200
|
}
|
170
201
|
});
|
171
202
|
|
203
|
+
var MagicButtons = $.klass({
|
204
|
+
initialize: function() {
|
205
|
+
if( this.element.find('.magic').size() > 0 ) {
|
206
|
+
this.element.find('.magic').hide();
|
207
|
+
}
|
208
|
+
},
|
209
|
+
onmouseover: $.delegate({
|
210
|
+
'p': function(mousedElement, event) {
|
211
|
+
if( mousedElement.find('.magic').size() > 0 ) {
|
212
|
+
mousedElement.find('.magic').show();
|
213
|
+
}
|
214
|
+
}
|
215
|
+
}),
|
216
|
+
onmouseout: $.delegate({
|
217
|
+
'p': function(mousedElement, event) {
|
218
|
+
if( mousedElement.find('.magic').size() > 0 ) {
|
219
|
+
mousedElement.find('.magic').hide();
|
220
|
+
}
|
221
|
+
}
|
222
|
+
})
|
223
|
+
});
|
224
|
+
var QuickZoom = $.klass({
|
225
|
+
onmouseover: $.delegate({
|
226
|
+
'.zoom': function(mousedElement, event) {
|
227
|
+
mousedElement.addClass('enlarge');
|
228
|
+
}
|
229
|
+
}),
|
230
|
+
onmouseout: $.delegate({
|
231
|
+
'.enlarge': function(mousedElement, event) {
|
232
|
+
mousedElement.removeClass('enlarge');
|
233
|
+
}
|
234
|
+
})
|
235
|
+
});
|
236
|
+
|
172
237
|
var Collapsible = $.klass({
|
173
238
|
initialize: function() {
|
174
239
|
this.element.find('.open').each(function(i, e) {
|
@@ -180,6 +245,10 @@ var Collapsible = $.klass({
|
|
180
245
|
},
|
181
246
|
onclick: $.delegate({
|
182
247
|
'.collapsible': function(clickedElement, event) {
|
248
|
+
expanded = clickedElement.siblings().find(':visible').size();
|
249
|
+
if( expanded < 1 ) {
|
250
|
+
event.preventDefault();
|
251
|
+
}
|
183
252
|
clickedElement.siblings().toggle();
|
184
253
|
}
|
185
254
|
})
|
@@ -5,11 +5,13 @@ describe EventsController do
|
|
5
5
|
let(:event) do
|
6
6
|
mock_model(Event, {
|
7
7
|
:name => 'Some Event',
|
8
|
-
:start_on =>
|
8
|
+
:start_on => 4.hours.from_now,
|
9
|
+
:start_time= => 4.hours.from_now,
|
9
10
|
:end_on => Date.tomorrow,
|
10
11
|
:timezone => 'Pacific Time (US & Canada)',
|
11
12
|
:description => 'Some Description',
|
12
|
-
:location => 'Some City'
|
13
|
+
:location => 'Some City',
|
14
|
+
:links => mock('Relation', :build => mock_model(Link))
|
13
15
|
})
|
14
16
|
end
|
15
17
|
let(:params) do
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LinksController do
|
4
|
+
subject{ Event }
|
5
|
+
let(:stub_link) do
|
6
|
+
stub_model(Link)
|
7
|
+
end
|
8
|
+
let(:link) do
|
9
|
+
mock_model(Link)
|
10
|
+
end
|
11
|
+
let(:event) do
|
12
|
+
mock_model(Event, {
|
13
|
+
:save! => nil,
|
14
|
+
:links => mock('Relation', {
|
15
|
+
:build => stub_link
|
16
|
+
})
|
17
|
+
})
|
18
|
+
end
|
19
|
+
before(:each) do
|
20
|
+
subject.stub(:find).and_return(event)
|
21
|
+
end
|
22
|
+
describe "GET :edit, :event_id => int, :id => int" do
|
23
|
+
let(:params) do
|
24
|
+
{:event_id => event.id, :id => link.id}
|
25
|
+
end
|
26
|
+
before(:each) do
|
27
|
+
Link.should_receive(:find){ link }
|
28
|
+
end
|
29
|
+
it "loads an @event and @link" do
|
30
|
+
get :edit, params
|
31
|
+
assigns(:event).should eq event
|
32
|
+
assigns(:link).should eq link
|
33
|
+
end
|
34
|
+
it "renders the edit template" do
|
35
|
+
get :edit, params
|
36
|
+
response.should render_template('links/edit')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
describe "PUT :update, :event_id => int, :id => int, :link => {}" do
|
40
|
+
let(:params) do
|
41
|
+
{:event_id => event.id, :id => link.id}
|
42
|
+
end
|
43
|
+
let(:link_params) do
|
44
|
+
{:name => 'Updated', :url => 'example.com/updated.html'}
|
45
|
+
end
|
46
|
+
before(:each) do
|
47
|
+
link.stub(:update_attributes){ nil }
|
48
|
+
Link.should_receive(:find){ link }
|
49
|
+
end
|
50
|
+
it "loads an @event and @link" do
|
51
|
+
put :update, params
|
52
|
+
assigns(:event).should eq event
|
53
|
+
assigns(:link).should eq link
|
54
|
+
end
|
55
|
+
it "updates the @link" do
|
56
|
+
link.should_receive(:update_attributes).with(link_params.stringify_keys)
|
57
|
+
put :update, params.merge!({:link => link_params})
|
58
|
+
end
|
59
|
+
context "update succeeds :)" do
|
60
|
+
before(:each) do
|
61
|
+
link.stub(:update_attributes){ true }
|
62
|
+
end
|
63
|
+
it "sets flash[:notice]" do
|
64
|
+
put :update, params
|
65
|
+
flash[:notice].should_not be_nil
|
66
|
+
end
|
67
|
+
it "as http: redirects to @event" do
|
68
|
+
put :update, params
|
69
|
+
response.should redirect_to event_path(event)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
context "update fails :(" do
|
73
|
+
before(:each) do
|
74
|
+
link.stub(:update_attributes){ false }
|
75
|
+
end
|
76
|
+
it "as http: renders the edit template" do
|
77
|
+
put :update, params
|
78
|
+
response.should render_template('links/edit')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
it "as xhr: renders update.rjs" do
|
82
|
+
xhr :put, :update, params
|
83
|
+
response.should render_template('links/update')
|
84
|
+
end
|
85
|
+
end
|
86
|
+
describe "POST :create, :event_id => int, :link => {}" do
|
87
|
+
let(:params) do
|
88
|
+
{:event_id => event.id}
|
89
|
+
end
|
90
|
+
let(:link_params) do
|
91
|
+
{:name => 'Created', :url => 'http://test.com'}
|
92
|
+
end
|
93
|
+
it "loads an @event" do
|
94
|
+
post :create, params
|
95
|
+
assigns(:event).should eq event
|
96
|
+
end
|
97
|
+
it "builds a new link" do
|
98
|
+
event.links.should_receive(:build).with(link_params.stringify_keys)
|
99
|
+
post :create, params.merge!({:link => link_params})
|
100
|
+
end
|
101
|
+
it "saves! the @event, without triggering a revision" do
|
102
|
+
event.should_receive(:save!).with(:without_revision => true)
|
103
|
+
post :create, params
|
104
|
+
end
|
105
|
+
it "as http: renders events/show if an ActiveRecord::RecordInvalid exception is raised" do
|
106
|
+
event.stub(:save!){ raise ActiveRecord::RecordInvalid.new(event) }
|
107
|
+
post :create, params
|
108
|
+
response.should render_template('events/show')
|
109
|
+
end
|
110
|
+
it "sets a flash[:notice]" do
|
111
|
+
post :create, params
|
112
|
+
flash[:notice].should_not be_nil
|
113
|
+
end
|
114
|
+
it "as http: redirects to the event" do
|
115
|
+
post :create, params
|
116
|
+
response.should redirect_to event_path(event)
|
117
|
+
end
|
118
|
+
it "as xhr: renders create.rjs" do
|
119
|
+
xhr :post, :create, params
|
120
|
+
response.should render_template('links/create')
|
121
|
+
end
|
122
|
+
end
|
123
|
+
describe "DELETE :destroy, :event_id => int, :id => int" do
|
124
|
+
let(:params) do
|
125
|
+
{:event_id => event.id, :id => link.id}
|
126
|
+
end
|
127
|
+
before(:each) do
|
128
|
+
link.stub(:destroy){ nil }
|
129
|
+
Link.should_receive(:find){ link }
|
130
|
+
end
|
131
|
+
it "destroys a link" do
|
132
|
+
link.should_receive(:destroy)
|
133
|
+
delete :destroy, params
|
134
|
+
end
|
135
|
+
it "as http: redirects to :event_id" do
|
136
|
+
delete :destroy, params
|
137
|
+
response.should redirect_to event_path event.id
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -4,5 +4,15 @@ editable_event:
|
|
4
4
|
event_type: Conference
|
5
5
|
location: "Eugene, Oregon"
|
6
6
|
description: "Will be great! Lots of good info, food and drinks!"
|
7
|
-
start_on: "10
|
8
|
-
end_on: "10
|
7
|
+
start_on: "2010-10-14"
|
8
|
+
end_on: "2010-10-15"
|
9
|
+
timezone: 'Pacific Time (US & Canada)'
|
10
|
+
|
11
|
+
restorable_event:
|
12
|
+
id: <%= Fixtures.identify :restorable_event %>
|
13
|
+
name: Restorable Event
|
14
|
+
event_type: Meeting
|
15
|
+
location: "Portland, Oregon"
|
16
|
+
start_on: 2011-02-04 14:00:00.000000
|
17
|
+
end_on: 2011-02-04 15:00:00.000000
|
18
|
+
timezone: 'Pacific Time (US & Canada)'
|
@@ -5,10 +5,10 @@ describe EventCalendar::ApplicationHelper do
|
|
5
5
|
it "returns times" do
|
6
6
|
time = Time.now
|
7
7
|
helper.time_with_zones(time).should eq [
|
8
|
-
["
|
9
|
-
["
|
10
|
-
["
|
11
|
-
["
|
8
|
+
["Eastern", time.in_time_zone("Eastern Time (US & Canada)").strftime(TIME_BASE)],
|
9
|
+
["Central", time.in_time_zone("Central Time (US & Canada)").strftime(TIME_BASE)],
|
10
|
+
["Mountain", time.in_time_zone("Mountain Time (US & Canada)").strftime(TIME_BASE)],
|
11
|
+
["Pacific", time.in_time_zone("Pacific Time (US & Canada)").strftime(TIME_BASE)]
|
12
12
|
]
|
13
13
|
end
|
14
14
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'acts_as_fu'
|
3
|
+
RSpec.configure do |config|
|
4
|
+
config.include ActsAsFu
|
5
|
+
end
|
6
|
+
|
7
|
+
describe EventInstanceMethods do
|
8
|
+
before(:each) do
|
9
|
+
build_model :fake_event do
|
10
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[Rails.env.to_sym])
|
11
|
+
string :name
|
12
|
+
datetime :start_on
|
13
|
+
datetime :end_on
|
14
|
+
string :timezone
|
15
|
+
|
16
|
+
include EventInstanceMethods
|
17
|
+
end
|
18
|
+
end
|
19
|
+
let(:event) do
|
20
|
+
FakeEvent.new({
|
21
|
+
:name => 'One Day',
|
22
|
+
:start_on => Time.now,
|
23
|
+
:end_on => Time.now,
|
24
|
+
:timezone => "Pacific Time (US & Canada)"
|
25
|
+
})
|
26
|
+
end
|
27
|
+
|
28
|
+
context "distinguishing one day events from the rest" do
|
29
|
+
it "given a start_on & end_on, compare day, month and year" do
|
30
|
+
event.one_day?.should be_true
|
31
|
+
event.end_on = 1.day.from_now
|
32
|
+
event.one_day?.should be_false
|
33
|
+
end
|
34
|
+
it "given only a start_on, return true" do
|
35
|
+
event.end_on = nil
|
36
|
+
event.one_day?.should be_true
|
37
|
+
end
|
38
|
+
it "given only a end_on, ... return true" do
|
39
|
+
event.start_on = nil
|
40
|
+
event.one_day?.should be_true
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "knows start|end_day" do
|
45
|
+
event.start_day.should eq Date.today.day
|
46
|
+
event.end_day.should eq Date.today.day
|
47
|
+
end
|
48
|
+
|
49
|
+
it "knows start|end_month" do
|
50
|
+
event.start_month.should eq Date.today.strftime('%B')
|
51
|
+
event.end_month.should eq Date.today.strftime("%B")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "knows start|end_year" do
|
55
|
+
event.start_year.should eq Date.today.year
|
56
|
+
event.end_year.should eq Date.today.year
|
57
|
+
end
|
58
|
+
end
|