Refactor external_user_statistics to own controller action
This commit is contained in:

committed by
Sebastian Serth

parent
6ca5982a45
commit
2141fdb1ac
@ -11,8 +11,9 @@ class ExercisesController < ApplicationController
|
|||||||
before_action :set_execution_environments, only: %i[index create edit new update]
|
before_action :set_execution_environments, only: %i[index create edit new update]
|
||||||
before_action :set_exercise_and_authorize,
|
before_action :set_exercise_and_authorize,
|
||||||
only: MEMBER_ACTIONS + %i[clone implement working_times intervention search run statistics submit reload feedback
|
only: MEMBER_ACTIONS + %i[clone implement working_times intervention search run statistics submit reload feedback
|
||||||
requests_for_comments study_group_dashboard export_external_check export_external_confirm]
|
requests_for_comments study_group_dashboard export_external_check export_external_confirm
|
||||||
before_action :set_external_user_and_authorize, only: [:statistics]
|
external_user_statistics]
|
||||||
|
before_action :set_external_user_and_authorize, only: [:external_user_statistics]
|
||||||
before_action :set_file_types, only: %i[create edit new update]
|
before_action :set_file_types, only: %i[create edit new update]
|
||||||
before_action :set_course_token, only: [:implement]
|
before_action :set_course_token, only: [:implement]
|
||||||
before_action :set_available_tips, only: %i[implement show new edit]
|
before_action :set_available_tips, only: %i[implement show new edit]
|
||||||
@ -466,57 +467,58 @@ working_time_accumulated: working_time_accumulated})
|
|||||||
end
|
end
|
||||||
|
|
||||||
def statistics
|
def statistics
|
||||||
if @external_user
|
# Show general statistic page for specific exercise
|
||||||
# Render statistics page for one specific external user
|
user_statistics = {'InternalUser' => {}, 'ExternalUser' => {}}
|
||||||
authorize(@external_user, :statistics?)
|
additional_filter = if policy(@exercise).detailed_statistics?
|
||||||
if policy(@exercise).detailed_statistics?
|
''
|
||||||
@submissions = Submission.where(user: @external_user,
|
elsif !policy(@exercise).detailed_statistics? && current_user.study_groups.count.positive?
|
||||||
exercise_id: @exercise.id).in_study_group_of(current_user).order('created_at')
|
"AND study_group_id IN (#{current_user.study_groups.pluck(:id).join(', ')}) AND cause = 'submit'"
|
||||||
@show_autosaves = params[:show_autosaves] == 'true'
|
else
|
||||||
@submissions = @submissions.where.not(cause: 'autosave') unless @show_autosaves
|
# e.g. internal user without any study groups, show no submissions
|
||||||
interventions = UserExerciseIntervention.where('user_id = ? AND exercise_id = ?', @external_user.id,
|
'AND FALSE'
|
||||||
@exercise.id)
|
end
|
||||||
@all_events = (@submissions + interventions).sort_by(&:created_at)
|
query = "SELECT user_id, user_type, MAX(score) AS maximum_score, COUNT(id) AS runs
|
||||||
@deltas = @all_events.map.with_index do |item, index|
|
FROM submissions WHERE exercise_id = #{@exercise.id} #{additional_filter}
|
||||||
delta = item.created_at - @all_events[index - 1].created_at if index.positive?
|
GROUP BY user_id, user_type;"
|
||||||
delta.nil? || (delta > StatisticsHelper::WORKING_TIME_DELTA_IN_SECONDS) ? 0 : delta
|
ApplicationRecord.connection.execute(query).each do |tuple|
|
||||||
end
|
user_statistics[tuple['user_type']][tuple['user_id'].to_i] = tuple
|
||||||
@working_times_until = []
|
|
||||||
@all_events.each_with_index do |_, index|
|
|
||||||
@working_times_until.push((format_time_difference(@deltas[0..index].sum) if index.positive?))
|
|
||||||
end
|
|
||||||
else
|
|
||||||
final_submissions = Submission.where(user: @external_user,
|
|
||||||
exercise_id: @exercise.id).in_study_group_of(current_user).final
|
|
||||||
@submissions = []
|
|
||||||
%i[before_deadline within_grace_period after_late_deadline].each do |filter|
|
|
||||||
relevant_submission = final_submissions.send(filter).latest
|
|
||||||
@submissions.push relevant_submission if relevant_submission.present?
|
|
||||||
end
|
|
||||||
@all_events = @submissions
|
|
||||||
end
|
|
||||||
render 'exercises/external_users/statistics'
|
|
||||||
else
|
|
||||||
# Show general statistic page for specific exercise
|
|
||||||
user_statistics = {'InternalUser' => {}, 'ExternalUser' => {}}
|
|
||||||
additional_filter = if policy(@exercise).detailed_statistics?
|
|
||||||
''
|
|
||||||
elsif !policy(@exercise).detailed_statistics? && current_user.study_groups.count.positive?
|
|
||||||
"AND study_group_id IN (#{current_user.study_groups.pluck(:id).join(', ')}) AND cause = 'submit'"
|
|
||||||
else
|
|
||||||
# e.g. internal user without any study groups, show no submissions
|
|
||||||
'AND FALSE'
|
|
||||||
end
|
|
||||||
query = "SELECT user_id, user_type, MAX(score) AS maximum_score, COUNT(id) AS runs
|
|
||||||
FROM submissions WHERE exercise_id = #{@exercise.id} #{additional_filter}
|
|
||||||
GROUP BY user_id, user_type;"
|
|
||||||
ApplicationRecord.connection.execute(query).each do |tuple|
|
|
||||||
user_statistics[tuple['user_type']][tuple['user_id'].to_i] = tuple
|
|
||||||
end
|
|
||||||
render locals: {
|
|
||||||
user_statistics: user_statistics,
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
render locals: {
|
||||||
|
user_statistics: user_statistics,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def external_user_statistics
|
||||||
|
# Render statistics page for one specific external user
|
||||||
|
|
||||||
|
if policy(@exercise).detailed_statistics?
|
||||||
|
@submissions = Submission.where(user: @external_user,
|
||||||
|
exercise_id: @exercise.id).in_study_group_of(current_user).order('created_at')
|
||||||
|
@show_autosaves = params[:show_autosaves] == 'true'
|
||||||
|
@submissions = @submissions.where.not(cause: 'autosave') unless @show_autosaves
|
||||||
|
interventions = UserExerciseIntervention.where('user_id = ? AND exercise_id = ?', @external_user.id,
|
||||||
|
@exercise.id)
|
||||||
|
@all_events = (@submissions + interventions).sort_by(&:created_at)
|
||||||
|
@deltas = @all_events.map.with_index do |item, index|
|
||||||
|
delta = item.created_at - @all_events[index - 1].created_at if index.positive?
|
||||||
|
delta.nil? || (delta > StatisticsHelper::WORKING_TIME_DELTA_IN_SECONDS) ? 0 : delta
|
||||||
|
end
|
||||||
|
@working_times_until = []
|
||||||
|
@all_events.each_with_index do |_, index|
|
||||||
|
@working_times_until.push((format_time_difference(@deltas[0..index].sum) if index.positive?))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
final_submissions = Submission.where(user: @external_user,
|
||||||
|
exercise_id: @exercise.id).in_study_group_of(current_user).final
|
||||||
|
@submissions = []
|
||||||
|
%i[before_deadline within_grace_period after_late_deadline].each do |filter|
|
||||||
|
relevant_submission = final_submissions.send(filter).latest
|
||||||
|
@submissions.push relevant_submission if relevant_submission.present?
|
||||||
|
end
|
||||||
|
@all_events = @submissions
|
||||||
|
end
|
||||||
|
|
||||||
|
render 'exercises/external_users/statistics'
|
||||||
end
|
end
|
||||||
|
|
||||||
def submit
|
def submit
|
||||||
|
@ -5,7 +5,7 @@ class ExercisePolicy < AdminOrAuthorPolicy
|
|||||||
admin?
|
admin?
|
||||||
end
|
end
|
||||||
|
|
||||||
%i[show? feedback? statistics? rfcs_for_exercise?].each do |action|
|
%i[show? feedback? statistics? external_user_statistics? rfcs_for_exercise?].each do |action|
|
||||||
define_method(action) { admin? || teacher_in_study_group? || (teacher? && @record.public?) || author? }
|
define_method(action) { admin? || teacher_in_study_group? || (teacher? && @record.public?) || author? }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -477,6 +477,7 @@ de:
|
|||||||
feedback: Feedback
|
feedback: Feedback
|
||||||
requests_for_comments: Kommentaranfragen
|
requests_for_comments: Kommentaranfragen
|
||||||
study_group_dashboard: Live Dashboard
|
study_group_dashboard: Live Dashboard
|
||||||
|
external_user_statistics: Statistik für externe Nutzer
|
||||||
show:
|
show:
|
||||||
is_unpublished: Aufgabe ist deaktiviert
|
is_unpublished: Aufgabe ist deaktiviert
|
||||||
statistics:
|
statistics:
|
||||||
|
@ -477,6 +477,7 @@ en:
|
|||||||
feedback: Feedback
|
feedback: Feedback
|
||||||
requests_for_comments: Requests for Comments
|
requests_for_comments: Requests for Comments
|
||||||
study_group_dashboard: Live Dashboard
|
study_group_dashboard: Live Dashboard
|
||||||
|
external_user_statistics: External User Statistics
|
||||||
show:
|
show:
|
||||||
is_unpublished: Exercise is unpublished
|
is_unpublished: Exercise is unpublished
|
||||||
statistics:
|
statistics:
|
||||||
|
@ -117,7 +117,9 @@ Rails.application.routes.draw do
|
|||||||
resources :user_exercise_feedbacks, except: %i[show index]
|
resources :user_exercise_feedbacks, except: %i[show index]
|
||||||
|
|
||||||
resources :external_users, only: %i[index show], concerns: :statistics do
|
resources :external_users, only: %i[index show], concerns: :statistics do
|
||||||
resources :exercises, concerns: :statistics
|
resources :exercises do
|
||||||
|
get :statistics, to: 'exercises#external_user_statistics', on: :member
|
||||||
|
end
|
||||||
member do
|
member do
|
||||||
get :tag_statistics
|
get :tag_statistics
|
||||||
end
|
end
|
||||||
|
@ -236,8 +236,8 @@ describe ExercisesController do
|
|||||||
expect_template(:statistics)
|
expect_template(:statistics)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET #statistics for external users' do
|
describe 'GET #external_user_statistics' do
|
||||||
let(:perform_request) { get :statistics, params: params }
|
let(:perform_request) { get :external_user_statistics, params: params }
|
||||||
let(:params) { {id: exercise.id, external_user_id: external_user.id} }
|
let(:params) { {id: exercise.id, external_user_id: external_user.id} }
|
||||||
let(:external_user) { create(:external_user) }
|
let(:external_user) { create(:external_user) }
|
||||||
|
|
||||||
@ -250,7 +250,7 @@ describe ExercisesController do
|
|||||||
context 'when viewing the default submission statistics page without a parameter' do
|
context 'when viewing the default submission statistics page without a parameter' do
|
||||||
it 'does not list autosaved submissions' do
|
it 'does not list autosaved submissions' do
|
||||||
perform_request
|
perform_request
|
||||||
expect(assigns(:submissions)).to match_array [
|
expect(assigns(:all_events).filter {|event| event.is_a? Submission }).to match_array [
|
||||||
an_object_having_attributes(cause: 'run', user_id: external_user.id),
|
an_object_having_attributes(cause: 'run', user_id: external_user.id),
|
||||||
an_object_having_attributes(cause: 'assess', user_id: external_user.id),
|
an_object_having_attributes(cause: 'assess', user_id: external_user.id),
|
||||||
an_object_having_attributes(cause: 'run', user_id: external_user.id),
|
an_object_having_attributes(cause: 'run', user_id: external_user.id),
|
||||||
@ -263,7 +263,7 @@ describe ExercisesController do
|
|||||||
|
|
||||||
it 'lists all submissions, including autosaved submissions' do
|
it 'lists all submissions, including autosaved submissions' do
|
||||||
perform_request
|
perform_request
|
||||||
submissions = assigns(:submissions)
|
submissions = assigns(:all_events).filter {|event| event.is_a? Submission }
|
||||||
expect(submissions).to match_array Submission.all
|
expect(submissions).to match_array Submission.all
|
||||||
expect(submissions).to include an_object_having_attributes(cause: 'autosave', user_id: external_user.id)
|
expect(submissions).to include an_object_having_attributes(cause: 'autosave', user_id: external_user.id)
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user