diff --git a/app/assets/stylesheets/style.css.sass b/app/assets/stylesheets/style.css.sass index 964de195d..3a2bdc683 100644 --- a/app/assets/stylesheets/style.css.sass +++ b/app/assets/stylesheets/style.css.sass @@ -526,7 +526,7 @@ footer border-left: 5px solid transition-duration: 0.2s -.message_container +.feedback padding: 90px text-align: center line-height: 2em diff --git a/app/controllers/feedback_controller.rb b/app/controllers/feedback_controller.rb index 6e4893a6f..330ffd028 100644 --- a/app/controllers/feedback_controller.rb +++ b/app/controllers/feedback_controller.rb @@ -1,15 +1,13 @@ class FeedbackController < ApplicationController def show - redirect_to action: 'not_found' unless Feedback.find_by_token(params[:id]) + redirect_to action: 'not_found' unless FeedbackRequest.find_by(token: params[:id], submited: false) - @feedback = Feedback.new(token: params[:id]) + @feedback = Feedback.new end def submit - redirect_to action: 'not_found' unless Feedback.find_by_token(params[:id]) - - if Feedback.submit_feedback(feedback_params) + if Feedback.submit_feedback(feedback_params, params[:id]) redirect_to success_feedback_path else @feedback = Feedback.new(feedback_params) @@ -26,6 +24,6 @@ def success; end private def feedback_params - params.require(:feedback).permit(:coach_id, :tutorial_id, :request, :rating, :suggestions, :token) + params.require(:feedback).permit(:coach_id, :tutorial_id, :request, :rating, :suggestions) end end \ No newline at end of file diff --git a/app/helpers/email_header_helper.rb b/app/helpers/email_header_helper.rb new file mode 100644 index 000000000..156d1eb76 --- /dev/null +++ b/app/helpers/email_header_helper.rb @@ -0,0 +1,15 @@ +module EmailHeaderHelper + private + + def load_attachments + %w{logo.png}.each do |image| + attachments.inline[image] = File.read("#{Rails.root.to_s}/app/assets/images/#{image}") + end + end + + def mail_args(member, subject) + { :from => "Codebar.io ", + :to => member.email, + :subject => subject } + end +end \ No newline at end of file diff --git a/app/mailers/course_invitation_mailer.rb b/app/mailers/course_invitation_mailer.rb index 951cb91d3..4e1a5e49a 100644 --- a/app/mailers/course_invitation_mailer.rb +++ b/app/mailers/course_invitation_mailer.rb @@ -1,4 +1,6 @@ class CourseInvitationMailer < ActionMailer::Base + include EmailHeaderHelper + layout 'email' def invite_student course, member, invitation @@ -23,12 +25,6 @@ def load_attachments end end - def mail_args(member, subject) - { :from => "Codebar.io ", - :to => member.email, - :subject => subject } - end - helper do def full_url_for path "#{@host}#{path}" diff --git a/app/mailers/feedback_request_mailer.rb b/app/mailers/feedback_request_mailer.rb new file mode 100644 index 000000000..80b4042f9 --- /dev/null +++ b/app/mailers/feedback_request_mailer.rb @@ -0,0 +1,26 @@ +class FeedbackRequestMailer < ActionMailer::Base + include EmailHeaderHelper + + layout 'email' + + def request_feedback sessions, member, feedback_request + @session = sessions + @host_address = AddressDecorator.decorate(@session.host.address) + @member = member + @feedback_request = feedback_request + + load_attachments + + subject = "Feedback for #{@session.title} by Codebar - #{l(@session.date_and_time, format: :email_title)}" + + mail(mail_args(member, subject)) do |format| + format.html + end + end + + helper do + def full_url_for path + "#{@host}#{path}" + end + end +end \ No newline at end of file diff --git a/app/mailers/session_invitation_mailer.rb b/app/mailers/session_invitation_mailer.rb index a3301d62a..1aa2ffb3c 100644 --- a/app/mailers/session_invitation_mailer.rb +++ b/app/mailers/session_invitation_mailer.rb @@ -1,4 +1,6 @@ class SessionInvitationMailer < ActionMailer::Base + include EmailHeaderHelper + layout 'email' def invite_student sessions, member, invitation @@ -95,18 +97,6 @@ def spots_available session, member, invitation private - def load_attachments - %w{logo.png}.each do |image| - attachments.inline[image] = File.read("#{Rails.root.to_s}/app/assets/images/#{image}") - end - end - - def mail_args(member, subject) - { :from => "Codebar.io ", - :to => member.email, - :subject => subject } - end - helper do def full_url_for path "#{@host}#{path}" diff --git a/app/models/concerns/listable.rb b/app/models/concerns/listable.rb index ecbab54e3..8db9afe47 100644 --- a/app/models/concerns/listable.rb +++ b/app/models/concerns/listable.rb @@ -11,5 +11,8 @@ module ClassMethods def next upcoming.load.first end + def most_recent + past.load.first + end end end diff --git a/app/models/feedback.rb b/app/models/feedback.rb index b61d46b61..3d54f7d15 100644 --- a/app/models/feedback.rb +++ b/app/models/feedback.rb @@ -2,7 +2,7 @@ class Feedback < ActiveRecord::Base belongs_to :tutorial belongs_to :coach, class_name: "Member" - validates :rating, presence: true, numericality: true, :inclusion => 1..5 + validates :rating, inclusion: { in: 1..5, message: "can't be blank" } validates :coach, presence: true validates :tutorial, presence: true validate :coach_field_has_a_coach_role? @@ -16,20 +16,15 @@ def coach_field_has_a_coach_role? end end - def self.submit_feedback params - return false unless Feedback.new(params).valid? - - feedback = Feedback.find_by_token(params[:token]) - - if feedback - feedback.update_attributes(params) + def self.submit_feedback params, token + return false unless feedback_request = FeedbackRequest.find_by_token(token) + feedback = Feedback.new(params) + + if feedback.valid? && !feedback_request.submited + feedback_request.update_attributes(submited: true) + feedback.save else false end end - - def self.create_token token - Feedback.new(token: token).save(validate: false) unless token.blank? - end - end \ No newline at end of file diff --git a/app/models/feedback_request.rb b/app/models/feedback_request.rb new file mode 100644 index 000000000..996713282 --- /dev/null +++ b/app/models/feedback_request.rb @@ -0,0 +1,25 @@ +class FeedbackRequest < ActiveRecord::Base + belongs_to :member + belongs_to :sessions + + validates :member, presence: true + validates :sessions, presence: true + validates :token, uniqueness: true, presence: true + validates_inclusion_of :submited, :in => [true, false] + + before_create :set_token + after_create :email + + private + + def set_token + self.token = loop do + random_token = SecureRandom.urlsafe_base64(nil, false) + break random_token unless self.class.where(token: random_token).exists? + end + end + + def email + FeedbackRequestMailer.request_feedback(self.sessions, self.member, self).deliver + end +end diff --git a/app/views/feedback/not_found.html.haml b/app/views/feedback/not_found.html.haml index 21dc492c4..bf63e4560 100644 --- a/app/views/feedback/not_found.html.haml +++ b/app/views/feedback/not_found.html.haml @@ -1,4 +1,4 @@ -.message_container +.feedback .error =I18n.t("messages.feedback_not_found") =link_to "Return to homepage >>", root_path \ No newline at end of file diff --git a/app/views/feedback/show.html.haml b/app/views/feedback/show.html.haml index fe8d4d7c8..9623f8060 100644 --- a/app/views/feedback/show.html.haml +++ b/app/views/feedback/show.html.haml @@ -11,8 +11,8 @@ - @feedback.errors.full_messages.each do |error_message| %li=error_message - = simple_form_for @feedback, url: submit_feedback_path(@feedback.token), html: {method: "patch"} do |f| - = f.hidden_field :token + = simple_form_for @feedback, url: submit_feedback_path(params[:id]), html: {method: "patch"} do |f| + = f.hidden_field :token, :value => params[:id] = f.hidden_field :rating .row %label.required diff --git a/app/views/feedback/success.html.haml b/app/views/feedback/success.html.haml index 166b955e8..3c0944faa 100644 --- a/app/views/feedback/success.html.haml +++ b/app/views/feedback/success.html.haml @@ -1,4 +1,4 @@ -.success_container +.feedback .success =I18n.t("messages.feedback_saved") diff --git a/app/views/feedback_request_mailer/request_feedback.html.erb b/app/views/feedback_request_mailer/request_feedback.html.erb new file mode 100644 index 000000000..d29e9b371 --- /dev/null +++ b/app/views/feedback_request_mailer/request_feedback.html.erb @@ -0,0 +1,11 @@ +

