From 7cc4fb00c63135164dfef94e65a6760834da91d6 Mon Sep 17 00:00:00 2001 From: Sebastian Serth Date: Thu, 18 Apr 2024 10:00:19 +0200 Subject: [PATCH] RfCs: Allow filtering for any states We want to differentiate between those RfCs explicitly marked as solved, those potentially solved since the author reached the maximum score, and those being unsolved where the author has not yet reached the full score yet. --- app/models/application_record.rb | 4 +++ app/models/request_for_comment.rb | 22 +++++++++++++--- .../request_for_comments/index.html.slim | 2 +- config/locales/de.yml | 1 + config/locales/en.yml | 5 ++-- spec/models/request_for_comment_spec.rb | 25 +++++++++++++++++-- 6 files changed, 51 insertions(+), 8 deletions(-) diff --git a/app/models/application_record.rb b/app/models/application_record.rb index 2870c0e8..d4a6120e 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -33,4 +33,8 @@ class ApplicationRecord < ActiveRecord::Base def self.ransackable_attributes(_auth_object = nil) [] end + + def self.ransackable_scopes(_auth_object = nil) + [] + end end diff --git a/app/models/request_for_comment.rb b/app/models/request_for_comment.rb index bde83062..8f6d5503 100644 --- a/app/models/request_for_comment.rb +++ b/app/models/request_for_comment.rb @@ -7,7 +7,8 @@ class RequestForComment < ApplicationRecord # SOLVED: The author explicitly marked the RfC as solved. # SOFT_SOLVED: The author did not mark the RfC as solved but reached the maximum score in the corresponding exercise at any time. # ONGOING: The author did not mark the RfC as solved and did not reach the maximum score in the corresponding exercise yet. - STATE = [SOLVED = :solved, SOFT_SOLVED = :soft_solved, ONGOING = :unsolved].freeze + # ALL: Any RfC, regardless of the author marking it as solved or reaching the maximum score in the corresponding exercise. + STATE = [SOLVED = :solved, SOFT_SOLVED = :soft_solved, ONGOING = :unsolved, ALL = :all].freeze belongs_to :submission belongs_to :exercise @@ -59,6 +60,21 @@ class RequestForComment < ApplicationRecord end class << self + def state(filter = RequestForComment::ALL) + # This method is used as a scope filter for Ransack + + case filter.to_sym + when RequestForComment::SOLVED + where(solved: true) + when RequestForComment::SOFT_SOLVED + unsolved.where(full_score_reached: true) + when RequestForComment::ONGOING + unsolved.where(full_score_reached: false) + else # 'all' + all + end + end + def with_last_activity joins('join "submissions" s on s.id = request_for_comments.submission_id ' \ 'left outer join "files" f on f.context_id = s.id ' \ @@ -81,8 +97,8 @@ class RequestForComment < ApplicationRecord %w[exercise submission] end - def ransackable_attributes(_auth_object = nil) - %w[solved] + def ransackable_scopes(_auth_object = nil) + %w[state] end private diff --git a/app/views/request_for_comments/index.html.slim b/app/views/request_for_comments/index.html.slim index 38b92aff..3dbc56df 100644 --- a/app/views/request_for_comments/index.html.slim +++ b/app/views/request_for_comments/index.html.slim @@ -9,7 +9,7 @@ h1 = RequestForComment.model_name.human(count: 2) = f.search_field(:exercise_title_cont, class: 'form-control', placeholder: t('activerecord.attributes.request_for_comments.exercise')) .col-auto.mt-3.mt-md-0 = f.label(:title_cont, t('request_for_comments.solved'), class: 'visually-hidden form-label') - = f.select(:solved_not_eq, [[t('request_for_comments.show_all'), 2], [t('request_for_comments.show_unsolved'), 1], [t('request_for_comments.show_solved'), 0]]) + = f.select(:state, [[t('request_for_comments.show_all'), RequestForComment::ALL], [t('request_for_comments.show_unsolved'), RequestForComment::ONGOING], [t('request_for_comments.show_soft_solved'), RequestForComment::SOFT_SOLVED], [t('request_for_comments.show_solved'), RequestForComment::SOLVED]]) - unless current_user.consumer.rfc_visibility_study_group? .row .col diff --git a/config/locales/de.yml b/config/locales/de.yml index 6f938c4a..6e9e41b4 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -857,6 +857,7 @@ de: mark_as_solved: "Diese Frage als beantwortet markieren" show_all: "Alle Anfragen anzeigen" show_solved: "Nur gelöste Anfragen anzeigen" + show_soft_solved: "Nur potenziell gelöste Anfragen anzeigen" show_unsolved: "Nur ungelöste Anfragen anzeigen" solved: "Diese Frage wurde erfolgreich beantwortet" comment_exercise: "Ich möchte die Aufgabenstellung kommentieren" diff --git a/config/locales/en.yml b/config/locales/en.yml index 13ff5235..07a045f8 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -856,8 +856,9 @@ en: no_question: "The author did not enter a question for this request." mark_as_solved: "Mark this question as answered" show_all: "All requests" - show_solved: "Solved requests" - show_unsolved: "Unvsolved requests" + show_solved: "Show only solved requests" + show_soft_solved: "Show only requests presumably solved" + show_unsolved: "Show only unsolved requests" solved: "This question has been answered" comment_exercise: "I would like to give feedback for this exercise" write_a_thank_you_node: "If you want, you can write a thank you note to all your commenters:" diff --git a/spec/models/request_for_comment_spec.rb b/spec/models/request_for_comment_spec.rb index 720cc5d3..d61c33cd 100644 --- a/spec/models/request_for_comment_spec.rb +++ b/spec/models/request_for_comment_spec.rb @@ -3,9 +3,8 @@ require 'rails_helper' RSpec.describe RequestForComment do - let!(:rfc) { create(:rfc) } - describe 'scope with_comments' do + let!(:rfc) { create(:rfc) } let!(:rfc2) { create(:rfc_with_comment) } it 'includes all RfCs with comments' do @@ -16,4 +15,26 @@ RSpec.describe RequestForComment do expect(described_class.with_comments).not_to include(rfc) end end + + describe 'state' do + let!(:rfc_solved) { create(:rfc, solved: true) } + let!(:rfc_soft_solved) { create(:rfc, solved: false, full_score_reached: true) } + let!(:rfc_ongoing) { create(:rfc, solved: false, full_score_reached: false) } + + it 'returns solved RfCs when solved state is requested' do + expect(described_class.state(RequestForComment::SOLVED)).to contain_exactly(rfc_solved) + end + + it 'returns soft solved RfCs when soft solved state is requested' do + expect(described_class.state(RequestForComment::SOFT_SOLVED)).to contain_exactly(rfc_soft_solved) + end + + it 'returns ongoing RfCs when ongoing state is requested' do + expect(described_class.state(RequestForComment::ONGOING)).to contain_exactly(rfc_ongoing) + end + + it 'returns all RfCs when all state is requested' do + expect(described_class.state(RequestForComment::ALL)).to contain_exactly(rfc_solved, rfc_soft_solved, rfc_ongoing) + end + end end