Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
# frozen_string_literal: true

class Course::Assessment::Submission::Answer::AnswersController < \
class Course::Assessment::Submission::Answer::AnswersController <
Course::Assessment::Submission::Answer::Controller
include Course::Assessment::SubmissionConcern
include Course::Assessment::Answer::UpdateAnswerConcern

before_action :authorize_submission!
before_action :check_password, only: [:update]

def show
authorize! :read, @answer
respond_to do |format|
format.json { render 'show' }

Check warning on line 14 in app/controllers/course/assessment/submission/answer/answers_controller.rb

View check run for this annotation

Codecov / codecov/patch

app/controllers/course/assessment/submission/answer/answers_controller.rb#L12-L14

Added lines #L12 - L14 were not covered by tests
end
end

def update
authorize! :update, @answer

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
# frozen_string_literal: true
class Course::Assessment::SubmissionQuestion::SubmissionQuestionsController < \
Course::Assessment::SubmissionQuestion::Controller
def past_answers
answers_to_load = past_answers_params[:answers_to_load]&.to_i || 10
answers = @submission_question.past_answers(answers_to_load)
class Course::Assessment::SubmissionQuestion::SubmissionQuestionsController < Course::Controller
load_resource :assessment, class: 'Course::Assessment', through: :course, parent: false

respond_to do |format|
format.json { render 'past_answers', locals: { answers: answers } }
end
def all_answers
@submission = @assessment.submissions.find(all_answers_params[:submission_id])
authorize!(:read, @submission)
@submission_question = @submission.

Check warning on line 8 in app/controllers/course/assessment/submission_question/submission_questions_controller.rb

View check run for this annotation

Codecov / codecov/patch

app/controllers/course/assessment/submission_question/submission_questions_controller.rb#L6-L8

Added lines #L6 - L8 were not covered by tests
submission_questions.
where(
question_id: all_answers_params[:question_id]
).
includes(actable: { files: { annotations:
{ discussion_topic: { posts: :codaveri_feedback } } } },
discussion_topic: { posts: :codaveri_feedback }).first
@all_answers = @submission.answers.

Check warning on line 16 in app/controllers/course/assessment/submission_question/submission_questions_controller.rb

View check run for this annotation

Codecov / codecov/patch

app/controllers/course/assessment/submission_question/submission_questions_controller.rb#L16

Added line #L16 was not covered by tests
without_attempting_state.
unscope(:order).
order(:created_at).
where(
question_id: all_answers_params[:question_id]
)
end

private

def past_answers_params
params.permit(:answers_to_load)
def all_answers_params
params.permit(:submission_id, :question_id)

Check warning on line 28 in app/controllers/course/assessment/submission_question/submission_questions_controller.rb

View check run for this annotation

Codecov / codecov/patch

app/controllers/course/assessment/submission_question/submission_questions_controller.rb#L28

Added line #L28 was not covered by tests
end
end
35 changes: 0 additions & 35 deletions app/controllers/course/statistics/answers_controller.rb

This file was deleted.

6 changes: 5 additions & 1 deletion app/models/course/assessment/assessment_ability.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# frozen_string_literal: true
module Course::Assessment::AssessmentAbility
include Course::Assessment::SubmissionQuestionAbility
include Course::Assessment::Answer::ProgrammingAbility

def define_permissions
Expand Down Expand Up @@ -125,6 +124,7 @@
allow_staff_read_observe_access_and_attempt_assessment
allow_staff_read_assessment_submissions
allow_staff_read_assessment_tests
allow_staff_read_submission_answers

Check warning on line 127 in app/models/course/assessment/assessment_ability.rb

View check run for this annotation

Codecov / codecov/patch

app/models/course/assessment/assessment_ability.rb#L127

Added line #L127 was not covered by tests
allow_staff_read_submission_questions
allow_staff_delete_own_assessment_submission
end
Expand All @@ -149,6 +149,10 @@
can :read, Course::Assessment::SubmissionQuestion, discussion_topic: { course_id: course.id }
end

def allow_staff_read_submission_answers
can :read, Course::Assessment::Answer, submission: { assessment: assessment_course_hash }

Check warning on line 153 in app/models/course/assessment/assessment_ability.rb

View check run for this annotation

Codecov / codecov/patch

app/models/course/assessment/assessment_ability.rb#L153

Added line #L153 was not covered by tests
end

