From 6660006aa36f0fee80149ca27dc76cb255c8b52a Mon Sep 17 00:00:00 2001 From: phil Date: Wed, 11 Jun 2014 13:34:39 +0200 Subject: [PATCH 01/19] initial version of strong parameters, some specs still failing --- Gemfile | 1 - Gemfile.lock | 3 --- app/controllers/api/messages_controller.rb | 6 ++++- .../api/social_shares_controller.rb | 10 +++++--- app/controllers/comments_controller.rb | 6 ++++- app/controllers/embed_talks_controller.rb | 2 ++ app/controllers/errors_controller.rb | 2 ++ app/controllers/search_controller.rb | 11 +++++--- app/controllers/venues_controller.rb | 23 +++++++++-------- app/models/appearance.rb | 2 -- app/models/comment.rb | 2 -- app/models/message.rb | 2 -- app/models/setting.rb | 2 -- app/models/social_share.rb | 3 +-- app/models/talk.rb | 4 --- app/models/user.rb | 6 ----- app/models/venue.rb | 3 --- config/initializers/globalize_fix.rb | 3 --- .../api/social_shares_controller_spec.rb | 1 + spec/controllers/venues_controller_spec.rb | 25 +++++++++---------- 20 files changed, 55 insertions(+), 62 deletions(-) delete mode 100644 config/initializers/globalize_fix.rb diff --git a/Gemfile b/Gemfile index 8ada81b16..2773d7a7e 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,6 @@ source 'https://rubygems.org' gem 'rails', '4.0.2' #gem 'turbolinks' -gem 'protected_attributes' # support legacy 'attr_accessible' gem 'rails-i18n' gem 'pg' diff --git a/Gemfile.lock b/Gemfile.lock index 2ccfeed10..934c80027 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -292,8 +292,6 @@ GEM polyglot (0.3.3) private_pub (1.0.3) faye - protected_attributes (1.0.5) - activemodel (>= 4.0.1, < 5.0) pry (0.9.12.4) coderay (~> 1.0) method_source (~> 0.8) @@ -489,7 +487,6 @@ DEPENDENCIES pg_search! poltergeist private_pub - protected_attributes pry-rails rack-cache rails (= 4.0.2) diff --git a/app/controllers/api/messages_controller.rb b/app/controllers/api/messages_controller.rb index 206a1a852..136ef571d 100644 --- a/app/controllers/api/messages_controller.rb +++ b/app/controllers/api/messages_controller.rb @@ -13,7 +13,7 @@ def create good = good || @talk.venue.users.include?(user) return render text: 'Computer says no', status: 740 unless good - message = @talk.messages.build(params[:message]) + message = @talk.messages.build(message_params) message.user = user message.save! @@ -43,4 +43,8 @@ def verified_request? super || form_authenticity_token == request.headers['X-XSRF-TOKEN'] end + def message_params + params.require(:message).permit(:content) + end + end diff --git a/app/controllers/api/social_shares_controller.rb b/app/controllers/api/social_shares_controller.rb index 0999d5029..92ab0a5f1 100644 --- a/app/controllers/api/social_shares_controller.rb +++ b/app/controllers/api/social_shares_controller.rb @@ -3,7 +3,7 @@ class Api::SocialSharesController < ApplicationController before_filter :authenticate_user! def create - @social_share = SocialShare.new(params[:social_share]) + @social_share = SocialShare.new(social_share_params) @social_share.request_ip = request.remote_addr @social_share.user_agent = request.user_agent @social_share.user_id = current_user.id @@ -18,9 +18,11 @@ def create end private + def social_share_params - params.require(:social_share).permit(:request_ip, :user_agent, - :shareable_id, :shareable_type, - :social_network) + params.require(:social_share).permit( :shareable_id, + :shareable_type, + :social_network ) end + end diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 68eca3ee0..c37627e80 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -7,7 +7,7 @@ def create authorize! :create, Comment venue = Venue.find(params[:venue_id]) - comment = venue.comments.build(params[:comment]) + comment = venue.comments.build(comment_params) comment.user = current_user if comment.save @@ -29,4 +29,8 @@ def send_email(comment, users) end end + def comment_params + params.require(:comment).permit(:content) + end + end diff --git a/app/controllers/embed_talks_controller.rb b/app/controllers/embed_talks_controller.rb index 478b519f2..a870dc842 100644 --- a/app/controllers/embed_talks_controller.rb +++ b/app/controllers/embed_talks_controller.rb @@ -1,4 +1,5 @@ class EmbedTalksController < ApplicationController + after_action :allow_iframe, only: :show def show @@ -14,4 +15,5 @@ def show def allow_iframe response.headers.except! 'X-Frame-Options' end + end diff --git a/app/controllers/errors_controller.rb b/app/controllers/errors_controller.rb index 91049cfa5..46f09c072 100644 --- a/app/controllers/errors_controller.rb +++ b/app/controllers/errors_controller.rb @@ -1,4 +1,5 @@ class ErrorsController < ApplicationController + skip_before_filter :check_browser # Handling exceptions dynamically using middleware. @@ -15,4 +16,5 @@ def show # Dedicated landing page for outdated browsers def upgrade_browser end + end diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 1b3e50619..0f3fa3bb2 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -2,15 +2,15 @@ class SearchController < ApplicationController PER_PAGE = 10 + before_action :set_query + # POST /search def create - redirect_to "/search/1/" + u(params[:query]) + redirect_to "/search/1/" + u(@query) end # GET /search/1/:query def show - @query = params[:query] - @results = PgSearch.multisearch(@query). paginate(page: params[:page], per_page: PER_PAGE) @@ -33,4 +33,9 @@ def u(str) ERB::Util.url_encode(str) end + def set_query + params.permit(:query) + @query = params[:query] + end + end diff --git a/app/controllers/venues_controller.rb b/app/controllers/venues_controller.rb index ab68c6c15..86a109fb3 100644 --- a/app/controllers/venues_controller.rb +++ b/app/controllers/venues_controller.rb @@ -51,9 +51,6 @@ def new # GET /venues/1/edit def edit - if params[:renew] - @renew = true - end authorize! :edit, @venue respond_to do |format| format.html {} @@ -64,7 +61,7 @@ def edit # POST /venues # POST /venues.json def create - @venue = Venue.new(params[:venue]) + @venue = Venue.new(venue_params) @venue.user = current_user authorize! :create, @venue @@ -90,7 +87,7 @@ def update authorize! :update, @venue respond_to do |format| - if @venue.update_attributes(params[:venue]) + if @venue.update_attributes(venue_params) format.html { redirect_to @venue, notice: 'Venue was successfully updated.' } format.json { head :no_content } else @@ -113,11 +110,11 @@ def destroy end end - def tags # TODO: check if needed - scope = ActsAsTaggableOn::Tag.where(["name ILIKE ?", "%#{params[:q]}%"]) - tags = scope.paginate(:page => params[:page], :per_page => params[:limit] || 10) - render json: { tags: tags, total: scope.count } - end + # def tags # TODO: check if needed + # scope = ActsAsTaggableOn::Tag.where(["name ILIKE ?", "%#{params[:q]}%"]) + # tags = scope.paginate(:page => params[:page], :per_page => params[:limit] || 10) + # render json: { tags: tags, total: scope.count } + # end private @@ -131,4 +128,10 @@ def set_venue @venue = Venue.find(params[:id]) end + # Only allow a trusted parameter "white list" through. + def venue_params + params.require(:venue).permit(:title, :teaser, :description, + :image, :tag_list) + end + end diff --git a/app/models/appearance.rb b/app/models/appearance.rb index f4026f40f..d0a99578e 100644 --- a/app/models/appearance.rb +++ b/app/models/appearance.rb @@ -6,8 +6,6 @@ # * user_id [integer] - belongs to :user class Appearance < ActiveRecord::Base - attr_accessible :user_id - validates :user, :talk, presence: true belongs_to :user diff --git a/app/models/comment.rb b/app/models/comment.rb index 3a2ba0080..396ccd629 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -8,8 +8,6 @@ # * user_id [integer, not null] - belongs to :user class Comment < ActiveRecord::Base - attr_accessible :content - belongs_to :commentable, polymorphic: true belongs_to :user diff --git a/app/models/message.rb b/app/models/message.rb index 330f0d5c6..2693e3fb9 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -7,8 +7,6 @@ # * user_id [integer] - belongs to :user class Message < ActiveRecord::Base - attr_accessible :content - belongs_to :user belongs_to :talk diff --git a/app/models/setting.rb b/app/models/setting.rb index b934b6445..1e5547644 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -22,8 +22,6 @@ class Setting < ActiveRecord::Base validates :key, :value, presence: true - attr_accessible :key, :value - class << self def get(key) # try to find an entry in the db diff --git a/app/models/social_share.rb b/app/models/social_share.rb index 13e99cfee..9ef6c3836 100644 --- a/app/models/social_share.rb +++ b/app/models/social_share.rb @@ -9,10 +9,9 @@ # * user_agent [string] - TODO: document me # * user_id [integer] - TODO: document me class SocialShare < ActiveRecord::Base - attr_accessible :request_ip, :user_agent, :user_id, :shareable_id, - :shareable_type, :social_network belongs_to :shareable, polymorphic: true validates :shareable_type, inclusion: %w(talk venue) + end diff --git a/app/models/talk.rb b/app/models/talk.rb index e81f8f7bf..e64363549 100644 --- a/app/models/talk.rb +++ b/app/models/talk.rb @@ -75,10 +75,6 @@ class Talk < ActiveRecord::Base acts_as_taggable - attr_accessible :title, :teaser, :duration, :uri, - :description, :record, :image, :tag_list, - :guest_list, :starts_at_date, :starts_at_time - belongs_to :venue, :inverse_of => :talks has_many :appearances, dependent: :destroy has_many :guests, through: :appearances, source: :user diff --git a/app/models/user.rb b/app/models/user.rb index 2edaf0391..3e10687bb 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -34,12 +34,6 @@ class User < ActiveRecord::Base extend FriendlyId friendly_id :name, use: [:slugged, :finders] - attr_accessible :password, :password_confirmation, :remember_me - attr_accessible :email, :firstname, :lastname - attr_accessible :provider, :uid, :last_request_at, :available - attr_accessible :accept_terms_of_use, :guest, :header, :avatar, :about - attr_accessible :timezone, :website - has_many :comments, dependent: :destroy has_many :messages, dependent: :destroy diff --git a/app/models/venue.rb b/app/models/venue.rb index a34cb90cb..1fe4987d9 100644 --- a/app/models/venue.rb +++ b/app/models/venue.rb @@ -26,9 +26,6 @@ class Venue < ActiveRecord::Base acts_as_taggable - attr_accessible :title, :teaser, :description, :tag_list, - :talks_attributes, :image, :uri - # TODO: rename to host belongs_to :user diff --git a/config/initializers/globalize_fix.rb b/config/initializers/globalize_fix.rb deleted file mode 100644 index 73feaae75..000000000 --- a/config/initializers/globalize_fix.rb +++ /dev/null @@ -1,3 +0,0 @@ -Globalize::ActiveRecord::Translation.class_eval do - attr_accessible :locale -end \ No newline at end of file diff --git a/spec/controllers/api/social_shares_controller_spec.rb b/spec/controllers/api/social_shares_controller_spec.rb index 22ad59f59..0648d59b0 100644 --- a/spec/controllers/api/social_shares_controller_spec.rb +++ b/spec/controllers/api/social_shares_controller_spec.rb @@ -4,6 +4,7 @@ describe 'anonymous' do it 'does not return with unauthorized' do + pending 'fails with strong parameters' venue = FactoryGirl.create(:venue, user: @current_user) @talk = FactoryGirl.create(:talk, venue: venue) xhr :post, :create, id: @talk.id diff --git a/spec/controllers/venues_controller_spec.rb b/spec/controllers/venues_controller_spec.rb index 4fff760a4..6ac081540 100644 --- a/spec/controllers/venues_controller_spec.rb +++ b/spec/controllers/venues_controller_spec.rb @@ -31,6 +31,10 @@ def valid_attributes FactoryGirl.attributes_for(:venue) end + def invalid_attributes + { asdf: 'asdf' } + end + def valid_session {} end @@ -102,12 +106,12 @@ def valid_session describe "with invalid params" do it "assigns a newly created but unsaved venue as @venue" do - post :create, {:venue => { }}, valid_session + post :create, {venue: invalid_attributes}, valid_session assigns(:venue).should be_a_new(Venue) end it "re-renders the 'new' template" do - post :create, {:venue => { }}, valid_session + post :create, {venue: invalid_attributes}, valid_session response.should render_template("new") end @@ -123,14 +127,9 @@ def valid_session describe "PUT update" do describe "with valid params" do it "updates the requested venue" do - venue = FactoryGirl.create(:venue, :user => @user) - _time = Time.now - # Assuming there are no other venues in the database, this - # specifies that the Venue created on the previous line - # receives the :update_attributes message with whatever params are - # submitted in the request. - Venue.any_instance.should_receive(:update_attributes).with({ "start_time" => _time.to_s }) - put :update, {:id => venue.to_param, :venue => { "start_time" => _time.to_s }}, valid_session + venue = FactoryGirl.create(:venue, user: @user) + put :update, {id: venue.to_param, venue: { title: 'blablub' }}, valid_session + expect(venue.reload.title).to eq('blablub') end it "assigns the requested venue as @venue" do @@ -151,7 +150,7 @@ def valid_session venue = FactoryGirl.create(:venue, :user => @user) # Trigger the behavior that occurs when invalid params are submitted Venue.any_instance.stub(:save).and_return(false) - put :update, {:id => venue.to_param, :venue => { }}, valid_session + put :update, {:id => venue.to_param, venue: invalid_attributes}, valid_session assigns(:venue).should eq(venue) end @@ -159,7 +158,7 @@ def valid_session venue = FactoryGirl.create(:venue, :user => @user) # Trigger the behavior that occurs when invalid params are submitted Venue.any_instance.stub(:save).and_return(false) - put :update, {:id => venue.to_param, :venue => { }}, valid_session + put :update, {:id => venue.to_param, venue: invalid_attributes}, valid_session response.should render_template("edit") end end @@ -168,7 +167,7 @@ def valid_session it "raises permission denied" do venue = FactoryGirl.create(:venue) expect { - put :update, {:id => venue.to_param, :venue => { }}, valid_session + put :update, {:id => venue.to_param, venue: invalid_attributes}, valid_session }.to raise_error # CanCan::AccessDenied end end From 6e39b50f7165539c92df8a7d85ae5103805df4ce Mon Sep 17 00:00:00 2001 From: phil Date: Wed, 11 Jun 2014 14:35:01 +0200 Subject: [PATCH 02/19] down to 3 failing specs :fish::fish::fish: --- app/controllers/application_controller.rb | 4 +-- app/controllers/users_controller.rb | 17 ++++++++-- .../api/social_shares_controller_spec.rb | 9 ++--- spec/controllers/users_controller_spec.rb | 34 +++++-------------- 4 files changed, 31 insertions(+), 33 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 6fa555506..5954b8f39 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -77,10 +77,10 @@ def store_location before_filter :update_sanitized_params, if: :devise_controller? + # strong parameters for devise def update_sanitized_params devise_parameter_sanitizer.for(:sign_up) do |u| - u.permit(:firstname, :lastname, :accept_terms_of_use, - :email, :password, :password_confirmation) + u.permit(UsersController::PERMITTED_ATTRS) end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index bba13b47e..e71fb136f 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,5 +1,12 @@ class UsersController < ApplicationController + PERMITTED_ATTRS = [ :firstname, + :lastname, + :accept_terms_of_use, + :email, + :password, + :password_confirmation ] + before_filter :authenticate_user!, :only => [:edit,:update,:destroy] # layout "application", :only => [:welcome] @@ -47,7 +54,7 @@ def edit # POST /users # POST /users.json def create - @user = User.new(params[:user]) + @user = User.new(user_params) respond_to do |format| if @user.save @@ -69,7 +76,7 @@ def update authorize! :update, @user respond_to do |format| - if @user.update_attributes(params[:user]) + if @user.update_attributes(user_params) format.html do redirect_to @user, flash: { notice: I18n.t("flash.actions.update.notice") } end @@ -100,4 +107,10 @@ def destroy end end + private + + def user_params + params.require(:user).permit(PERMITTED_ATTRS) + end + end diff --git a/spec/controllers/api/social_shares_controller_spec.rb b/spec/controllers/api/social_shares_controller_spec.rb index 0648d59b0..fbdf559c3 100644 --- a/spec/controllers/api/social_shares_controller_spec.rb +++ b/spec/controllers/api/social_shares_controller_spec.rb @@ -4,10 +4,9 @@ describe 'anonymous' do it 'does not return with unauthorized' do - pending 'fails with strong parameters' venue = FactoryGirl.create(:venue, user: @current_user) @talk = FactoryGirl.create(:talk, venue: venue) - xhr :post, :create, id: @talk.id + xhr :post, :create, id: @talk.id, social_share: { asdf: 'asdf' } response.status.should_not be(401) response.status.should be(200) end @@ -33,7 +32,8 @@ it 'tracks what was shared' do expect { xhr :post, :create, social_share: { shareable_type: 'talk', - shareable_id: @talk.id, social_network: 'facebook' } + shareable_id: @talk.id, + social_network: 'facebook' } }.to change(SocialShare, :count).by(1) share = SocialShare.last @@ -44,7 +44,8 @@ end it 'returns json to verify success' do - xhr :post, :create, social_share: { shareable_type: 'talk', shareable_id: @talk.id } + xhr :post, :create, social_share: { shareable_type: 'talk', + shareable_id: @talk.id } res = JSON.parse(response.body) res['message'].should == I18n.t("social_share/has_been_tracked") end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index f0d5af0e6..22871fa67 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -7,26 +7,14 @@ request.env['warden'].stub :authenticate! => @user controller.stub :current_user => @user end - # This should return the minimal set of attributes required to create a valid - # User. As you add validations to User, be sure to - # update the return value of this method accordingly. - def valid_attributes - FactoryGirl.attributes_for(:user) - end - - # This should return the minimal set of values that should be in the session - # in order to pass any filters (e.g. authentication) defined in - # UsersController. Be sure to keep this updated too. - def valid_session - {} - end describe "GET show" do let(:user) { FactoryGirl.create(:user) } it "assigns the requested user as @user" do - get :show, {:id => user.to_param}, valid_session + get :show, {:id => user.to_param} assigns(:user).should eq(user) end + it "returns http success with format rss" do get :show, id: user.to_param, format: 'rss' response.should be_success @@ -36,22 +24,18 @@ def valid_session describe "PUT update" do describe "with valid params" do it "updates the requested user" do - # Assuming there are no other users in the database, this - # specifies that the User created on the previous line - # receives the :update_attributes message with whatever params are - # submitted in the request. - User.any_instance.should_receive(:update_attributes).with({'these' => 'params'}) - put :update, {:id => @user.to_param, :user => {'these' => 'params'}}, valid_session + put :update, id: @user.to_param, user: { firstname: 'Hugo' } + expect(@user.reload.firstname).to eq('Hugo') end it "assigns the requested user as @user" do - put :update, {:id => @user.to_param, :user => valid_attributes}, valid_session + put :update, id: @user.to_param, user: { firstname: 'Hugo' } assigns(:user).should eq(@user) end it "redirects to the user" do - put :update, {:id => @user.to_param, :user => @user.attributes[:email] }, valid_session # - response.should redirect_to(user_url(:id => @user)) + put :update, id: @user.to_param, user: { firstname: 'Hugo' } + response.should redirect_to(user_url(id: @user)) end end @@ -59,14 +43,14 @@ def valid_session it "assigns the user as @user" do # Trigger the behavior that occurs when invalid params are submitted User.any_instance.stub(:save).and_return(false) - put :update, {:id => @user.to_param, :user => {}}, valid_session + put :update, id: @user.to_param, user: { firstname: 'Hugo' } assigns(:user).should eq(@user) end it "re-renders the 'edit' template" do # Trigger the behavior that occurs when invalid params are submitted User.any_instance.stub(:save).and_return(false) - put :update, {:id => @user.to_param, :user => {}}, valid_session + put :update, id: @user.to_param, user: { firstname: 'Hugo' } response.should render_template("edit") end end From 126dc9f462e4ca6639220beb9edbf3e1c67b8fe9 Mon Sep 17 00:00:00 2001 From: phil Date: Wed, 11 Jun 2014 14:38:46 +0200 Subject: [PATCH 03/19] :fish::fish: --- app/controllers/users_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index e71fb136f..46917e667 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -4,6 +4,8 @@ class UsersController < ApplicationController :lastname, :accept_terms_of_use, :email, + :avatar, + :header, :password, :password_confirmation ] From 84399f5fd55b8e5df62ce09952b364096beb9705 Mon Sep 17 00:00:00 2001 From: phil Date: Wed, 11 Jun 2014 14:46:01 +0200 Subject: [PATCH 04/19] rounding up strong parameters, one spec left to fix :fish: --- app/controllers/users/registrations_controller.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/controllers/users/registrations_controller.rb b/app/controllers/users/registrations_controller.rb index 12c3e22f9..12a3112b8 100644 --- a/app/controllers/users/registrations_controller.rb +++ b/app/controllers/users/registrations_controller.rb @@ -1,6 +1,7 @@ class Users::RegistrationsController < Devise::RegistrationsController + def new - resource = build_resource(params[:user]) + resource = build_resource(user_params) respond_with resource end @@ -8,4 +9,11 @@ def create @guest_user = session[:guest_user_id] = nil super end + + private + + def user_params + params.require(:user).permit(:firstname, :lastname, :email) + end + end From 56ee3041b255fb899af5066f300685d79a370353 Mon Sep 17 00:00:00 2001 From: phil Date: Wed, 11 Jun 2014 15:25:10 +0200 Subject: [PATCH 05/19] all green, strong parameters on their way --- app/controllers/users/omniauth_callbacks_controller.rb | 8 ++++---- app/controllers/users/registrations_controller.rb | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index 15c2ad5e7..81fd369bc 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -1,10 +1,10 @@ -require 'pp' - class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController + include Devise::Controllers::Rememberable def facebook - logger.debug("OmniauthCallbacks#facebook - omniauth.auth: \n #{request.env['omniauth.auth']}\n") + logger.debug("OmniauthCallbacks#facebook - omniauth.auth: \n" + + " #{request.env['omniauth.auth']}\n") @user = User.find_for_facebook_oauth(request.env["omniauth.auth"], current_user) unless @user.valid? @@ -12,7 +12,7 @@ def facebook flash[:error] = @user.errors.full_message(:email, "is in use") redirect_to new_user_registration_url and return end - + if @user.persisted? flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook" remember_me(@user) diff --git a/app/controllers/users/registrations_controller.rb b/app/controllers/users/registrations_controller.rb index 12a3112b8..ce42cf4a6 100644 --- a/app/controllers/users/registrations_controller.rb +++ b/app/controllers/users/registrations_controller.rb @@ -13,6 +13,7 @@ def create private def user_params + return {} unless params[:user] # for redirect on subscribe params.require(:user).permit(:firstname, :lastname, :email) end From 7791df930c89400a117bb332e13f650b3256d36f Mon Sep 17 00:00:00 2001 From: phil Date: Wed, 11 Jun 2014 15:25:36 +0200 Subject: [PATCH 06/19] add strong parameters overview or file --- doc/strong_parameters.org | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 doc/strong_parameters.org diff --git a/doc/strong_parameters.org b/doc/strong_parameters.org new file mode 100644 index 000000000..0cb073630 --- /dev/null +++ b/doc/strong_parameters.org @@ -0,0 +1,20 @@ +| Controller | Model | Permitted Params | +|----------------------+-------------+-----------------------------------------------------------------------------------------------------------| +| Api::Messages | Message | content | +| Api::SocialShares | SocialShare | shareable_id, shareable_type, social_network | +| Api::Talks | - | - | +| Api::Users | - | - | +|----------------------+-------------+-----------------------------------------------------------------------------------------------------------| +| Comments | Comment | content | +| EmbedTalks | - | - | +| Errors | - | - | +| LandingPage | - | - | +| Participations | - | - | +| Search | n/a | query | +| Talks | Talk | title, teaser, description, starts_at_time, starts_at_date, duration, record, image, tag_list, guest_list | +| Users | User | firstname, lastname, accept_terms_of_use, email, avatar, header, password, password_confirmation | +| Venues | Venue | title, teaser, description, image, tag_list | +|----------------------+-------------+-----------------------------------------------------------------------------------------------------------| +| Users::Registrations | User | :firstname, :lastname, :email | +| Users::Sessions | - | - | + From 1e85700a954bc265a27bc56c8706e65f7fab42b7 Mon Sep 17 00:00:00 2001 From: phil Date: Thu, 3 Jul 2014 17:50:35 +0200 Subject: [PATCH 07/19] draft version of `remember`-feature --- app/controllers/reminders_controller.rb | 37 ++++ app/models/reminder.rb | 6 + app/models/user.rb | 8 +- app/views/shared/_reminder.html.haml | 8 + app/views/shared/_talk_medium_box.html.haml | 2 +- app/views/talks/show.html.haml | 7 + app/views/users/show.html.haml | 11 ++ config/routes.rb | 3 + db/migrate/20140703142905_create_reminders.rb | 10 ++ db/schema.rb | 63 +++---- spec/controllers/reminders_controller_spec.rb | 160 ++++++++++++++++++ spec/factories.rb | 4 + spec/models/reminder_spec.rb | 9 + spec/requests/reminders_spec.rb | 11 ++ 14 files changed, 294 insertions(+), 45 deletions(-) create mode 100644 app/controllers/reminders_controller.rb create mode 100644 app/models/reminder.rb create mode 100644 app/views/shared/_reminder.html.haml create mode 100644 db/migrate/20140703142905_create_reminders.rb create mode 100644 spec/controllers/reminders_controller_spec.rb create mode 100644 spec/models/reminder_spec.rb create mode 100644 spec/requests/reminders_spec.rb diff --git a/app/controllers/reminders_controller.rb b/app/controllers/reminders_controller.rb new file mode 100644 index 000000000..cbc43beed --- /dev/null +++ b/app/controllers/reminders_controller.rb @@ -0,0 +1,37 @@ +# TODO use i18n for flash messages +# TODO use cancan for authorization +class RemindersController < ApplicationController + + before_action :authenticate_user! + + # GET /reminders + def index + @reminders = current_user.reminders + end + + # POST /reminders + def create + @reminder = Reminder.new + @reminder.user = current_user + + rememberable ||= Talk.find(params[:talk_id]) + rememberable ||= Venue.find(params[:venue_id]) + raise "Cannot find Rememberable with #{params.inspect}" if rememberable.nil? + @reminder.rememberable = rememberable + + if @reminder.save + redirect_to rememberable, notice: 'Reminder was successfully created.' + else + redirect_to rememberable, error: 'Reminder could not be created.' + end + end + + # DELETE /reminders/1 + def destroy + @reminder = Reminder.find(params[:id]) + @reminder.destroy + redirect_to current_user, anchor: 'reminders', + notice: 'Reminder was successfully destroyed.' + end + +end diff --git a/app/models/reminder.rb b/app/models/reminder.rb new file mode 100644 index 000000000..99268ae56 --- /dev/null +++ b/app/models/reminder.rb @@ -0,0 +1,6 @@ +class Reminder < ActiveRecord::Base + belongs_to :user + belongs_to :rememberable, polymorphic: true + + validates :user, presence: true +end diff --git a/app/models/user.rb b/app/models/user.rb index dd6934d8c..12c6a4f3d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -46,7 +46,8 @@ class User < ActiveRecord::Base has_many :venues # as owner has_many :participations, dependent: :destroy has_many :participating_venues, through: :participations, source: :venue - + has_many :reminders, dependent: :destroy + dragonfly_accessor :header do default Rails.root.join('app/assets/images/defaults/user-header.jpg') end @@ -139,5 +140,10 @@ def for_select def insider? !!(email =~ /@voicerepublic.com$/) end + + def remembers?(model) + reminders.exists?( rememberable_id: model.id, + rememberable_type: model.class.name ) + end end diff --git a/app/views/shared/_reminder.html.haml b/app/views/shared/_reminder.html.haml new file mode 100644 index 000000000..2041b56c9 --- /dev/null +++ b/app/views/shared/_reminder.html.haml @@ -0,0 +1,8 @@ +%li + - target = reminder.rememberable + - case target + - when Talk + = render partial: 'shared/talk_medium_box', locals: { talk: target } + - else + - raise "Hey, you need to implement display of #{target.class.name}" + = link_to t('.delete_reminder'), reminder, method: 'delete' diff --git a/app/views/shared/_talk_medium_box.html.haml b/app/views/shared/_talk_medium_box.html.haml index a3aa350b2..ccf873351 100644 --- a/app/views/shared/_talk_medium_box.html.haml +++ b/app/views/shared/_talk_medium_box.html.haml @@ -1,4 +1,4 @@ -- talk = talk_medium_box +- talk ||= talk_medium_box %li.talk-medium-box.box-grey .left-box diff --git a/app/views/talks/show.html.haml b/app/views/talks/show.html.haml index 10abb2993..76d3d3687 100644 --- a/app/views/talks/show.html.haml +++ b/app/views/talks/show.html.haml @@ -174,6 +174,13 @@ - url = [ @talk.venue, :participations ] = link_to t('.participate'), url, method: 'post', class: 'button-vr' + - unless current_user.remembers?(@talk) + .row + .large-12.columns + .remember-button-box.text-center + - url = [ @talk, :reminders ] + = link_to t('.remember'), url, method: 'post', class: 'button-vr' + .talk-host-and-participants-action-box.row .large-12.columns.text-center .talkers-action-box diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index 3306286bb..3f6d525b6 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -34,6 +34,10 @@ %a(href="#venues") %span.icon-guide = t('.venues') + %dd.text-center + %a(href="#reminders") + %span.icon-reminders + = t('.reminders') -# -#%dd.text-center -# %a(href="#schedule") @@ -50,6 +54,13 @@ #venues.venues-content.content.active = render partial: 'shared/venue_medium_box', collection: @user.venues + #reminders.reminders-content.content + - if @user.reminders.empty? + = t('.no-reminders') + - else + %ul + = render partial: 'shared/reminder', collection: @user.reminders + #schedule.content TODO #activity.content TODO diff --git a/config/routes.rb b/config/routes.rb index 675964fe9..c8b0b4763 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -40,8 +40,11 @@ get :recent get :upcoming end + resources :reminders, only: [:create] end + resources :reminders, only: [:destroy] + devise_scope :user do delete "/users/sign_out" => "devise/sessions#destroy" end diff --git a/db/migrate/20140703142905_create_reminders.rb b/db/migrate/20140703142905_create_reminders.rb new file mode 100644 index 000000000..2b5d8b330 --- /dev/null +++ b/db/migrate/20140703142905_create_reminders.rb @@ -0,0 +1,10 @@ +class CreateReminders < ActiveRecord::Migration + def change + create_table :reminders do |t| + t.references :user, index: true + t.references :rememberable, polymorphic: true, index: true + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 6c56ba5f2..16d436b00 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,30 +11,13 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20140630132953) do +ActiveRecord::Schema.define(version: 20140703142905) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" enable_extension "pg_trgm" enable_extension "unaccent" - create_table "accounts", force: true do |t| - t.string "timezone" - t.string "language_1" - t.string "language_2" - t.string "language_3" - t.integer "user_id" - t.text "about" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "portrait_file_name" - t.string "portrait_content_type" - t.integer "portrait_file_size" - t.datetime "portrait_updated_at" - t.text "prefs" - t.string "website" - end - create_table "active_admin_comments", force: true do |t| t.string "namespace" t.text "body" @@ -107,13 +90,6 @@ add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree - create_table "follows", force: true do |t| - t.integer "follower_id" - t.integer "followed_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - create_table "messages", force: true do |t| t.integer "user_id" t.integer "talk_id" @@ -145,6 +121,17 @@ add_index "pg_search_documents", ["content"], name: "index_pg_search_documents_on_content", using: :btree + create_table "reminders", force: true do |t| + t.integer "user_id" + t.integer "rememberable_id" + t.string "rememberable_type" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "reminders", ["rememberable_id", "rememberable_type"], name: "index_reminders_on_rememberable_id_and_rememberable_type", using: :btree + add_index "reminders", ["user_id"], name: "index_reminders_on_user_id", using: :btree + create_table "settings", force: true do |t| t.string "key" t.string "value" @@ -191,7 +178,6 @@ t.datetime "ends_at" t.datetime "ended_at" t.boolean "collect", default: true - t.string "recording" t.datetime "created_at" t.datetime "updated_at" t.string "teaser" @@ -199,7 +185,6 @@ t.integer "duration", default: 30 t.string "image_uid" t.text "session" - t.text "audio_formats", default: "--- []\n" t.datetime "featured_from" t.string "state" t.datetime "started_at" @@ -213,9 +198,11 @@ t.text "storage", default: "--- {}\n" t.string "grade" t.string "language", default: "en" + t.string "slug" end add_index "talks", ["grade"], name: "index_talks_on_grade", using: :btree + add_index "talks", ["slug"], name: "index_talks_on_slug", unique: true, using: :btree add_index "talks", ["uri"], name: "index_talks_on_uri", using: :btree create_table "users", force: true do |t| @@ -237,11 +224,6 @@ t.string "uid" t.text "slug" t.datetime "last_request_at" - t.string "available" - t.string "image_file_name" - t.string "image_content_type" - t.integer "image_file_size" - t.datetime "image_updated_at" t.boolean "guest" t.string "header_uid" t.string "avatar_uid" @@ -255,24 +237,19 @@ add_index "users", ["slug"], name: "index_users_on_slug", unique: true, using: :btree create_table "venues", force: true do |t| - t.datetime "start_time" t.text "description" t.string "title" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "duration" - t.text "teaser" - t.datetime "featured_from" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "teaser" t.integer "user_id" - t.string "image_file_name" - t.string "image_content_type" - t.integer "image_file_size" - t.datetime "image_updated_at" - t.text "options", default: "--- {}\n" + t.text "options", default: "--- {}\n" t.string "image_uid" t.string "uri" + t.string "slug" end + add_index "venues", ["slug"], name: "index_venues_on_slug", unique: true, using: :btree add_index "venues", ["uri"], name: "index_venues_on_uri", using: :btree add_index "venues", ["user_id"], name: "index_venues_on_user_id", using: :btree diff --git a/spec/controllers/reminders_controller_spec.rb b/spec/controllers/reminders_controller_spec.rb new file mode 100644 index 000000000..5c091a0d8 --- /dev/null +++ b/spec/controllers/reminders_controller_spec.rb @@ -0,0 +1,160 @@ +require 'spec_helper' + +# This spec was generated by rspec-rails when you ran the scaffold generator. +# It demonstrates how one might use RSpec to specify the controller code that +# was generated by Rails when you ran the scaffold generator. +# +# It assumes that the implementation code is generated by the rails scaffold +# generator. If you are using any extension libraries to generate different +# controller code, this generated spec may or may not pass. +# +# It only uses APIs available in rails and/or rspec-rails. There are a number +# of tools you can use to make these specs even more expressive, but we're +# sticking to rails and rspec-rails APIs to keep things simple and stable. +# +# Compared to earlier versions of this generator, there is very limited use of +# stubs and message expectations in this spec. Stubs are only used when there +# is no simpler way to get a handle on the object needed for the example. +# Message expectations are only used when there is no simpler way to specify +# that an instance is receiving a specific message. + +describe RemindersController do + + # This should return the minimal set of attributes required to create a valid + # Reminder. As you add validations to Reminder, be sure to + # adjust the attributes here as well. + let(:valid_attributes) { { "create" => "MyString" } } + + # This should return the minimal set of values that should be in the session + # in order to pass any filters (e.g. authentication) defined in + # RemindersController. Be sure to keep this updated too. + let(:valid_session) { {} } + + describe "GET index" do + it "assigns all reminders as @reminders" do + reminder = Reminder.create! valid_attributes + get :index, {}, valid_session + assigns(:reminders).should eq([reminder]) + end + end + + describe "GET show" do + it "assigns the requested reminder as @reminder" do + reminder = Reminder.create! valid_attributes + get :show, {:id => reminder.to_param}, valid_session + assigns(:reminder).should eq(reminder) + end + end + + describe "GET new" do + it "assigns a new reminder as @reminder" do + get :new, {}, valid_session + assigns(:reminder).should be_a_new(Reminder) + end + end + + describe "GET edit" do + it "assigns the requested reminder as @reminder" do + reminder = Reminder.create! valid_attributes + get :edit, {:id => reminder.to_param}, valid_session + assigns(:reminder).should eq(reminder) + end + end + + describe "POST create" do + describe "with valid params" do + it "creates a new Reminder" do + expect { + post :create, {:reminder => valid_attributes}, valid_session + }.to change(Reminder, :count).by(1) + end + + it "assigns a newly created reminder as @reminder" do + post :create, {:reminder => valid_attributes}, valid_session + assigns(:reminder).should be_a(Reminder) + assigns(:reminder).should be_persisted + end + + it "redirects to the created reminder" do + post :create, {:reminder => valid_attributes}, valid_session + response.should redirect_to(Reminder.last) + end + end + + describe "with invalid params" do + it "assigns a newly created but unsaved reminder as @reminder" do + # Trigger the behavior that occurs when invalid params are submitted + Reminder.any_instance.stub(:save).and_return(false) + post :create, {:reminder => { "create" => "invalid value" }}, valid_session + assigns(:reminder).should be_a_new(Reminder) + end + + it "re-renders the 'new' template" do + # Trigger the behavior that occurs when invalid params are submitted + Reminder.any_instance.stub(:save).and_return(false) + post :create, {:reminder => { "create" => "invalid value" }}, valid_session + response.should render_template("new") + end + end + end + + describe "PUT update" do + describe "with valid params" do + it "updates the requested reminder" do + reminder = Reminder.create! valid_attributes + # Assuming there are no other reminders in the database, this + # specifies that the Reminder created on the previous line + # receives the :update_attributes message with whatever params are + # submitted in the request. + Reminder.any_instance.should_receive(:update).with({ "create" => "MyString" }) + put :update, {:id => reminder.to_param, :reminder => { "create" => "MyString" }}, valid_session + end + + it "assigns the requested reminder as @reminder" do + reminder = Reminder.create! valid_attributes + put :update, {:id => reminder.to_param, :reminder => valid_attributes}, valid_session + assigns(:reminder).should eq(reminder) + end + + it "redirects to the reminder" do + reminder = Reminder.create! valid_attributes + put :update, {:id => reminder.to_param, :reminder => valid_attributes}, valid_session + response.should redirect_to(reminder) + end + end + + describe "with invalid params" do + it "assigns the reminder as @reminder" do + reminder = Reminder.create! valid_attributes + # Trigger the behavior that occurs when invalid params are submitted + Reminder.any_instance.stub(:save).and_return(false) + put :update, {:id => reminder.to_param, :reminder => { "create" => "invalid value" }}, valid_session + assigns(:reminder).should eq(reminder) + end + + it "re-renders the 'edit' template" do + reminder = Reminder.create! valid_attributes + # Trigger the behavior that occurs when invalid params are submitted + Reminder.any_instance.stub(:save).and_return(false) + put :update, {:id => reminder.to_param, :reminder => { "create" => "invalid value" }}, valid_session + response.should render_template("edit") + end + end + end + + describe "DELETE destroy" do + it "destroys the requested reminder" do + reminder = Reminder.create! valid_attributes + expect { + delete :destroy, {:id => reminder.to_param}, valid_session + }.to change(Reminder, :count).by(-1) + end + + it "redirects to the reminders list" do + reminder = Reminder.create! valid_attributes + delete :destroy, {:id => reminder.to_param}, valid_session + response.should redirect_to(reminders_url) + end + end + +end diff --git a/spec/factories.rb b/spec/factories.rb index 5ce43b8ca..33f2cb917 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -66,4 +66,8 @@ value "MyString" end + factory :reminder do + user + rememberable nil + end end diff --git a/spec/models/reminder_spec.rb b/spec/models/reminder_spec.rb new file mode 100644 index 000000000..d35547e03 --- /dev/null +++ b/spec/models/reminder_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe Reminder do + + it 'is invalid without a user' do + expect(FactoryGirl.build(user: nil)).to_not be_valid + end + +end diff --git a/spec/requests/reminders_spec.rb b/spec/requests/reminders_spec.rb new file mode 100644 index 000000000..d4a32c2cc --- /dev/null +++ b/spec/requests/reminders_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe "Reminders" do + describe "GET /reminders" do + it "works! (now write some real specs)" do + # Run the generator again with the --webrat flag if you want to use webrat methods/matchers + get reminders_path + response.status.should be(200) + end + end +end From 9ade95b4b1590f85f0a536a8f883f8d49bc66d4a Mon Sep 17 00:00:00 2001 From: phil Date: Mon, 21 Jul 2014 11:35:06 +0200 Subject: [PATCH 08/19] add field for speakers and format to talk --- app/views/talks/_fields.html.haml | 3 +- config/locales/en.yml | 14 ++++++++ ...092301_add_format_and_speakers_to_talks.rb | 6 ++++ db/schema.rb | 33 ++++++++++++++----- 4 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 db/migrate/20140721092301_add_format_and_speakers_to_talks.rb diff --git a/app/views/talks/_fields.html.haml b/app/views/talks/_fields.html.haml index a4e54f9f0..a90b0be2f 100644 --- a/app/views/talks/_fields.html.haml +++ b/app/views/talks/_fields.html.haml @@ -17,7 +17,8 @@ = f.input :language, as: :grouped_select, collection: Talk::LANGUAGES, input_html: { class: 'languageSelect' }, group_method: :last, label_method: :last, value_method: :first - + = f.input :format, collection: t('.formats') + %br %br -#testdatepicker diff --git a/config/locales/en.yml b/config/locales/en.yml index 543e9fb62..3579ddf25 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -835,6 +835,15 @@ en: title: Title teaser: Teaser tag_list: Tag list + formats: + - Conference + - Reading + - Lecture + - Meeting + - Discussion + - Podcast + - Concert + - Other index: talks_on_voice_republic: TALKS ON VOICE REPUBLIC now_live: NOW LIVE @@ -929,3 +938,8 @@ en:
  • Download Internet Explorer (If you have an older version of Windows, you need to upgrade to get a newer version of Internet explorer. It's easier to use Chrome or Firefox.)
  • + simple_form: + hints: + talk: + language: Please select the main language of your talk. + format: Please provide the format purely for informational purposes. \ No newline at end of file diff --git a/db/migrate/20140721092301_add_format_and_speakers_to_talks.rb b/db/migrate/20140721092301_add_format_and_speakers_to_talks.rb new file mode 100644 index 000000000..891073eb2 --- /dev/null +++ b/db/migrate/20140721092301_add_format_and_speakers_to_talks.rb @@ -0,0 +1,6 @@ +class AddFormatAndSpeakersToTalks < ActiveRecord::Migration + def change + add_column :talks, :format, :string + add_column :talks, :speakers, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 49522b40c..16f877f8d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,10 +11,12 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20140702134835) do +ActiveRecord::Schema.define(version: 20140721092301) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" + enable_extension "pg_trgm" + enable_extension "unaccent" create_table "active_admin_comments", force: true do |t| t.string "namespace" @@ -62,8 +64,8 @@ create_table "comments", force: true do |t| t.text "content" t.integer "user_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "commentable_id" t.string "commentable_type" end @@ -102,8 +104,8 @@ create_table "participations", force: true do |t| t.integer "venue_id" t.integer "user_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "participations", ["user_id"], name: "index_participations_on_user_id", using: :btree @@ -119,6 +121,17 @@ add_index "pg_search_documents", ["content"], name: "index_pg_search_documents_on_content", using: :btree + create_table "reminders", force: true do |t| + t.integer "user_id" + t.integer "rememberable_id" + t.string "rememberable_type" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "reminders", ["rememberable_id", "rememberable_type"], name: "index_reminders_on_rememberable_id_and_rememberable_type", using: :btree + add_index "reminders", ["user_id"], name: "index_reminders_on_user_id", using: :btree + create_table "settings", force: true do |t| t.string "key" t.string "value" @@ -186,6 +199,8 @@ t.string "grade" t.string "language", default: "en" t.string "slug" + t.string "format" + t.string "speakers" end add_index "talks", ["grade"], name: "index_talks_on_grade", using: :btree @@ -195,8 +210,8 @@ create_table "users", force: true do |t| t.string "firstname" t.string "lastname" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false t.string "reset_password_token" @@ -226,8 +241,8 @@ create_table "venues", force: true do |t| t.text "description" t.string "title" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "teaser" t.integer "user_id" t.text "options", default: "--- {}\n" From 71526417488aad4c35caf42df9f541a9737d0ed4 Mon Sep 17 00:00:00 2001 From: phil Date: Mon, 21 Jul 2014 11:37:15 +0200 Subject: [PATCH 09/19] fix missed merge conflict --- spec/controllers/api/social_shares_controller_spec.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/spec/controllers/api/social_shares_controller_spec.rb b/spec/controllers/api/social_shares_controller_spec.rb index acce66807..a15471b3b 100644 --- a/spec/controllers/api/social_shares_controller_spec.rb +++ b/spec/controllers/api/social_shares_controller_spec.rb @@ -4,14 +4,8 @@ describe 'anonymous' do it 'does not return with unauthorized' do -<<<<<<< HEAD @talk = FactoryGirl.create(:talk) - xhr :post, :create, id: @talk.id -======= - venue = FactoryGirl.create(:venue, user: @current_user) - @talk = FactoryGirl.create(:talk, venue: venue) xhr :post, :create, id: @talk.id, social_share: { asdf: 'asdf' } ->>>>>>> feature/66935580/finally-strong-parameters response.status.should_not be(401) response.status.should be(200) end From 2be08ea0086766da61428f03bad8ce026067afa9 Mon Sep 17 00:00:00 2001 From: phil Date: Mon, 21 Jul 2014 11:42:37 +0200 Subject: [PATCH 10/19] add format to list of strong parameters --- app/controllers/talks_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/talks_controller.rb b/app/controllers/talks_controller.rb index 8b298f4b8..28a5fc849 100644 --- a/app/controllers/talks_controller.rb +++ b/app/controllers/talks_controller.rb @@ -115,7 +115,8 @@ def talk_params params.require(:talk).permit(:title, :teaser, :starts_at_date, :starts_at_time, :duration, :description, :collect, :image, - :tag_list, :guest_list, :language) + :tag_list, :guest_list, :language, + :format) end end From 6d6f90e84118dd35fa928125645ed83cb7e15f46 Mon Sep 17 00:00:00 2001 From: phil Date: Mon, 21 Jul 2014 13:18:50 +0200 Subject: [PATCH 11/19] render speaker list into a meta tag of talk page --- app/views/shared/_social_meta_tags.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/shared/_social_meta_tags.html.haml b/app/views/shared/_social_meta_tags.html.haml index 66e736e16..58743276b 100644 --- a/app/views/shared/_social_meta_tags.html.haml +++ b/app/views/shared/_social_meta_tags.html.haml @@ -2,7 +2,7 @@ - title = @talk.title - image = "https://#{request.host}#{@talk.flyer.path}" - keywords = @talk.try(:tag_list) -- author = @talk.venue.user.name +- author = @talk.speakers || @talk.venue.user.name - _user_url = user_url(@talk.user) - _venue_url = venue_url(@talk.venue) -# Google From d10ef79304d143d5c2bb93d0a290b63967e7a8c4 Mon Sep 17 00:00:00 2001 From: phil Date: Mon, 21 Jul 2014 13:21:21 +0200 Subject: [PATCH 12/19] when speakers are set, display these on the talk page's stage, instead of host & guests --- app/views/talks/show.html.haml | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/app/views/talks/show.html.haml b/app/views/talks/show.html.haml index 6d8816482..7a4c77178 100644 --- a/app/views/talks/show.html.haml +++ b/app/views/talks/show.html.haml @@ -155,20 +155,23 @@ .talk-talkers-box.row .large-12.columns.text-center - .avatar.avatar-host - .avatar-box - = render partial: "shared/avatar_image", locals: {user: @talk.venue.user, img_size: 62} - .avatar-name.text-center - = @talk.venue.user.name - .avatar(ng-repeat="guest in guests()") - .avatar-box - = render partial: "shared/avatar_image", locals: {user: 'guest', img_size: 62} - .avatar-name.text-center - {{ guest.name }} - .host-actions(ng-show='showHostActions()') - .guest-demote-link(ng-click="demote(guest.id)") - = t('.demote') - + - unless @talk.speakers.blank? + %p.speakers= @talk.speakers + - else + .avatar.avatar-host + .avatar-box + = render partial: "shared/avatar_image", locals: {user: @talk.venue.user, img_size: 62} + .avatar-name.text-center + = @talk.venue.user.name + .avatar(ng-repeat="guest in guests()") + .avatar-box + = render partial: "shared/avatar_image", locals: {user: 'guest', img_size: 62} + .avatar-name.text-center + {{ guest.name }} + .host-actions(ng-show='showHostActions()') + .guest-demote-link(ng-click="demote(guest.id)") + = t('.demote') + .talk-visitors-action-box.row.collapse-large-only(ng-show="userIsAListener()") .large-12.columns .participate-button-box.text-center From b0b7d5752c9fe42a8c1dbc4ae2bba2286e2819ed Mon Sep 17 00:00:00 2001 From: "Munen Alain M. Lafon" Date: Wed, 23 Jul 2014 11:33:44 +0200 Subject: [PATCH 13/19] fix comments --- app/controllers/comments_controller.rb | 5 +++-- spec/controllers/comments_controller_spec.rb | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index c37627e80..7d0444231 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -7,7 +7,8 @@ def create authorize! :create, Comment venue = Venue.find(params[:venue_id]) - comment = venue.comments.build(comment_params) + comment = venue.comments.build + comment.content = comment_params["content"] comment.user = current_user if comment.save @@ -32,5 +33,5 @@ def send_email(comment, users) def comment_params params.require(:comment).permit(:content) end - + end diff --git a/spec/controllers/comments_controller_spec.rb b/spec/controllers/comments_controller_spec.rb index 56b0c43e0..9c9a94591 100644 --- a/spec/controllers/comments_controller_spec.rb +++ b/spec/controllers/comments_controller_spec.rb @@ -1,13 +1,13 @@ require 'spec_helper' describe CommentsController do - + describe 'with user logged in' do - + before do @user = FactoryGirl.create(:user) request.env['warden'].stub :authenticate! => @user - controller.stub :current_user => @user + controller.stub :current_user => @user end describe 'POST create' do From 679155acd2dc340894f6db46d16fea1779837511 Mon Sep 17 00:00:00 2001 From: "Munen Alain M. Lafon" Date: Wed, 23 Jul 2014 11:50:56 +0200 Subject: [PATCH 14/19] Revert "fix comments" This reverts commit b0b7d5752c9fe42a8c1dbc4ae2bba2286e2819ed. --- app/controllers/comments_controller.rb | 5 ++--- spec/controllers/comments_controller_spec.rb | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 7d0444231..c37627e80 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -7,8 +7,7 @@ def create authorize! :create, Comment venue = Venue.find(params[:venue_id]) - comment = venue.comments.build - comment.content = comment_params["content"] + comment = venue.comments.build(comment_params) comment.user = current_user if comment.save @@ -33,5 +32,5 @@ def send_email(comment, users) def comment_params params.require(:comment).permit(:content) end - + end diff --git a/spec/controllers/comments_controller_spec.rb b/spec/controllers/comments_controller_spec.rb index 9c9a94591..56b0c43e0 100644 --- a/spec/controllers/comments_controller_spec.rb +++ b/spec/controllers/comments_controller_spec.rb @@ -1,13 +1,13 @@ require 'spec_helper' describe CommentsController do - + describe 'with user logged in' do - + before do @user = FactoryGirl.create(:user) request.env['warden'].stub :authenticate! => @user - controller.stub :current_user => @user + controller.stub :current_user => @user end describe 'POST create' do From 622fd0f5f038f9561cdca6510e7856db15162932 Mon Sep 17 00:00:00 2001 From: "Munen Alain M. Lafon" Date: Wed, 23 Jul 2014 12:04:26 +0200 Subject: [PATCH 15/19] add comment --- app/views/shared/_podcast.rss.builder | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/shared/_podcast.rss.builder b/app/views/shared/_podcast.rss.builder index 7231ac940..7743fc855 100644 --- a/app/views/shared/_podcast.rss.builder +++ b/app/views/shared/_podcast.rss.builder @@ -45,7 +45,7 @@ xml.rss namespaces.merge(version: '2.0') do langs = @podcast.talks.map(&:language).compact langs = %w(en) if langs.empty? main_lang = langs.inject(Hash.new { |h, k| h[k] = 0 }) { |h, l| h[l]+=1; h }.to_a.sort_by { |e| e.last }.last.first - xml.language main_lang + xml.language main_lang xml.image do xml.url @podcast.image_url xml.title do @@ -80,7 +80,7 @@ xml.rss namespaces.merge(version: '2.0') do talks.each do |talk| # skip talks where media is missing for whatever reason next unless talk.podcast_file - + xml.item do xml.title h talk.title @@ -89,6 +89,7 @@ xml.rss namespaces.merge(version: '2.0') do xml.itunes :summary, talk.description_as_plaintext xml.itunes :subtitle, talk.teaser + # TODO: Maybe we want to show the speakers here? xml.itunes :author, talk.venue.user.name xml.itunes :duration, talk.podcast_file[:duration] xml.itunes :explicit, 'no' From 0d194525d67ea171db10ae12f970dc736dd973b3 Mon Sep 17 00:00:00 2001 From: "Munen Alain M. Lafon" Date: Wed, 23 Jul 2014 12:36:20 +0200 Subject: [PATCH 16/19] Uncomment VenuesController#tags. * The action is needed for looking up tags in Venue#form. Otherwise a AbstractController::ActionNotFound will be thrown and autocomplete does not work anymore * This is hard to test. I wrote a spec for it, but it did not fail well enough. --- app/controllers/venues_controller.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/controllers/venues_controller.rb b/app/controllers/venues_controller.rb index 86a109fb3..b5cce7b4a 100644 --- a/app/controllers/venues_controller.rb +++ b/app/controllers/venues_controller.rb @@ -23,10 +23,10 @@ def show format.html do @upcoming_talks = @venue.talks.where(state: [:prelive, :live]).ordered @archived_talks = @venue.talks.archived.ordered - + @participation = @venue.participations.find_by(user_id: current_user.id) - + @show_join = @participation.nil? && current_user != @venue.user end @@ -110,11 +110,11 @@ def destroy end end - # def tags # TODO: check if needed - # scope = ActsAsTaggableOn::Tag.where(["name ILIKE ?", "%#{params[:q]}%"]) - # tags = scope.paginate(:page => params[:page], :per_page => params[:limit] || 10) - # render json: { tags: tags, total: scope.count } - # end + def tags + scope = ActsAsTaggableOn::Tag.where(["name ILIKE ?", "%#{params[:q]}%"]) + tags = scope.paginate(:page => params[:page], :per_page => params[:limit] || 10) + render json: { tags: tags, total: scope.count } + end private From b8c417811640fe12b2748945d0e144c8bdaf34ea Mon Sep 17 00:00:00 2001 From: "Munen Alain M. Lafon" Date: Wed, 23 Jul 2014 14:40:39 +0200 Subject: [PATCH 17/19] add spec --- spec/controllers/talks_controller_spec.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec/controllers/talks_controller_spec.rb b/spec/controllers/talks_controller_spec.rb index e08ab047d..b1af664ae 100644 --- a/spec/controllers/talks_controller_spec.rb +++ b/spec/controllers/talks_controller_spec.rb @@ -87,6 +87,12 @@ post :create, { venue_id: @venue.id, talk: valid_attributes } Talk.all[2].tag_list.should_not be_empty end + + it 'talk has attached format after creation' do + Talk.count.should be(2) # @talk & @talk_2 + post :create, { venue_id: @venue.id, talk: valid_attributes.merge(format: "foo_conf") } + Talk.all[2].format.should == "foo_conf" + end end describe "download message history" do From 51289e994a6cb02119094fdae38033a2565c26c3 Mon Sep 17 00:00:00 2001 From: phil Date: Wed, 23 Jul 2014 15:43:30 +0200 Subject: [PATCH 18/19] fix specs --- spec/controllers/reminders_controller_spec.rb | 146 ++---------------- spec/models/reminder_spec.rb | 2 +- spec/requests/reminders_spec.rb | 11 -- 3 files changed, 16 insertions(+), 143 deletions(-) delete mode 100644 spec/requests/reminders_spec.rb diff --git a/spec/controllers/reminders_controller_spec.rb b/spec/controllers/reminders_controller_spec.rb index 5c091a0d8..f12bb755f 100644 --- a/spec/controllers/reminders_controller_spec.rb +++ b/spec/controllers/reminders_controller_spec.rb @@ -1,159 +1,43 @@ require 'spec_helper' -# This spec was generated by rspec-rails when you ran the scaffold generator. -# It demonstrates how one might use RSpec to specify the controller code that -# was generated by Rails when you ran the scaffold generator. -# -# It assumes that the implementation code is generated by the rails scaffold -# generator. If you are using any extension libraries to generate different -# controller code, this generated spec may or may not pass. -# -# It only uses APIs available in rails and/or rspec-rails. There are a number -# of tools you can use to make these specs even more expressive, but we're -# sticking to rails and rspec-rails APIs to keep things simple and stable. -# -# Compared to earlier versions of this generator, there is very limited use of -# stubs and message expectations in this spec. Stubs are only used when there -# is no simpler way to get a handle on the object needed for the example. -# Message expectations are only used when there is no simpler way to specify -# that an instance is receiving a specific message. - describe RemindersController do - # This should return the minimal set of attributes required to create a valid - # Reminder. As you add validations to Reminder, be sure to - # adjust the attributes here as well. - let(:valid_attributes) { { "create" => "MyString" } } - - # This should return the minimal set of values that should be in the session - # in order to pass any filters (e.g. authentication) defined in - # RemindersController. Be sure to keep this updated too. - let(:valid_session) { {} } - - describe "GET index" do - it "assigns all reminders as @reminders" do - reminder = Reminder.create! valid_attributes - get :index, {}, valid_session - assigns(:reminders).should eq([reminder]) - end - end - - describe "GET show" do - it "assigns the requested reminder as @reminder" do - reminder = Reminder.create! valid_attributes - get :show, {:id => reminder.to_param}, valid_session - assigns(:reminder).should eq(reminder) - end - end - - describe "GET new" do - it "assigns a new reminder as @reminder" do - get :new, {}, valid_session - assigns(:reminder).should be_a_new(Reminder) - end - end - - describe "GET edit" do - it "assigns the requested reminder as @reminder" do - reminder = Reminder.create! valid_attributes - get :edit, {:id => reminder.to_param}, valid_session - assigns(:reminder).should eq(reminder) - end - end - describe "POST create" do describe "with valid params" do + + let(:talk) { FactoryGirl.create(:talk) } + it "creates a new Reminder" do expect { - post :create, {:reminder => valid_attributes}, valid_session + post :create, talk_id: talk.id }.to change(Reminder, :count).by(1) end - + it "assigns a newly created reminder as @reminder" do - post :create, {:reminder => valid_attributes}, valid_session + post :create, talk_id: talk.id assigns(:reminder).should be_a(Reminder) assigns(:reminder).should be_persisted end - + it "redirects to the created reminder" do - post :create, {:reminder => valid_attributes}, valid_session - response.should redirect_to(Reminder.last) - end - end - - describe "with invalid params" do - it "assigns a newly created but unsaved reminder as @reminder" do - # Trigger the behavior that occurs when invalid params are submitted - Reminder.any_instance.stub(:save).and_return(false) - post :create, {:reminder => { "create" => "invalid value" }}, valid_session - assigns(:reminder).should be_a_new(Reminder) - end - - it "re-renders the 'new' template" do - # Trigger the behavior that occurs when invalid params are submitted - Reminder.any_instance.stub(:save).and_return(false) - post :create, {:reminder => { "create" => "invalid value" }}, valid_session - response.should render_template("new") - end - end - end - - describe "PUT update" do - describe "with valid params" do - it "updates the requested reminder" do - reminder = Reminder.create! valid_attributes - # Assuming there are no other reminders in the database, this - # specifies that the Reminder created on the previous line - # receives the :update_attributes message with whatever params are - # submitted in the request. - Reminder.any_instance.should_receive(:update).with({ "create" => "MyString" }) - put :update, {:id => reminder.to_param, :reminder => { "create" => "MyString" }}, valid_session - end - - it "assigns the requested reminder as @reminder" do - reminder = Reminder.create! valid_attributes - put :update, {:id => reminder.to_param, :reminder => valid_attributes}, valid_session - assigns(:reminder).should eq(reminder) - end - - it "redirects to the reminder" do - reminder = Reminder.create! valid_attributes - put :update, {:id => reminder.to_param, :reminder => valid_attributes}, valid_session - response.should redirect_to(reminder) - end - end - - describe "with invalid params" do - it "assigns the reminder as @reminder" do - reminder = Reminder.create! valid_attributes - # Trigger the behavior that occurs when invalid params are submitted - Reminder.any_instance.stub(:save).and_return(false) - put :update, {:id => reminder.to_param, :reminder => { "create" => "invalid value" }}, valid_session - assigns(:reminder).should eq(reminder) - end - - it "re-renders the 'edit' template" do - reminder = Reminder.create! valid_attributes - # Trigger the behavior that occurs when invalid params are submitted - Reminder.any_instance.stub(:save).and_return(false) - put :update, {:id => reminder.to_param, :reminder => { "create" => "invalid value" }}, valid_session - response.should render_template("edit") + post :create, talk_id: talk.id + response.should redirect_to(talk) end end end describe "DELETE destroy" do it "destroys the requested reminder" do - reminder = Reminder.create! valid_attributes + reminder = FactoryGirl.create(:reminder) expect { - delete :destroy, {:id => reminder.to_param}, valid_session + delete :destroy, {:id => reminder.to_param} }.to change(Reminder, :count).by(-1) end - it "redirects to the reminders list" do - reminder = Reminder.create! valid_attributes - delete :destroy, {:id => reminder.to_param}, valid_session - response.should redirect_to(reminders_url) + it "redirects to the users reminders list" do + reminder = FactoryGirl.create(:reminder) + delete :destroy, {:id => reminder.to_param} + response.should redirect_to(controller.current_user) end end diff --git a/spec/models/reminder_spec.rb b/spec/models/reminder_spec.rb index d35547e03..9ed91dec2 100644 --- a/spec/models/reminder_spec.rb +++ b/spec/models/reminder_spec.rb @@ -3,7 +3,7 @@ describe Reminder do it 'is invalid without a user' do - expect(FactoryGirl.build(user: nil)).to_not be_valid + expect(FactoryGirl.build(:reminder, user: nil)).to_not be_valid end end diff --git a/spec/requests/reminders_spec.rb b/spec/requests/reminders_spec.rb deleted file mode 100644 index d4a32c2cc..000000000 --- a/spec/requests/reminders_spec.rb +++ /dev/null @@ -1,11 +0,0 @@ -require 'spec_helper' - -describe "Reminders" do - describe "GET /reminders" do - it "works! (now write some real specs)" do - # Run the generator again with the --webrat flag if you want to use webrat methods/matchers - get reminders_path - response.status.should be(200) - end - end -end From 71dda60d868867c9839bc3a2c1a5700fd41786c4 Mon Sep 17 00:00:00 2001 From: phil Date: Wed, 23 Jul 2014 16:02:27 +0200 Subject: [PATCH 19/19] use i18n for reminders flashes --- app/controllers/reminders_controller.rb | 7 +++---- config/locales/en.yml | 6 ++++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app/controllers/reminders_controller.rb b/app/controllers/reminders_controller.rb index cbc43beed..794a9a85f 100644 --- a/app/controllers/reminders_controller.rb +++ b/app/controllers/reminders_controller.rb @@ -1,4 +1,3 @@ -# TODO use i18n for flash messages # TODO use cancan for authorization class RemindersController < ApplicationController @@ -20,9 +19,9 @@ def create @reminder.rememberable = rememberable if @reminder.save - redirect_to rememberable, notice: 'Reminder was successfully created.' + redirect_to rememberable, notice: I18n.t('reminders.create.success') else - redirect_to rememberable, error: 'Reminder could not be created.' + redirect_to rememberable, error: I18n.t('reminders.create.failure') end end @@ -31,7 +30,7 @@ def destroy @reminder = Reminder.find(params[:id]) @reminder.destroy redirect_to current_user, anchor: 'reminders', - notice: 'Reminder was successfully destroyed.' + notice: I18n.t('reminders.destroy.success') end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 79e07d17f..02ca89356 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -930,3 +930,9 @@ en:
  • Download Internet Explorer (If you have an older version of Windows, you need to upgrade to get a newer version of Internet explorer. It's easier to use Chrome or Firefox.)
  • + reminders: + create: + success: Reminder was successfully created. + failure: Reminder could not be created. + destroy: + success: Reminder was successfully destroyed.