Hi <%= @member.name %>

+ +

Thanks for attending our codebar sessions!

+ +

We would like to ask you to give us feedback, so we could improve and make the Codebar better for you and others. It's completely anonymous and it will take just a couple of minutes.

+ +
+

<%= link_to "Submit feedback", full_url_for(feedback_url(@feedback_request.token)), style: "text-decoration:none; color: #663095; font-size: 25px; font-weight: 600; letter-spacing: 0.02em; margin: 10px; text-decoration: none; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);"%>

+
+ +

Thank you.

diff --git a/config/environments/development.rb b/config/environments/development.rb index 869d6a6f9..5c6070d59 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -9,6 +9,8 @@ # Do not eager load code on boot. config.eager_load = false + config.action_mailer.default_url_options = { :host => 'localhost:3000' } + # Show full error reports and disable caching. config.consider_all_requests_local = true config.action_controller.perform_caching = false diff --git a/config/locales/en.yml b/config/locales/en.yml index 3199b09ab..ad845f4df 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -25,7 +25,7 @@ en: member_notifications: "You will be receiving notifications for: %{roles}" no_roles: "You have not selected any roles so you won't be receiving any notifications. If you change your mind, send us an email at hello@codebar.io so we can change your settings." feedback_saved: "Feedback was successfully submited. Thank you!" - feedback_not_found: "Sorry, feedback link seems to be invalid." + feedback_not_found: "Sorry, feedback is already submited or link does not exists." notifications: provider_already_connected: 'You are already signed in!' diff --git a/db/migrate/20140119093708_create_feedback_requests.rb b/db/migrate/20140119093708_create_feedback_requests.rb new file mode 100644 index 000000000..5303363c6 --- /dev/null +++ b/db/migrate/20140119093708_create_feedback_requests.rb @@ -0,0 +1,12 @@ +class CreateFeedbackRequests < ActiveRecord::Migration + def change + create_table :feedback_requests do |t| + t.references :member, index: true + t.references :sessions, index: true + t.string :token + t.boolean :submited + + t.timestamps + end + end +end diff --git a/db/migrate/20140202112853_remove_token_from_feedbacks.rb b/db/migrate/20140202112853_remove_token_from_feedbacks.rb new file mode 100644 index 000000000..27c6e429e --- /dev/null +++ b/db/migrate/20140202112853_remove_token_from_feedbacks.rb @@ -0,0 +1,5 @@ +class RemoveTokenFromFeedbacks < ActiveRecord::Migration + def change + remove_column :feedbacks, :token, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 143f37735..1107960b0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20131222160002) do +ActiveRecord::Schema.define(version: 20140202112853) do create_table "addresses", force: true do |t| t.string "flat" @@ -59,6 +59,18 @@ t.datetime "updated_at" end + create_table "feedback_requests", force: true do |t| + t.integer "member_id" + t.integer "sessions_id" + t.string "token" + t.boolean "submited" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "feedback_requests", ["member_id"], name: "index_feedback_requests_on_member_id" + add_index "feedback_requests", ["sessions_id"], name: "index_feedback_requests_on_sessions_id" + create_table "feedbacks", force: true do |t| t.integer "tutorial_id" t.text "request" @@ -66,12 +78,10 @@ t.text "suggestions" t.datetime "created_at" t.datetime "updated_at" - t.string "token" t.integer "rating" end add_index "feedbacks", ["coach_id"], name: "index_feedbacks_on_coach_id" - add_index "feedbacks", ["token"], name: "index_feedbacks_on_token", unique: true add_index "feedbacks", ["tutorial_id"], name: "index_feedbacks_on_tutorial_id" create_table "meeting_talks", force: true do |t| diff --git a/db/seeds.rb b/db/seeds.rb index 77e0eebe9..8b4347673 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -11,9 +11,9 @@ tutorials = 10.times.map { |n| Fabricate(:tutorial, sessions: sessions.sample) } - feedbacks_not_submited = Feedback.new(token: 'feedback_valid_token').save(validate: false) + feedback_requests = 5.times.map { Fabricate(:feedback_request) } - feedbacks = 5.times { Fabricate(:feedback, tutorial: tutorials.sample, coach: coaches.sample) } + feedbacks = 5.times.map { Fabricate(:feedback, tutorial: tutorials.sample, coach: coaches.sample) } 40.times do |n| coach = coaches.sample diff --git a/lib/tasks/feedback.rake b/lib/tasks/feedback.rake new file mode 100644 index 000000000..a1a0f161c --- /dev/null +++ b/lib/tasks/feedback.rake @@ -0,0 +1,19 @@ +namespace :feedback do + desc "Request feedback from students that attendanted last session" + + task request: :environment do + raise 'Sorry. No recent sessions found.' if Sessions.most_recent.nil? + + STDOUT.print "Do you want to send feedback requests for session: #{Sessions.most_recent.title}? (y/N) " + + if STDIN.gets.chomp == 'y' + STDOUT.puts "Sending feedback requests to:" + Sessions.most_recent.invitations.attended.each do |invitation| + STDOUT.puts "#{invitation.member.full_name} <#{invitation.member.email}>" + FeedbackRequest.create(member: invitation.member, sessions: invitation.sessions, submited: false) + end + + STDOUT.puts "\nTotal requests sent: #{Sessions.most_recent.invitations.attended.count}" + end + end +end diff --git a/spec/fabricators/feedback_request_fabricator.rb b/spec/fabricators/feedback_request_fabricator.rb new file mode 100644 index 000000000..27d906405 --- /dev/null +++ b/spec/fabricators/feedback_request_fabricator.rb @@ -0,0 +1,6 @@ +Fabricator(:feedback_request) do + member + sessions + token { 'valid_token' } + submited { false } +end \ No newline at end of file diff --git a/spec/features/member_feedback_spec.rb b/spec/features/member_feedback_spec.rb index cd359a6a4..cd26b93a8 100644 --- a/spec/features/member_feedback_spec.rb +++ b/spec/features/member_feedback_spec.rb @@ -1,12 +1,13 @@ require 'spec_helper' feature 'member feedback' do - let(:valid_token) { 'feedback_valid_token' } + let(:valid_token) { Fabricate(:feedback_request).token } + let(:submited_token) { Fabricate(:feedback_request, submited: true).token } let(:invalid_token) { 'feedback_invalid_token' } let(:feedback_submited_message) { I18n.t("messages.feedback_saved") } before do - Fabricate(:feedback, token: valid_token) + Fabricate(:feedback) @coach = Fabricate(:coach, name: 'coach_name', surname: 'coach_surname') @tutorial = Fabricate(:tutorial, title: 'tutorial title') @@ -37,15 +38,24 @@ end end - scenario "I get error message when invalid token given and link to homepage" do - visit feedback_path(invalid_token) + context "I get error message with link to homepage" do + scenario "when invalid token given" do + visit feedback_path(invalid_token) - find_link('Return to homepage >>')[:href].should == root_path - expect(page).to have_content('Sorry, feedback link seems to be invalid.') + find_link('Return to homepage >>')[:href].should == root_path + expect(page).to have_content('Sorry, feedback is already submited or link does not exists.') + end + + scenario "when feedback has been already submited" do + visit feedback_path(submited_token) + + find_link('Return to homepage >>')[:href].should == root_path + expect(page).to have_content('Sorry, feedback is already submited or link does not exists.') + end end context 'When form is submitted' do - scenario 'I can see validation errors when invalid data given' do + scenario 'I can see validation errors when invalid data is given' do visit feedback_path(valid_token) click_button('Submit feedback') @@ -53,12 +63,13 @@ expect(page).to have_content("Tutorial can't be blank") end - scenario 'I can see success page with message and link to homepage when valid data' do + scenario 'I can see success page with message and link to homepage when valid data is given' do visit feedback_path(valid_token) find(:xpath, "//input[@id='feedback_rating']").set "4" select(@coach.full_name, from: 'feedback_coach_id') select(@tutorial.title, from: 'feedback_tutorial_id') + click_button('Submit feedback') current_path.should =~ /\/success/ diff --git a/spec/lib/tasks/feedback_rake_spec.rb b/spec/lib/tasks/feedback_rake_spec.rb new file mode 100644 index 000000000..e2c8ecd4c --- /dev/null +++ b/spec/lib/tasks/feedback_rake_spec.rb @@ -0,0 +1,52 @@ +require "spec_helper" + +describe "feedback:request" do + include_context "rake" + + its(:prerequisites) { should include("environment") } + + context "when most recent sessions has attended student" do + let(:session) { Fabricate(:sessions, date_and_time: 1.day.ago) } + let(:student) { Fabricate(:student) } + + before do + STDOUT.stub(:puts) + STDOUT.stub(:print) + STDIN.stub(:gets).and_return('y') + student.session_invitations << Fabricate(:attended_session_invitation, member: student, sessions: session) + end + + it 'should gracefully run' do + expect { subject.invoke }.to_not raise_error + end + + it "generates a FeedbackRequest" do + FeedbackRequest.stub(:create) + subject.invoke + FeedbackRequest.should have_received(:create).with(member: student, sessions: session, submited: false) + end + + context "confirmation message" do + it "is displayed" do + confirmation_message = "Do you want to send feedback requests for session: #{session.title}? (y/N) " + + subject.invoke + STDOUT.should have_received(:print).with(confirmation_message) + end + + it "terminates rake task if negative answer is given" do + FeedbackRequest.stub(:create) + STDIN.stub(:gets).and_return('N') + + subject.invoke + FeedbackRequest.should_not have_received(:create) + end + end + end + + context "when there is no sessions" do + it "raises error" do + expect { subject.invoke }.to raise_error(RuntimeError, 'Sorry. No recent sessions found.') + end + end +end \ No newline at end of file diff --git a/spec/mailers/feedback_request_mailer_spec.rb b/spec/mailers/feedback_request_mailer_spec.rb new file mode 100644 index 000000000..f8423c1cf --- /dev/null +++ b/spec/mailers/feedback_request_mailer_spec.rb @@ -0,0 +1,18 @@ +require "spec_helper" + +describe FeedbackRequestMailer do + + let(:email) { ActionMailer::Base.deliveries.last } + let(:session) { Fabricate(:sessions, title: "HTML & CSS") } + let(:member) { Fabricate(:member) } + let(:feedback_request) { Fabricate(:feedback_request, sessions: session, member: member) } + + it "#request_feedback" do + email_subject = "Feedback for #{session.title} by Codebar - #{I18n.l(session.date_and_time, format: :email_title)}" + + FeedbackRequestMailer.request_feedback(session, member, feedback_request).deliver + + expect(email.subject).to eq(email_subject) + expect(email.parts.first.body.raw_source).to include feedback_url(feedback_request.token) + end +end \ No newline at end of file diff --git a/spec/models/feedback_request_spec.rb b/spec/models/feedback_request_spec.rb new file mode 100644 index 000000000..98a278f09 --- /dev/null +++ b/spec/models/feedback_request_spec.rb @@ -0,0 +1,58 @@ +require 'spec_helper' + +describe FeedbackRequest do + subject { Fabricate(:feedback_request) } + + it { should respond_to(:member) } + it { should respond_to(:sessions) } + it { should respond_to(:token) } + it { should respond_to(:submited) } + + context "validations" do + context 'presence' do + it '#member should not be blank' do + feedback_request = Fabricate.build(:feedback_request, member: nil) + + feedback_request.should_not be_valid + feedback_request.should have(1).error_on(:member) + end + + it '#session should not be blank' do + feedback_request = Fabricate.build(:feedback_request, sessions: nil) + + feedback_request.should_not be_valid + feedback_request.should have(1).error_on(:sessions) + end + + it '#token should not be blank' do + feedback_request = Fabricate.build(:feedback_request, token: nil) + + feedback_request.should_not be_valid + feedback_request.should have(1).error_on(:token) + end + + it '#submited should not be blank' do + feedback_request = Fabricate.build(:feedback_request, submited: nil) + + feedback_request.should_not be_valid + feedback_request.should have(1).error_on(:submited) + end + end + end + + context "after create hook" do + it "#email" do + feedback_request = Fabricate.build(:feedback_request) + feedback_request.stub(:email) + feedback_request.save + feedback_request.should have_received(:email) + end + + it "sends request feedback email" do + FeedbackRequestMailer.stub(:request_feedback) { double('feedback_request_mailer').as_null_object } + Fabricate(:feedback_request) + FeedbackRequestMailer.should have_received(:request_feedback) + end + end + +end diff --git a/spec/models/feedback_spec.rb b/spec/models/feedback_spec.rb index 5b49a6986..2d3a66eae 100644 --- a/spec/models/feedback_spec.rb +++ b/spec/models/feedback_spec.rb @@ -7,7 +7,6 @@ let(:invalid_feedback_token) { 'invalid_feedback_token' } it { should respond_to(:request) } - it { should respond_to(:token) } it { should respond_to(:rating) } it { should respond_to(:suggestions) } it { should respond_to(:coach) } @@ -19,7 +18,7 @@ feedback = Fabricate.build(:feedback, rating: nil) feedback.should_not be_valid - feedback.should have(3).error_on(:rating) + feedback.should have(1).error_on(:rating) end it 'should accept numbers from 1 to 5' do @@ -48,7 +47,7 @@ feedback = Fabricate.build(:feedback, rating: 'alpha') feedback.should_not be_valid - feedback.should have(2).error_on(:rating) + feedback.should have(1).error_on(:rating) end end @@ -77,65 +76,31 @@ end end - context '#create_token' do - it 'is created when token is not blank' do - Feedback.create_token(valid_feedback_token) - - Feedback.find_by_token(valid_feedback_token).should_not be_nil - end - - it 'is not created when token is blank' do - Feedback.create_token('') - - Feedback.find_by_token('').should be_nil - end - end - context "#submit_feedback" do - let (:valid_params) do - { - token: valid_feedback_token, - rating: 4, - coach: Fabricate(:coach), - tutorial: Fabricate(:tutorial) - } + let(:feedback_request) { Fabricate(:feedback_request) } + + let (:params) do + { rating: 4, coach: Fabricate(:coach), tutorial: Fabricate(:tutorial) } end - let(:invalid_token_params) do - { - token: invalid_feedback_token, - rating: 4, - coach: Fabricate(:coach), - tutorial: Fabricate(:tutorial) - } - end - - let(:valid_token_invalid_params) do - { - token: valid_feedback_token, - coach: Fabricate(:coach) - } - end - - it 'is submited with valid token' do - Feedback.create_token(valid_feedback_token) - Feedback.submit_feedback(valid_params) - - Feedback.find_by(valid_params).should_not be_nil + context 'with valid token' do + it 'is submited valid params' do + expect { + Feedback.submit_feedback(params, feedback_request.token) + }.to change { Feedback.count }.by(1) + end + + it 'is not submited invalid params' do + expect { + Feedback.submit_feedback(params.except(:rating), feedback_request.token) + }.to_not change { Feedback.count } + end end it 'is not submited with invalid token' do - Feedback.create_token(valid_feedback_token) - Feedback.submit_feedback(invalid_token_params) - - Feedback.find_by(invalid_token_params).should be_nil + expect { + Feedback.submit_feedback(params, 'invalid_token') + }.to_not change { Feedback.count } end - - it 'is not submited with valid token but invalid params' do - Feedback.create_token(valid_feedback_token) - Feedback.submit_feedback(valid_token_invalid_params) - - Feedback.find_by(valid_token_invalid_params).should be_nil - end end end diff --git a/spec/models/sessions_spec.rb b/spec/models/sessions_spec.rb index 6bf458dd1..1ad390679 100644 --- a/spec/models/sessions_spec.rb +++ b/spec/models/sessions_spec.rb @@ -11,10 +11,12 @@ context "#scopes" do let(:set_upcoming) { 2.times.map { |n| Sessions.create date_and_time: DateTime.now+(n+1).week } } + let(:most_recent) { Sessions.create date_and_time: 1.day.ago } before do Sessions.create date_and_time: DateTime.now-1.week set_upcoming + most_recent end it "#upcoming" do @@ -25,6 +27,10 @@ Sessions.next.should eq set_upcoming.first end + it "#most_recent" do + Sessions.most_recent.should eq most_recent + end + describe "#host" do let(:sponsor) { Fabricate(:sponsor) } diff --git a/spec/support/shared_contexts/rake.rb b/spec/support/shared_contexts/rake.rb new file mode 100644 index 000000000..5a22765bc --- /dev/null +++ b/spec/support/shared_contexts/rake.rb @@ -0,0 +1,19 @@ +require "rake" + +shared_context "rake" do + let(:rake) { Rake::Application.new } + let(:task_name) { self.class.top_level_description } + let(:task_path) { "lib/tasks/#{task_name.split(":").first}" } + subject { rake[task_name] } + + def loaded_files_excluding_current_rake_file + $".reject {|file| file == Rails.root.join("#{task_path}.rake").to_s } + end + + before do + Rake.application = rake + Rake.application.rake_require(task_path, [Rails.root.to_s], loaded_files_excluding_current_rake_file) + + Rake::Task.define_task(:environment) + end +end \ No newline at end of file