From 028fc2989a6c93247fcf2e5dd5d38d8c3b8b6155 Mon Sep 17 00:00:00 2001 From: Maximilian Pass Date: Tue, 15 Dec 2020 12:17:11 +0100 Subject: [PATCH] #18 Add sql index for unpublished exercises And remove spec for remove feature --- .../stylesheets/request-for-comments.css.scss | 4 ++ .../request_for_comments_controller.rb | 13 ++++++ .../request_for_comments/index.html.slim | 4 ++ config/locales/de.yml | 4 ++ config/locales/en.yml | 4 ++ db/migrate/20201208095929_add_index_to_rfc.rb | 6 +++ ...2844_add_index_to_unpublished_exercises.rb | 5 ++ ...01210113500_add_index_to_exercise_title.rb | 6 +++ db/schema.rb | 6 ++- .../request_for_comments_controller_spec.rb | 46 +++++++++++++++++++ spec/factories/request_for_comment.rb | 11 +++++ spec/factories/study_group.rb | 8 ++++ .../request_for_comments_filter_spec.rb | 32 +++++++++++++ 13 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20201208095929_add_index_to_rfc.rb create mode 100644 db/migrate/20201208132844_add_index_to_unpublished_exercises.rb create mode 100644 db/migrate/20201210113500_add_index_to_exercise_title.rb create mode 100644 spec/controllers/request_for_comments_controller_spec.rb create mode 100644 spec/factories/request_for_comment.rb create mode 100644 spec/factories/study_group.rb create mode 100644 spec/features/request_for_comments_filter_spec.rb diff --git a/app/assets/stylesheets/request-for-comments.css.scss b/app/assets/stylesheets/request-for-comments.css.scss index 34f4a393..2b34915e 100644 --- a/app/assets/stylesheets/request-for-comments.css.scss +++ b/app/assets/stylesheets/request-for-comments.css.scss @@ -271,3 +271,7 @@ input#subscribe { .do-not-answer { background-color: #ea2f1085; } + +#q_submission_study_group_id_in_chosen { + margin-right: 20px; +} diff --git a/app/controllers/request_for_comments_controller.rb b/app/controllers/request_for_comments_controller.rb index 5a0bcb03..5cb3728b 100644 --- a/app/controllers/request_for_comments_controller.rb +++ b/app/controllers/request_for_comments_controller.rb @@ -1,6 +1,7 @@ class RequestForCommentsController < ApplicationController include SubmissionScoring before_action :set_request_for_comment, only: [:show, :edit, :update, :destroy, :mark_as_solved, :set_thank_you_note] + before_action :set_study_group_grouping, only: %i[index get_my_comment_requests get_rfcs_with_my_comments] before_action :require_user! @@ -18,8 +19,12 @@ class RequestForCommentsController < ApplicationController .ransack(params[:q]) @request_for_comments = @search.result .where("question NOT LIKE '%#loesung%'") + .joins(:exercise) + .where(exercises: {unpublished: false}) + .includes(submission: [:study_group]) .order('created_at DESC') .paginate(page: params[:page], total_entries: @search.result.length) + authorize! end @@ -125,4 +130,12 @@ class RequestForCommentsController < ApplicationController params.require(:request_for_comment).permit(:exercise_id, :file_id, :question, :requested_at, :solved, :submission_id).merge(user_id: current_user.id, user_type: current_user.class.name) end + # The index page requires the grouping of the study groups + # The study groups are grouped by the current study group and other study groups of the user + def set_study_group_grouping + current_study_group = StudyGroup.find_by(id: session[:study_group_id]) + my_study_groups = current_user.study_groups.reject { |group| group == current_study_group } + @study_groups_grouping = [[t('request_for_comments.index.study_groups.current'), Array(current_study_group)], + [t('request_for_comments.index.study_groups.my'), my_study_groups]] + end end diff --git a/app/views/request_for_comments/index.html.slim b/app/views/request_for_comments/index.html.slim index 93d3052c..c41b64f1 100644 --- a/app/views/request_for_comments/index.html.slim +++ b/app/views/request_for_comments/index.html.slim @@ -8,6 +8,10 @@ h1 = RequestForComment.model_name.human(count: 2) .form-group = f.label(:title_cont, t('request_for_comments.solved'), class: 'sr-only') = 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]]) + .form-group + = f.label(:submission_study_group_id_eq, t('request_for_comments.index.study_groups.placeholder'), class: 'sr-only') + = f.grouped_collection_select(:submission_study_group_id_in, @study_groups_grouping, :second, :first, :id, :name, {}, + { class: 'form-control', multiple: true, "data-placeholder": t('request_for_comments.index.study_groups.placeholder') }) .table-responsive table.table.sortable.mt-4 diff --git a/config/locales/de.yml b/config/locales/de.yml index f91e5486..07186660 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -722,6 +722,10 @@ de: all: "Alle Kommentaranfragen" get_rfcs_with_my_comments: Kommentaranfragen die ich kommentiert habe get_my_rfc_activity: "Meine Kommentaraktivität" + study_groups: + placeholder: "Lerngruppe" + current: "Aktuelle Lerngruppe" + my: "Meine Lerngruppen" no_question: "Der Autor hat keine Frage zu dieser Anfrage gestellt." mark_as_solved: "Diese Frage als beantwortet markieren" show_all: "Alle Anfragen anzeigen" diff --git a/config/locales/en.yml b/config/locales/en.yml index 8a86a061..f4d5d959 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -724,6 +724,10 @@ en: get_my_comment_requests: My Requests for Comments get_rfcs_with_my_comments: Requests for Comments I have commented on get_my_rfc_activity: "My Comment Activity" + study_groups: + placeholder: "Study group" + current: "Current Study Group" + my: "My Study Groups" no_question: "The author did not enter a question for this request." mark_as_solved: "Mark this question as answered" show_all: "All requests" diff --git a/db/migrate/20201208095929_add_index_to_rfc.rb b/db/migrate/20201208095929_add_index_to_rfc.rb new file mode 100644 index 00000000..50bd4d40 --- /dev/null +++ b/db/migrate/20201208095929_add_index_to_rfc.rb @@ -0,0 +1,6 @@ +class AddIndexToRfc < ActiveRecord::Migration[5.2] + def change + add_index(:request_for_comments, %i[user_id user_type created_at], + order: { user_id: :asc, user_type: :asc, created_at: :desc }, name: :index_rfc_on_user_and_created_at) + end +end diff --git a/db/migrate/20201208132844_add_index_to_unpublished_exercises.rb b/db/migrate/20201208132844_add_index_to_unpublished_exercises.rb new file mode 100644 index 00000000..02d9d06e --- /dev/null +++ b/db/migrate/20201208132844_add_index_to_unpublished_exercises.rb @@ -0,0 +1,5 @@ +class AddIndexToUnpublishedExercises < ActiveRecord::Migration[5.2] + def change + add_index(:exercises, :id, where: 'NOT unpublished', name: :index_unpublished_exercises) + end +end diff --git a/db/migrate/20201210113500_add_index_to_exercise_title.rb b/db/migrate/20201210113500_add_index_to_exercise_title.rb new file mode 100644 index 00000000..899ce712 --- /dev/null +++ b/db/migrate/20201210113500_add_index_to_exercise_title.rb @@ -0,0 +1,6 @@ +class AddIndexToExerciseTitle < ActiveRecord::Migration[5.2] + def change + enable_extension 'pg_trgm' + add_index :exercises, :title, using: :gin, opclass: :gin_trgm_ops + end +end diff --git a/db/schema.rb b/db/schema.rb index bfc9c8a3..9e06ed8e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,9 +10,10 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_10_26_184633) do +ActiveRecord::Schema.define(version: 2020_12_10_113500) do # These are extensions that must be enabled in order to support this database + enable_extension "pg_trgm" enable_extension "plpgsql" create_table "anomaly_notifications", id: :serial, force: :cascade do |t| @@ -168,6 +169,8 @@ ActiveRecord::Schema.define(version: 2020_10_26_184633) do t.datetime "submission_deadline" t.datetime "late_submission_deadline" t.index ["id"], name: "index_exercises_on_id" + t.index ["id"], name: "index_unpublished_exercises", where: "(NOT unpublished)" + t.index ["title"], name: "index_exercises_on_title", opclass: :gin_trgm_ops, using: :gin end create_table "exercises_proxy_exercises", id: false, force: :cascade do |t| @@ -331,6 +334,7 @@ ActiveRecord::Schema.define(version: 2020_10_26_184633) do t.integer "times_featured", default: 0 t.index ["exercise_id"], name: "index_request_for_comments_on_exercise_id" t.index ["submission_id"], name: "index_request_for_comments_on_submission_id" + t.index ["user_id", "user_type", "created_at"], name: "index_rfc_on_user_and_created_at", order: { created_at: :desc } end create_table "searches", id: :serial, force: :cascade do |t| diff --git a/spec/controllers/request_for_comments_controller_spec.rb b/spec/controllers/request_for_comments_controller_spec.rb new file mode 100644 index 00000000..e58222a9 --- /dev/null +++ b/spec/controllers/request_for_comments_controller_spec.rb @@ -0,0 +1,46 @@ +require 'rails_helper' + +describe RequestForCommentsController do + let(:user) { FactoryBot.create(:admin) } + + before { allow(controller).to receive(:current_user).and_return(user) } + + describe 'GET #index' do + it 'renders the index template' do + get :index + + expect(response).to have_http_status :ok + expect(response).to render_template :index + end + + it 'shows only rfc`s belonging to selected study group' do + my_study_group = FactoryBot.create(:study_group) + rfc_within_my_study_group = FactoryBot.create(:rfc, user: user) + user.update(study_groups: [my_study_group]) + rfc_within_my_study_group.submission.update(study_group: my_study_group) + + another_study_group = FactoryBot.create(:study_group) + rfc_other_study_group = FactoryBot.create(:rfc) + rfc_other_study_group.user.update(study_groups: [another_study_group]) + rfc_other_study_group.submission.update(study_group: another_study_group) + + get :index, params: {"q[submission_study_group_id_in][]": my_study_group.id} + + expect(assigns(:request_for_comments)).to eq([rfc_within_my_study_group]) + end + end + + describe 'GET #get_my_comment_requests' do + before { get :get_my_comment_requests } + + expect_status(200) + expect_template(:index) + end + + describe 'GET #get_rfcs_with_my_comments' do + before { get :get_rfcs_with_my_comments } + + expect_status(200) + expect_template(:index) + end +end diff --git a/spec/factories/request_for_comment.rb b/spec/factories/request_for_comment.rb new file mode 100644 index 00000000..30d40330 --- /dev/null +++ b/spec/factories/request_for_comment.rb @@ -0,0 +1,11 @@ +FactoryBot.define do + factory :rfc, class: RequestForComment do + association :user, factory: :external_user + association :submission + association :exercise, factory: :dummy + association :file + sequence :question do |n| + "test question #{n}" + end + end +end diff --git a/spec/factories/study_group.rb b/spec/factories/study_group.rb new file mode 100644 index 00000000..1676eaa0 --- /dev/null +++ b/spec/factories/study_group.rb @@ -0,0 +1,8 @@ +FactoryBot.define do + factory :study_group, class: StudyGroup do + association :consumer + sequence :name do |n| + "TestGroup#{n}" + end + end +end diff --git a/spec/features/request_for_comments_filter_spec.rb b/spec/features/request_for_comments_filter_spec.rb new file mode 100644 index 00000000..e2139797 --- /dev/null +++ b/spec/features/request_for_comments_filter_spec.rb @@ -0,0 +1,32 @@ +require 'rails_helper' + +describe 'Request_for_Comments' do + let(:exercise) { FactoryBot.create(:audio_video, description: Forgery(:lorem_ipsum).sentence) } + let(:user) { FactoryBot.create(:teacher) } + + before do + visit(sign_in_path) + fill_in('email', with: user.email) + fill_in('password', with: FactoryBot.attributes_for(:teacher)[:password]) + click_button(I18n.t('sessions.new.link')) + end + + it 'does not contain rfcs for unpublished exercises' do + unpublished_rfc = FactoryBot.create(:rfc) + unpublished_rfc.exercise.update(title: 'Unpublished Exercise') + unpublished_rfc.exercise.update(unpublished: true) + rfc = FactoryBot.create(:rfc) + rfc.exercise.update(title: 'Normal Exercise') + rfc.exercise.update(unpublished: false) + + visit(request_for_comments_path) + + expect(page).to have_content(rfc.exercise.title) + expect(page).not_to have_content(unpublished_rfc.exercise.title) + end + + it 'contains a filter for study group in the view' do + visit(request_for_comments_path) + expect(page.find('#q_submission_study_group_id_in')).not_to be_nil + end +end