diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index e45a792f311..cf2758b78fa 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -94,7 +94,6 @@ var initialize_modules = function() { App.LegislationAnnotatable.initialize(); App.WatchFormChanges.initialize(); App.TreeNavigator.initialize(); - App.Followable.initialize(); }; $(function(){ diff --git a/app/assets/javascripts/followable.js.coffee b/app/assets/javascripts/followable.js.coffee index 69ea61bacdb..9fa9aa319b1 100644 --- a/app/assets/javascripts/followable.js.coffee +++ b/app/assets/javascripts/followable.js.coffee @@ -1,10 +1,8 @@ App.Followable = - initialize: -> - $('.followable-content a[data-toggle]').on 'click', (event) -> - event.preventDefault() - - update: (followable_id, button) -> + update: (followable_id, button, notice) -> $("#" + followable_id + " .js-follow").html(button) - # Temporary line. Waiting for issue resolution: https://github.com/consul/consul/issues/1736 - initialize_modules() + if ($('[data-alert]').length > 0) + $('[data-alert]').replaceWith(notice) + else + $("body").append(notice) diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index b4ea0cca344..25d569ff704 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -1932,8 +1932,39 @@ table { .activity { margin-bottom: $line-height * 2; + .accordion li { + margin-bottom: $line-height / 2; + + .accordion-title { + border-bottom: 1px solid $border; + background: #f8f9fb; + font-size: $small-font-size; + padding: $line-height / 2; + } + + .accordion-content { + padding: 0; + } + } + + .accordion .title { + display: block; + line-height: $line-height; + } + + .accordion .icon { + font-size: rem-calc(20); + float: left; + margin-right: $line-height / 3; + + &.icon-debates { + margin-top: rem-calc(3); + } + } + table { border: 0; + margin-bottom: 0; } td { diff --git a/app/controllers/follows_controller.rb b/app/controllers/follows_controller.rb index 9cec999fa73..05f0e8f96ca 100644 --- a/app/controllers/follows_controller.rb +++ b/app/controllers/follows_controller.rb @@ -3,15 +3,15 @@ class FollowsController < ApplicationController load_and_authorize_resource def create - @followable = find_followable - @follow = Follow.create(user: current_user, followable: @followable) + @follow = Follow.create(user: current_user, followable: find_followable) + flash.now[:notice] = t("shared.followable.#{followable_translation_key(@follow.followable)}.create.notice_html") render :refresh_follow_button end def destroy @follow = Follow.find(params[:id]) - @followable = @follow.followable @follow.destroy + flash.now[:notice] = t("shared.followable.#{followable_translation_key(@follow.followable)}.destroy.notice_html") render :refresh_follow_button end @@ -20,4 +20,9 @@ def destroy def find_followable params[:followable_type].constantize.find(params[:followable_id]) end + + def followable_translation_key(followable) + followable.class.name.parameterize("_") + end + end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 6ef59fb60ce..ae3ce36925d 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,13 +1,12 @@ class UsersController < ApplicationController - has_filters %w{proposals debates budget_investments comments}, only: :show + has_filters %w{proposals debates budget_investments comments follows}, only: :show load_and_authorize_resource helper_method :author? - helper_method :author_or_admin? + helper_method :valid_interests_access? def show load_filtered_activity if valid_access? - load_interests if valid_interests_access? end private @@ -17,7 +16,8 @@ def set_activity_counts proposals: Proposal.where(author_id: @user.id).count, debates: (Setting['feature.debates'] ? Debate.where(author_id: @user.id).count : 0), budget_investments: (Setting['feature.budgets'] ? Budget::Investment.where(author_id: @user.id).count : 0), - comments: only_active_commentables.count) + comments: only_active_commentables.count, + follows: @user.follows.count) end def load_filtered_activity @@ -26,7 +26,8 @@ def load_filtered_activity when "proposals" then load_proposals when "debates" then load_debates when "budget_investments" then load_budget_investments - when "comments" then load_comments + when "comments" then load_comments + when "follows" then load_follows else load_available_activity end end @@ -44,6 +45,9 @@ def load_available_activity elsif @activity_counts[:comments] > 0 load_comments @current_filter = "comments" + elsif @activity_counts[:follows] > 0 + load_follows + @current_filter = "follows" end end @@ -63,8 +67,8 @@ def load_budget_investments @budget_investments = Budget::Investment.where(author_id: @user.id).order(created_at: :desc).page(params[:page]) end - def load_interests - @user.interests + def load_follows + @follows = @user.follows.group_by(&:followable_type) end def valid_access? @@ -75,12 +79,8 @@ def valid_interests_access? @user.public_interests || authorized_current_user? end - def author? - @author ||= current_user && (current_user == @user) - end - - def author_or_admin? - @author_or_admin ||= current_user && (author? || current_user.administrator?) + def author?(proposal) + proposal.author_id == current_user.id if current_user end def authorized_current_user? diff --git a/app/helpers/followables_helper.rb b/app/helpers/followables_helper.rb new file mode 100644 index 00000000000..b7fe1f1992a --- /dev/null +++ b/app/helpers/followables_helper.rb @@ -0,0 +1,30 @@ +module FollowablesHelper + + def followable_type_title(followable_type) + t("activerecord.models.#{followable_type.underscore}.other") + end + + def followable_icon(followable) + { + proposals: 'Proposal', + budget: 'Budget::Investment' + }.invert[followable] + end + + def render_follow(follow) + followable = follow.followable + partial = followable_class_name(followable) + locals = {followable_class_name(followable).to_sym => followable} + + render partial, locals + end + + def followable_class_name(followable) + followable.class.to_s.parameterize.gsub('-', '_') + end + + def find_or_build_follow(user, followable) + Follow.find_or_initialize_by(user: user, followable: followable) + end + +end diff --git a/app/helpers/follows_helper.rb b/app/helpers/follows_helper.rb index 63f50f7be6d..b3426df1258 100644 --- a/app/helpers/follows_helper.rb +++ b/app/helpers/follows_helper.rb @@ -1,61 +1,13 @@ module FollowsHelper - def show_follow_action?(followable) - current_user && !followed?(followable) - end - - def show_unfollow_action?(followable) - current_user && followed?(followable) - end - - def follow_entity_text(followable) - entity = followable.class.name.gsub('::', '/').downcase + def follow_text(followable) + entity = followable.class.name.underscore t('shared.follow_entity', entity: t("activerecord.models.#{entity}.one").downcase) end - def follow_entity_title(followable) - entity = followable.class.name.gsub('::', '/').downcase - t('shared.follow_entity_title', entity: t("activerecord.models.#{entity}.one").downcase) - end - - def unfollow_entity_text(followable) - entity = followable.class.name.gsub('::', '/').downcase + def unfollow_text(followable) + entity = followable.class.name.underscore t('shared.unfollow_entity', entity: t("activerecord.models.#{entity}.one").downcase) end - def entity_full_name(followable) - name = followable.class.name - name.downcase.gsub("::", "-") - end - - def follow_link_wrapper_id(followable) - "follow-expand-#{entity_full_name(followable)}-#{followable.id}" - end - - def unfollow_link_wrapper_id(followable) - "unfollow-expand-#{entity_full_name(followable)}-#{followable.id}" - end - - def follow_link_id(followable) - "follow-#{entity_full_name(followable)}-#{followable.id}" - end - - def unfollow_link_id(followable) - "unfollow-#{entity_full_name(followable)}-#{followable.id}" - end - - def follow_drop_id(followable) - "follow-drop-#{entity_full_name(followable)}-#{followable.id}" - end - - def unfollow_drop_id(followable) - "unfollow-drop-#{entity_full_name(followable)}-#{followable.id}" - end - - private - - def followed?(followable) - Follow.followed?(current_user, followable) - end - end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 9c13e8ef849..968fa6e6689 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -41,4 +41,4 @@ def current_administrator? current_user && current_user.administrator? end -end \ No newline at end of file +end diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb index cf183ec5306..33a9d50f6cd 100644 --- a/app/models/abilities/common.rb +++ b/app/models/abilities/common.rb @@ -50,7 +50,7 @@ def initialize(user) can :create, Budget::Investment, budget: { phase: "accepting" } can :suggest, Budget::Investment, budget: { phase: "accepting" } can :destroy, Budget::Investment, budget: { phase: ["accepting", "reviewing"] }, author_id: user.id - can :vote, Budget::Investment, budget: { phase: "selecting" } + can :vote, Budget::Investment, budget: { phase: "selecting" } can [:show, :create], Budget::Ballot, budget: { phase: "balloting" } can [:create, :destroy], Budget::Ballot::Line, budget: { phase: "balloting" } diff --git a/app/models/concerns/followable.rb b/app/models/concerns/followable.rb index 51469698eb1..6231a24f449 100644 --- a/app/models/concerns/followable.rb +++ b/app/models/concerns/followable.rb @@ -6,4 +6,8 @@ module Followable has_many :followers, through: :follows, source: :user end + def followed_by?(user) + followers.include?(user) + end + end diff --git a/app/models/follow.rb b/app/models/follow.rb index 6c2c62e99d5..2da52127f37 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -6,15 +6,4 @@ class Follow < ActiveRecord::Base validates :followable_id, presence: true validates :followable_type, presence: true - scope(:by_user_and_followable, lambda do |user, followable| - where(user_id: user.id, - followable_type: followable.class.to_s, - followable_id: followable.id) - end) - - def self.followed?(user, followable) - return false unless user - !! by_user_and_followable(user, followable).try(:first) - end - end diff --git a/app/views/budgets/investments/_investment_show.html.erb b/app/views/budgets/investments/_investment_show.html.erb index 950b93b6aee..434934c7e63 100644 --- a/app/views/budgets/investments/_investment_show.html.erb +++ b/app/views/budgets/investments/_investment_show.html.erb @@ -113,7 +113,9 @@ url: budget_investment_url(budget_id: investment.budget_id, id: investment.id) } %> - <%= render 'follows/followable_button', followable: investment if current_user %> + <% if current_user %> + <%= render 'follows/follow_button', follow: find_or_build_follow(current_user, investment) %> + <% end %> diff --git a/app/views/follows/_follow_button.html.erb b/app/views/follows/_follow_button.html.erb new file mode 100644 index 00000000000..547e880b9ae --- /dev/null +++ b/app/views/follows/_follow_button.html.erb @@ -0,0 +1,24 @@ + + + + <% if follow.followable.followed_by?(current_user) %> + + <%= link_to t('shared.unfollow'), + follow_path(follow), + method: :delete, remote: true, + title: unfollow_text(follow.followable), + class: 'button hollow' %> + + <% else %> + + <%= link_to t('shared.follow'), + follows_path(followable_id: follow.followable.id, + followable_type: follow.followable.class.name), + method: :post, remote: true, + title: follow_text(follow.followable), + class: 'button hollow' %> + + <% end %> + + + \ No newline at end of file diff --git a/app/views/follows/_followable_button.html.erb b/app/views/follows/_followable_button.html.erb deleted file mode 100644 index 527a7e02973..00000000000 --- a/app/views/follows/_followable_button.html.erb +++ /dev/null @@ -1,45 +0,0 @@ - - - - <% if show_follow_action? followable %> - - <%= link_to "##{follow_link_wrapper_id(followable)}", - id: follow_link_wrapper_id(followable), - title: follow_entity_text(followable), - data: { toggle: follow_drop_id(followable) }, - class: 'button hollow' do %> - <%= t('shared.follow') %> - <% end %> - - - <% end %> - - <% if show_unfollow_action? followable %> - - <% follow = followable.follows.where(user: current_user).first %> - <%= link_to "##{unfollow_link_wrapper_id(followable)}", - id: unfollow_link_wrapper_id(followable), - title: unfollow_entity_text(followable), - data: { toggle: unfollow_drop_id(followable) }, - class: 'button hollow' do %> - <%= t('shared.unfollow') %> - <% end %> - - - <% end %> - - - \ No newline at end of file diff --git a/app/views/follows/refresh_follow_button.js.erb b/app/views/follows/refresh_follow_button.js.erb index 31e2627a3b9..ad7a7d4f157 100644 --- a/app/views/follows/refresh_follow_button.js.erb +++ b/app/views/follows/refresh_follow_button.js.erb @@ -1,2 +1,3 @@ -App.Followable.update("<%= dom_id(@followable) %>", - "<%= j render('followable_button', followable: @followable) %>") +App.Followable.update("<%= dom_id(@follow.followable) %>", + "<%= j render('follow_button', follow: @follow) %>", + "<%= j render('layouts/flash') %>") diff --git a/app/views/proposals/show.html.erb b/app/views/proposals/show.html.erb index d5c83d9f55d..6a8a567387d 100644 --- a/app/views/proposals/show.html.erb +++ b/app/views/proposals/show.html.erb @@ -140,7 +140,9 @@ url: proposal_url(@proposal) } %> - <%= render 'follows/followable_button', followable: @proposal if current_user %> + <% if current_user %> + <%= render 'follows/follow_button', follow: find_or_build_follow(current_user, @proposal) %> + <% end %> diff --git a/app/views/users/_activity_page.html.erb b/app/views/users/_activity_page.html.erb index df46df76db6..bbea17ae619 100644 --- a/app/views/users/_activity_page.html.erb +++ b/app/views/users/_activity_page.html.erb @@ -1,3 +1,4 @@ +<%= render "following" if @follows.present? %> <%= render "proposals" if @proposals.present? %> <%= render "debates" if @debates.present? && feature?(:debates) %> <%= render "budget_investments" if @budget_investments.present? && feature?(:budgets) %> diff --git a/app/views/users/_budget_investment.html.erb b/app/views/users/_budget_investment.html.erb new file mode 100644 index 00000000000..774fae777e8 --- /dev/null +++ b/app/views/users/_budget_investment.html.erb @@ -0,0 +1,11 @@ + + + <%= link_to budget_investment.title, budget_investment_path(budget_investment.budget, budget_investment) %> + + + <% if can? :destroy, budget_investment %> + <%= link_to t('shared.delete'), budget_investment_path(budget_investment.budget, budget_investment), + method: :delete, class: "button hollow alert" %> + <% end %> + + diff --git a/app/views/users/_budget_investments.html.erb b/app/views/users/_budget_investments.html.erb index 64cad676dbe..fb782f97ca3 100644 --- a/app/views/users/_budget_investments.html.erb +++ b/app/views/users/_budget_investments.html.erb @@ -1,16 +1,6 @@ <% @budget_investments.each do |budget_investment| %> - - - - + <%= render "budget_investment", budget_investment: budget_investment %> <% end %>
- <%= link_to budget_investment.title, budget_investment_path(budget_investment.budget, budget_investment) %> - - <% if can? :destroy, budget_investment %> - <%= link_to t('shared.delete'), budget_investment_path(budget_investment.budget, budget_investment), - method: :delete, class: "button hollow alert" %> - <% end %> -
diff --git a/app/views/users/_following.html.erb b/app/views/users/_following.html.erb new file mode 100644 index 00000000000..a5e78a3b63a --- /dev/null +++ b/app/views/users/_following.html.erb @@ -0,0 +1,30 @@ + diff --git a/app/views/users/_proposal.html.erb b/app/views/users/_proposal.html.erb new file mode 100644 index 00000000000..9144de0993f --- /dev/null +++ b/app/views/users/_proposal.html.erb @@ -0,0 +1,34 @@ + + + <%= link_to proposal.title, proposal, proposal.retired? ? { class: 'retired' } : {} %> +
+ <%= proposal.summary %> + + + <% if proposal.retired? %> + + + <%= t('users.proposals.retired') %> + + + <% elsif author?(proposal) %> + + + <%= link_to t("users.proposals.send_notification"), + new_proposal_notification_path(proposal_id: proposal.id), + class: 'button hollow' %> + + + + <% if proposal.retired? %> + <%= t('users.proposals.retired') %> + <% else %> + <%= link_to t('users.proposals.retire'), + retire_form_proposal_path(proposal), + class: 'button hollow alert' %> + <% end %> + + + <% end %> + + diff --git a/app/views/users/_proposals.html.erb b/app/views/users/_proposals.html.erb index 3112dd5722c..87cc6ee2fa1 100644 --- a/app/views/users/_proposals.html.erb +++ b/app/views/users/_proposals.html.erb @@ -1,30 +1,6 @@ <% @proposals.each do |proposal| %> - - - - <% if author? %> - - - - <% end %> - - + <%= render "proposal", proposal: proposal %> <% end %>
- <%= link_to proposal.title, proposal, proposal.retired? ? {class: 'retired'} : {} %> -
- <%= proposal.summary %> -
- <%= link_to t("users.proposals.send_notification"), new_proposal_notification_path(proposal_id: proposal.id), - class: 'button hollow' %> - - <% if proposal.retired? %> - <%= t('users.proposals.retired') %> - <% else %> - <%= link_to t('users.proposals.retire'), - retire_form_proposal_path(proposal), - class: 'button hollow alert' %> - <% end %> -
diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index fb4a3d1f95e..989e90aacd4 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -46,7 +46,7 @@

<%= t('users.show.private_activity') %>

<% end %> - <% if @user.public_interests || @authorized_current_user %> + <% if valid_interests_access? %>

<%= t('account.show.public_interests_title_list') %>

<% @user.interests.in_groups_of(10, false) do |interests_group| %> diff --git a/config/locales/en/general.yml b/config/locales/en/general.yml index fd5a128b841..dd4bcee3dc3 100644 --- a/config/locales/en/general.yml +++ b/config/locales/en/general.yml @@ -504,7 +504,17 @@ en: flag: Flag as inappropriate follow: "Follow" follow_entity: "Follow %{entity}" - follow_entity_title: "Follow %{entity}: You can participate and receive notifications of any related events." + followable: + budget_investment: + create: + notice_html: "You are now following this investment project!
We will notify you of changes as they occur so that you are up-to-date." + destroy: + notice_html: "You have stopped following this investment project!
You will no longer receive notifications related to this project." + proposal: + create: + notice_html: "Now you are following this citizen proposal!
We will notify you of changes as they occur so that you are up-to-date." + destroy: + notice_html: "You have stopped following this citizen proposal!
You will no longer receive notifications related to this proposal." hide: Hide print: print_button: Print this info diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml index 941a03813aa..76dde0bce29 100644 --- a/config/locales/es/general.yml +++ b/config/locales/es/general.yml @@ -504,7 +504,17 @@ es: flag: Denunciar como inapropiado follow: "Seguir" follow_entity: "Seguir %{entity}" - follow_entity_title: "Seguir %{entity}: Podrás participar y recibir notificaciones de cualquier suceso relacionado." + followable: + budget_investment: + create: + notice_html: "¡Ahora estás siguiendo este proyecto de inversión!
Te notificaremos los cambios a medida que se produzcan para que estés al día." + destroy: + notice_html: "¡Has dejado de seguir este proyecto de inverisión!
Ya no recibirás más notificaciones relacionadas con este proyecto." + proposal: + create: + notice_html: "¡Ahora estás siguiendo esta propuesta ciudadana!
Te notificaremos los cambios a medida que se produzcan para que estés al día." + destroy: + notice_html: "¡Has dejado de seguir esta propuesta ciudadana!
Ya no recibirás más notificaciones relacionadas con esta propuesta." hide: Ocultar print: print_button: Imprimir esta información diff --git a/spec/features/users_spec.rb b/spec/features/users_spec.rb index a6e9e2941a7..3eba5a1f6ec 100644 --- a/spec/features/users_spec.rb +++ b/spec/features/users_spec.rb @@ -357,4 +357,159 @@ end end + feature 'Following (public page)' do + + before do + @user = create(:user) + end + + scenario 'Not display following tab when user is not following any followable' do + visit user_path(@user) + + expect(page).not_to have_content('0 Following') + end + + scenario 'Active following tab by default when follows filters selected', :js do + proposal = create(:proposal, author: @user) + create(:follow, followable: proposal, user: @user) + + visit user_path(@user, filter: "follows") + + expect(page).to have_selector(".activity li.active", text: "1 Following" ) + end + + describe 'Proposals' do + + scenario 'Display following tab when user is following one proposal at least' do + proposal = create(:proposal) + create(:follow, followable: proposal, user: @user) + + visit user_path(@user) + + expect(page).to have_content('1 Following') + end + + scenario 'Display accordion proposal tab when user is following one proposal at least' do + proposal = create(:proposal) + create(:follow, followable: proposal, user: @user) + + visit user_path(@user, filter: "follows") + + expect(page).to have_link('Citizen proposals', href: "#") + end + + scenario 'Not display accordion proposal tab when user is not following any proposal' do + visit user_path(@user, filter: "follows") + + expect(page).not_to have_link('Citizen proposals', href: "#") + end + + scenario 'Display proposal with action buttons inside accordion proposal tab when current user is proposal author', :js do + proposal = create(:proposal, author: @user) + create(:follow, followable: proposal, user: @user) + login_as @user + + visit user_path(@user, filter: "follows") + click_link 'Citizen proposals' + + expect(page).to have_content proposal.title + expect(page).to have_link "Send notification" + expect(page).to have_link "Retire" + end + + scenario 'Display proposal with action buttons inside accordion proposal tab when there is no logged user', :js do + proposal = create(:proposal, author: @user) + create(:follow, followable: proposal, user: @user) + + visit user_path(@user, filter: "follows") + click_link 'Citizen proposals' + + expect(page).to have_content proposal.title + expect(page).not_to have_link "Send notification" + expect(page).not_to have_link "Retire" + end + + scenario 'Display proposal without action buttons inside accordion proposal tab when current user is not proposal author', :js do + proposal = create(:proposal) + create(:follow, followable: proposal, user: @user) + login_as @user + + visit user_path(@user, filter: "follows") + click_link 'Citizen proposals' + + expect(page).to have_content proposal.title + expect(page).not_to have_link "Send notification" + expect(page).not_to have_link "Retire" + end + + end + + describe 'Budget Investments' do + + scenario 'Display following tab when user is following one budget investment at least' do + budget_investment = create(:budget_investment) + create(:follow, followable: budget_investment, user: @user) + + visit user_path(@user) + + expect(page).to have_content('1 Following') + end + + scenario 'Display accordion budget investment tab when user is following one budget investment at least' do + budget_investment = create(:budget_investment) + create(:follow, followable: budget_investment, user: @user) + + visit user_path(@user, filter: "follow") + + expect(page).to have_link('Investments', href: "#") + end + + scenario 'Not display accordion budget investment tab when user is not following any budget investment' do + visit user_path(@user, filter: "follow") + + expect(page).not_to have_link('Investments', href: "#") + end + + scenario 'Display budget investment with action buttons inside accordion budget investment tab when current user is a verified user and author', :js do + user = create(:user, :level_two) + budget_investment = create(:budget_investment, author: user) + create(:follow, followable: budget_investment, user: user) + login_as user + + visit user_path(user, filter: "follows") + click_link 'Investments' + + expect(page).to have_link budget_investment.title + expect(page).to have_link "Delete" + end + + scenario 'Display budget investment with action buttons inside accordion budget investment tab when there is no logged user', :js do + user = create(:user, :level_two) + budget_investment = create(:budget_investment, author: user) + create(:follow, followable: budget_investment, user: user) + + visit user_path(user, filter: "follows") + click_link 'Investments' + + expect(page).to have_link budget_investment.title + expect(page).not_to have_link "Delete" + end + + scenario 'Display budget investment without action buttons inside accordion budget investment tab when current user is not budget investment author', :js do + user = create(:user, :level_two) + budget_investment = create(:budget_investment) + create(:follow, followable: budget_investment, user: user) + login_as user + + visit user_path(user, filter: "follows") + click_link 'Investments' + + expect(page).to have_link budget_investment.title + expect(page).not_to have_link "Delete" + end + + end + + end + end diff --git a/spec/shared/features/followable.rb b/spec/shared/features/followable.rb index 7285ee15fe8..31afc38d388 100644 --- a/spec/shared/features/followable.rb +++ b/spec/shared/features/followable.rb @@ -41,19 +41,31 @@ expect(page).to have_link("Follow") end - scenario "Should display unfollow button when click on follow button", :js do + scenario "Should display unfollow after user clicks on follow button", :js do user = create(:user) login_as(user) visit send(followable_path, arguments) within "##{dom_id(followable)}" do click_link "Follow" - page.find("#follow-#{followable_dom_name}-#{followable.id}").click - expect(page).to have_css("#unfollow-expand-#{followable_dom_name}-#{followable.id}") + expect(page).not_to have_link "Follow" + expect(page).to have_link "Unfollow" end end + scenario "Should display new follower notice after user clicks on follow button", :js do + user = create(:user) + login_as(user) + + visit send(followable_path, arguments) + within "##{dom_id(followable)}" do + click_link "Follow" + end + + expect(page).to have_content strip_tags(t("shared.followable.#{followable_class_name}.create.notice_html")) + end + scenario "Display unfollow button when user already following" do user = create(:user) follow = create(:follow, user: user, followable: followable) @@ -64,7 +76,7 @@ expect(page).to have_link("Unfollow") end - scenario "Should display follow button when click on unfollow button", :js do + scenario "Should update follow button and show destroy notice after user clicks on unfollow button", :js do user = create(:user) follow = create(:follow, user: user, followable: followable) login_as(user) @@ -72,12 +84,25 @@ visit send(followable_path, arguments) within "##{dom_id(followable)}" do click_link "Unfollow" - page.find("#unfollow-#{followable_dom_name}-#{followable.id}").click - expect(page).to have_css("#follow-expand-#{followable_dom_name}-#{followable.id}") + expect(page).not_to have_link "Unfollow" + expect(page).to have_link "Follow" end end + scenario "Should display destroy follower notice after user clicks on unfollow button", :js do + user = create(:user) + follow = create(:follow, user: user, followable: followable) + login_as(user) + + visit send(followable_path, arguments) + within "##{dom_id(followable)}" do + click_link "Unfollow" + end + + expect(page).to have_content strip_tags(t("shared.followable.#{followable_class_name}.destroy.notice_html")) + end + end end