def allow_staff_delete_own_assessment_submission
can :delete_submission, Course::Assessment::Submission, creator_id: user.id
end
Expand Down
4 changes: 4 additions & 0 deletions app/models/course/assessment/question/forum_post_response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,8 @@
def files_downloadable?
true
end

def history_viewable?
true

Check warning on line 51 in app/models/course/assessment/question/forum_post_response.rb

View check run for this annotation

Codecov / codecov/patch

app/models/course/assessment/question/forum_post_response.rb#L51

Added line #L51 was not covered by tests
end
end
26 changes: 16 additions & 10 deletions app/models/course/assessment/submission.rb
Original file line number Diff line number Diff line change
Expand Up @@ -266,18 +266,24 @@
current_answers.select { |ans| ans.actable_type == Course::Assessment::Answer::Programming.name }
end

# Loads the answer ids of the past answers of each question
# Loads basic information about the past answers of each question
def answer_history
answers.unscope(:order).
order(created_at: :desc).
pluck(:question_id, :id, :current_answer).
group_by(&:first).
answers.

Check warning on line 271 in app/models/course/assessment/submission.rb

View check run for this annotation

Codecov / codecov/patch

app/models/course/assessment/submission.rb#L271

Added line #L271 was not covered by tests
without_attempting_state.
group_by(&:question_id).
map do |pair|
{
question_id: pair[0],
answer_ids: pair[1].reject(&:last).map(&:second).first(10)
}
end
{
question_id: pair[0],

Check warning on line 276 in app/models/course/assessment/submission.rb

View check run for this annotation

Codecov / codecov/patch

app/models/course/assessment/submission.rb#L276

Added line #L276 was not covered by tests
answers: pair[1].map do |answer|
{
id: answer.id,

Check warning on line 279 in app/models/course/assessment/submission.rb

View check run for this annotation

Codecov / codecov/patch

app/models/course/assessment/submission.rb#L279

Added line #L279 was not covered by tests
createdAt: answer.created_at&.iso8601,
currentAnswer: answer.current_answer,
workflowState: answer.workflow_state
}
end
}
end
end

# Returns all graded answers of the question in current submission.
Expand Down
15 changes: 0 additions & 15 deletions app/models/course/assessment/submission_question.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,6 @@ def notify(post)
Course::Assessment::SubmissionQuestion::CommentNotifier.post_replied(post)
end

def answers
Course::Assessment::Answer.where('submission_id = ? AND question_id = ?',
submission_id, question_id)
end

# Loads the past answers of a specific question
def past_answers(answers_to_load)
answers.
unscope(:order).
order(created_at: :desc).
where('workflow_state != ? '\
'OR (workflow_state = ? AND current_answer IS false)', 'attempting', 'attempting').
first(answers_to_load)
end

private

# Set the course as the same course of the assessment.
Expand Down
19 changes: 0 additions & 19 deletions app/models/course/assessment/submission_question_ability.rb

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# frozen_string_literal: true
specific_answer = @answer.specific
question = @answer.question
can_grade = can?(:grade, @answer.submission)

json.id @answer.id
json.grade @answer.grade
json.createdAt @answer.created_at&.iso8601

# this section is here because the answer can affect how the question is displayed
# e.g. option randomization for mcq/mrq questions
json.question do
json.id question.id
json.title question.title
json.questionTitle question.title
json.maximumGrade question.maximum_grade
json.description format_ckeditor_rich_text(question.description)
json.type question.question_type
Expand All @@ -19,6 +19,12 @@ json.question do
end
json.partial! specific_answer, answer: specific_answer, can_grade: false

if can_grade || @answer.submission.published?
json.grading do
json.grade @answer&.grade
end
end

if @answer.actable_type == Course::Assessment::Answer::Programming.name
files = @answer.specific.files
json.partial! 'course/assessment/answer/programming/annotations', programming_files: files,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# frozen_string_literal: true
json.history do
answer_history = submission.answer_history
history_viewable_map = @submission.questions.to_h { |question| [question.id, question.history_viewable?] }

