Skip to content

Commit 3cf8d7d

Browse files
emptygxYaleChen299RichDom2185GabrielCWT
authored
Add Publish Grading Feature (#965)
* Add migrations to create is_grading_published column for submissions Current submissions will have the is_grading_published field populated as `true` if all answers have been graded i.e. have a grader_id, while the rest will default to `false`. Future submissions will have the field with default value `false` upon creation. * Add and update endpoints for new publish grading feature - Update existing endpoints and queries related to assessment retrieval - Add new routes and endpoints to handle new publish grading feature - Add notification for new feature * Fix missing return tuple values in assessments.ex * Fix notification and formatting * Fix indentation and minor error * Fix formatting * fix formatting * fix credo long line * fix credo nesting alias * Fix formatting and code quality * Fix tests * feat: Implement format helper function Changing xp in the assessment_with_questions_and_answers is the wrong direction, I feel that the function should not be tied to a specific format. Instead, I will call a helper function in the controller to format the xp. * feat: Add formatting function for getting all assessments * fix: Fix bug of using virtual variable instead * refactor: Remove default value for virtual variable is_grading_published * feat: Implement tests for helper functions * feat: Add isGradingPublished to response for fetching all assessments * refactor: Format * chore: Remove unused match * feat: Implement tests for unpublish route * feat: Implement tests for publish route * refactor: Move repeated code into setup for publish test * refactor: Move repeated code into setup for unpublish test * refactor: Format code * feat: Add a guard to prevent unsubmit when grade is still published * feat: Implement filter by notPublished * refactor: Format * fix: Fix incorrect guard check for is_grading_published * refactor: Edit tests to accommodate new guard * feat: Implement test for new guard (check is_grading_published) * feat: Update seed to include is_grading_published * refactor: Update old tests to accommodate for is_grading_published * refactor: Improve filter tests to be more flexible Remove hard coded numbers and count expected number with students_with_assessment_info * feat: Implement test for filter by not published * chore: Format * refactor: Make is_grading_published default to false in factory function * feat: Add is_grading_auto_published column to assessment config * feat: Add guard clause to ensure submission is fully graded before publishing * feat: Implement publish_grading and is_fully_autograded? - Adds another publish_grading function which bypasses all checks - Adds a new function is_fully_autograded? which checks if all answers are successfully auto graded * chore: Clean up code * feat: Add is_grading_auto_published and is_manually_graded to seed * feat: Implement tests for is_fully_autograded?/1 * feat: Implement publish_all_grades route * feat: Add publish_all_grades in controller * feat: Implement publish_all_graded function * feat: Implement tests for publish_all_graded/2 * refactor: Rename param names and allow filter by true or false * refactor: Add tests for change in param and refactor code * refactor: Change response for publish all grades * refactor: Use update_all instead of recursively updating individual submissions * feat: Implement unpublish all grades route * feat: Implement unpublish_all * feat: Implement unpublish_all tests * chore: Format * feat: Implement auto publish for mcq/voting questions * feat: Implement auto publish for auto graded programming questions * chore: Fix consistency issue * feat: Implement published and unpublished notifications and remove deprecated ones * feat: Include isGradingAutoPublished in response for assessment configs * fix: Include sending of notifications when publishing/unpublishing all * docs: Add docs for functions implemented * chore: Update wording for tests * chore: Remove unused variables * feat: Implement test for unpublish and publish all routes * feat: Implement guard for publish/unpublish grades This commit prevents admin/staff from individually publishing/unpublishing grades for students. * refactor: Change notification types in swagger_schema * chore: Add comment in seed * refactor: remove redundant lines * Redate migrations Ensures total ordering of migration files are preserved. * Revert unnecessary changes * Revert more unnecessary changes * refactor: Move duplicate code into helper function * chore: Fix typo * refactor: Change control flow structure --------- Co-authored-by: YaleChen299 <[email protected]> Co-authored-by: Richard Dominick <[email protected]> Co-authored-by: GabrielCWT <[email protected]>
1 parent d94f60a commit 3cf8d7d

33 files changed

+1715
-155
lines changed

lib/cadet/accounts/notification_type.ex

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import EctoEnum
33
defenum(Cadet.Accounts.NotificationType, :notification_type, [
44
# Notifications for new assessments
55
:new,
6-
# Notifications for autograded assessments
7-
:autograded,
8-
# Notifications for manually graded assessments
9-
:graded,
106
# Notifications for unsubmitted submissions
117
:unsubmitted,
128
# Notifications for submitted assessments
13-
:submitted
9+
:submitted,
10+
# Notifications for published grades
11+
:published_grading,
12+
# Notifications for unpublished grades
13+
:unpublished_grading
1414
])

lib/cadet/accounts/notifications.ex

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,18 +145,41 @@ defmodule Cadet.Accounts.Notifications do
145145
{:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
146146
def handle_unsubmit_notifications(assessment_id, student = %CourseRegistration{})
147147
when is_ecto_id(assessment_id) do
148-
# Fetch and delete all notifications of :autograded and :graded
148+
# Fetch and delete all notifications of :unpublished_grading
149149
# Add new notification :unsubmitted
150150

151151
Notification
152152
|> where(course_reg_id: ^student.id)
153153
|> where(assessment_id: ^assessment_id)
154-
|> where([n], n.type in ^[:autograded, :graded])
154+
|> where([n], n.type in ^[:unpublished_grading])
155155
|> Repo.delete_all()
156156

157157
write(%{
158158
type: :unsubmitted,
159-
role: student.role,
159+
role: :student,
160+
course_reg_id: student.id,
161+
assessment_id: assessment_id
162+
})
163+
end
164+
165+
@doc """
166+
Function that handles notifications when a submission grade is unpublished.
167+
Deletes all :published notifications and adds a new :unpublished_grading notification.
168+
"""
169+
@spec handle_unpublish_grades_notifications(integer(), CourseRegistration.t()) ::
170+
{:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
171+
def handle_unpublish_grades_notifications(assessment_id, student = %CourseRegistration{})
172+
when is_ecto_id(assessment_id) do
173+
Notification
174+
|> where(course_reg_id: ^student.id)
175+
|> where(assessment_id: ^assessment_id)
176+
|> where([n], n.type in ^[:published_grading])
177+
|> Repo.delete_all()
178+
179+
write(%{
180+
type: :unpublished_grading,
181+
read: false,
182+
role: :student,
160183
course_reg_id: student.id,
161184
assessment_id: assessment_id
162185
})
@@ -166,9 +189,9 @@ defmodule Cadet.Accounts.Notifications do
166189
Writes a notification that a student's submission has been
167190
graded successfully. (for the student)
168191
"""
169-
@spec write_notification_when_graded(integer(), any()) ::
192+
@spec write_notification_when_published(integer(), any()) ::
170193
{:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
171-
def write_notification_when_graded(submission_id, type) when type in [:graded, :autograded] do
194+
def write_notification_when_published(submission_id, type) when type in [:published_grading] do
172195
case Repo.get(Submission, submission_id) do
173196
nil ->
174197
{:error, %Ecto.Changeset{}}

lib/cadet/assessments/assessment.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ defmodule Cadet.Assessments.Assessment do
2020
field(:grading_status, :string, virtual: true)
2121
field(:question_count, :integer, virtual: true)
2222
field(:graded_count, :integer, virtual: true)
23+
field(:is_grading_published, :boolean, virtual: true)
2324
field(:title, :string)
2425
field(:is_published, :boolean, default: false)
2526
field(:summary_short, :string)

0 commit comments

Comments
 (0)