From 4df59d85e290f11db0ae1790282797b9717f3959 Mon Sep 17 00:00:00 2001 From: Andrew Kvalheim Date: Wed, 1 Mar 2023 11:17:39 -0800 Subject: [PATCH 1/4] Add test of voting --- spec/factories/users.rb | 10 ++++++ spec/features/voting_spec.rb | 59 ++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 spec/features/voting_spec.rb diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 24affba4..b21dd88b 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -50,6 +50,16 @@ FactoryBot.define do end end + factory :cfp_user do + transient do + resource { create(:resource) } + end + + after :create do |user, evaluator| + user.add_role :cfp, evaluator.resource + end + end + trait :disabled do is_disabled { true } end diff --git a/spec/features/voting_spec.rb b/spec/features/voting_spec.rb new file mode 100644 index 00000000..1758de0b --- /dev/null +++ b/spec/features/voting_spec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require 'spec_helper' + +def have_rating(rating, max) + have_selector('.rating.bright', count: rating) + .and have_selector('.rating:not(.bright)', count: max - rating) +end + +def cast_vote(rating, before:, after:) + # Index shows existing rating but not user’s vote + visit admin_conference_program_events_path(conference.short_title) + within("#event-#{event.id}") do + expect(page).to have_rating(before, 5) + expect(page).to have_text('Not rated') + end + + # Event page shows existing rating but not user’s vote + click_on event.title + within('tr', text: 'Rating') { expect(page).to have_rating(before, 5) } + within('tr', text: 'Your vote') { expect(page).to have_rating(0, 5) } + + # Voting dynamically updates the page + within('tr', text: 'Your vote') { page.find(".rating:nth-of-type(#{rating})").click } + within('tr', text: 'Rating') { expect(page).to have_rating(after, 5) } + within('tr', text: 'Your vote') { expect(page).to have_rating(rating, 5) } + + # Index shows updated rating and vote + visit admin_conference_program_events_path(conference.short_title) + within("#event-#{event.id}") do + expect(page).to have_rating(after, 5) + expect(page).to have_text("You voted: #{rating}/5") + end + + # Re-rendered event page shows updated rating and vote + click_on event.title + within('tr', text: 'Rating') { expect(page).to have_rating(after, 5) } + within('tr', text: 'Your vote') { expect(page).to have_rating(rating, 5) } +end + +feature 'Voting' do + let(:conference) { create(:conference) } + let!(:event) { create(:event, program: conference.program) } + let(:voter1) { create(:cfp_user, resource: conference) } + let(:voter2) { create(:cfp_user, resource: conference) } + + before :each do + conference.program.update_attribute :rating, 5 + end + + scenario 'multiple users casting votes', feature: true, js: true do + sign_in voter1 + cast_vote 3, before: 0, after: 3 + sign_out + + sign_in voter2 + cast_vote 5, before: 3, after: 4 + end +end From 17366c6eab17c5b408f4de60a748b8f7b96eea6b Mon Sep 17 00:00:00 2001 From: Andrew Kvalheim Date: Wed, 1 Mar 2023 11:33:21 -0800 Subject: [PATCH 2/4] Update events when rated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When fragment caching is enabled— --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -27 +26,0 @@ - config.action_controller.perform_caching = false @@ -29 +27,0 @@ - config.cache_store = :null_store —the test of voting fails with: expected to find css ".rating.bright" … 3 times but there were no matches expected to find visible css ".rating:not(.bright)" … 2 times, found 5 matches # ./spec/features/voting_spec.rb:31 # ./spec/features/voting_spec.rb:30 # ./spec/features/voting_spec.rb:53 i.e. the rating displayed on the event index is not updated after voting, because while the fragment’s cache dependencies include the event, voting doesn’t update the event. re #2767 --- app/models/vote.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/vote.rb b/app/models/vote.rb index 64ab74de..cdd1e4cb 100644 --- a/app/models/vote.rb +++ b/app/models/vote.rb @@ -2,7 +2,7 @@ class Vote < ApplicationRecord belongs_to :user - belongs_to :event + belongs_to :event, touch: true validates :user_id, uniqueness: { scope: :event_id } From 1563881153250125c30fde672a845c2ba3238a18 Mon Sep 17 00:00:00 2001 From: Andrew Kvalheim Date: Wed, 1 Mar 2023 11:43:50 -0800 Subject: [PATCH 3/4] Add user to cache dependencies of vote in events index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When fragment caching is enabled— --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -27 +26,0 @@ - config.action_controller.perform_caching = false @@ -29 +27,0 @@ - config.cache_store = :null_store —the test of voting fails with: expected to find text "Not rated" in "…You voted: 3/5…" # ./spec/features/voting_spec.rb:15 # ./spec/features/voting_spec.rb:13 # ./spec/features/voting_spec.rb:57 i.e. the vote displayed on the event index is another user’s vote, because the fragment’s cache dependencies don’t include the current user. re #2767 --- app/views/admin/events/_datatable_row.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/events/_datatable_row.haml b/app/views/admin/events/_datatable_row.haml index 7de3f3f1..17f7b264 100644 --- a/app/views/admin/events/_datatable_row.haml +++ b/app/views/admin/events/_datatable_row.haml @@ -1,4 +1,4 @@ -- cache ['admin', conference_id, program, event] do +- cache ['admin', conference_id, program, event, current_user] do %tr{ id: "event-#{event.id}" } %td = event.id From 04f6a73d7361443dddde38a40653332c34291633 Mon Sep 17 00:00:00 2001 From: Andrew Kvalheim Date: Wed, 1 Mar 2023 11:52:16 -0800 Subject: [PATCH 4/4] Add user to cache dependencies of event proposal tab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When fragment caching is enabled— --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -27 +26,0 @@ - config.action_controller.perform_caching = false @@ -29 +27,0 @@ - config.cache_store = :null_store —the test of voting fails with: expected to find visible css ".rating.bright" … 0 times, found 3 matches expected to find visible css ".rating:not(.bright)" … 5 times, found 2 matches # ./spec/features/voting_spec.rb:21 # ./spec/features/voting_spec.rb:21 # ./spec/features/voting_spec.rb:57 i.e. the vote displayed in the event proposal tab is another user’s vote, because the fragment’s cache dependencies don’t include the current user. resolves #2767 --- app/views/admin/events/_proposal.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/events/_proposal.html.haml b/app/views/admin/events/_proposal.html.haml index 12f0efb6..17ed991d 100644 --- a/app/views/admin/events/_proposal.html.haml +++ b/app/views/admin/events/_proposal.html.haml @@ -1,4 +1,4 @@ -- cache ['admin/event', @conference, @program, @event] do +- cache ['admin/event', @conference, @program, @event, current_user] do .row .col-md-12 %h3