json.questions answer_history.map do |group|
json.id group[:question_id]
json.answerIds group[:answer_ids]
json.answers group[:answers]
json.canViewHistory history_viewable_map[group[:question_id]]
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ json.questions question_assessments.each_with_index.to_a do |(question_assessmen
answer_id = answer&.id
submission_question = sq_topic_ids_hash[question.id][0]
json.partial! 'question', question: question, can_grade: can_grade, answer: answer
json.questionNumber question_assessment.default_title(index + 1)
json.questionNumber index + 1
json.questionTitle question.title

json.answerId answer_id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ json.allAnswers @all_answers do |answer|
json.workflowState answer.workflow_state
end

json.canViewHistory @submission_question.question.history_viewable?

posts = @submission_question.discussion_topic.posts

json.comments posts do |post|
Expand Down

This file was deleted.

24 changes: 24 additions & 0 deletions client/app/api/course/Assessment/AllAnswers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { SubmissionQuestionDetails } from 'types/course/assessment/submission/submission-question';

import { APIResponse } from 'api/types';
import BaseAssessmentAPI from './Base';
import { AnswerDataWithQuestion } from 'course/assessment/submission/types';
import { QuestionType } from 'types/course/assessment/question';

export default class AllAnswersAPI extends BaseAssessmentAPI {
fetchSubmissionQuestionDetails(
submissionId: number,
questionId: number,
): APIResponse<SubmissionQuestionDetails> {
return this.client.get(
`/courses/${this.courseId}/assessments/${this.assessmentId}/submissions/${submissionId}/questions/${questionId}/all_answers`,
);
}

fetch(
submissionId: number,
answerId: number,
): APIResponse<AnswerDataWithQuestion<keyof typeof QuestionType>> {
return this.client.get(`/courses/${this.courseId}/assessments/${this.assessmentId}/submissions/${submissionId}/answers/${answerId}`);
}
}
8 changes: 8 additions & 0 deletions client/app/api/course/Assessment/Submission/Answer/Answer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,20 @@ import { APIResponse } from 'api/types';

import BaseAPI from '../../Base';
import SubmissionsAPI from '../../Submissions';
import { QuestionType } from 'types/course/assessment/question';
import { AnswerDataWithQuestion } from 'course/assessment/submission/types';

export default class AnswersAPI extends BaseAPI {
get #urlPrefix(): string {
return `/courses/${this.courseId}/assessments/${this.assessmentId}/submissions/${this.submissionId}/answers`;
}

fetch(
answerId: number,
): APIResponse<AnswerDataWithQuestion<keyof typeof QuestionType>> {
return this.client.get(`${this.#urlPrefix}/${answerId}`);
}

saveDraft(answerId: number, answerData: unknown): APIResponse<AnswerData> {
const config = {
headers: {
Expand Down
15 changes: 0 additions & 15 deletions client/app/api/course/Assessment/SubmissionQuestions.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,6 @@ export default class SubmissionQuestionsAPI extends BaseAssessmentAPI {
);
}

/**
* Gets the past answers from a SubmissionQuestion
* Can include answers_to_load in params to indicate how many to pull (default 10)
*
* @param {number} submissionQuestionId
* @return {Promise}
*/
getPastAnswers(submissionQuestionId, answersToLoad = 10) {
const params = { answers_to_load: answersToLoad };
return this.client.get(
`${this.#urlPrefix}/${submissionQuestionId}/past_answers`,
{ params },
);
}

get #urlPrefix() {
return `/courses/${this.courseId}/assessments/${this.assessmentId}/submission_questions`;
}
Expand Down
2 changes: 2 additions & 0 deletions client/app/api/course/Assessment/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import SessionsAPI from './Sessions';
import SkillsAPI from './Skills';
import SubmissionQuestionsAPI from './SubmissionQuestions';
import SubmissionsAPI from './Submissions';
import AllAnswersAPI from './AllAnswers';

const AssessmentAPI = {
answer: AnswerAPI,
allAnswers: new AllAnswersAPI(),
assessments: new AssessmentsAPI(),
categories: new CategoriesAPI(),
logs: new LogsAPI(),
Expand Down
16 changes: 0 additions & 16 deletions client/app/api/course/Statistics/AllAnswerStatistics.ts

This file was deleted.

4 changes: 2 additions & 2 deletions client/app/api/course/Statistics/AnswerStatistics.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { QuestionType } from 'types/course/assessment/question';
import { AnswerStatisticsData } from 'types/course/statistics/assessmentStatistics';

import { APIResponse } from 'api/types';
import { AnswerDataWithQuestion } from 'course/assessment/submission/types';

import BaseCourseAPI from '../Base';

Expand All @@ -12,7 +12,7 @@ export default class AnswerStatisticsAPI extends BaseCourseAPI {

fetch(
answerId: number,
): APIResponse<AnswerStatisticsData<keyof typeof QuestionType>> {
): APIResponse<AnswerDataWithQuestion<keyof typeof QuestionType>> {
return this.client.get(`${this.#urlPrefix}/${answerId}`);
}
}
Loading