diff --git a/lib/cadet/assessments/assessments.ex b/lib/cadet/assessments/assessments.ex index e1327bf0a..871b0fc7c 100644 --- a/lib/cadet/assessments/assessments.ex +++ b/lib/cadet/assessments/assessments.ex @@ -1338,8 +1338,6 @@ defmodule Cadet.Assessments do else it is {:error, {:forbidden, "Forbidden."}} """ - # We bypass Ecto here and use a raw query to generate JSON directly from - # PostgreSQL, because doing it in Elixir/Erlang is too inefficient. @spec submissions_by_grader_for_index(CourseRegistration.t()) :: {:ok, %{ diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs index dee7be580..c5661ee65 100644 --- a/priv/repo/seeds.exs +++ b/priv/repo/seeds.exs @@ -9,127 +9,186 @@ # # We recommend using the bang functions (`insert!`, `update!` # and so on) as they will fail if something goes wrong. +use Cadet, [:context, :display] + +import Cadet.Factory import Cadet.Factory +import Ecto.Query alias Cadet.Assessments.SubmissionStatus +alias Cadet.Accounts.{ + User, + CourseRegistration +} + # insert default source version # Cadet.Repo.insert!(%Cadet.Settings.Sublanguage{chapter: 1, variant: "default"}) if Cadet.Env.env() == :dev do + number_of_students = 10 + number_of_assessments = 5 + number_of_questions = 3 + # Course - course1 = insert(:course) - course2 = insert(:course, %{course_name: "Algorithm", course_short_name: "CS2040S"}) - # Users - avenger1 = insert(:user, %{name: "avenger", latest_viewed_course: course1}) - admin1 = insert(:user, %{name: "admin", latest_viewed_course: course1}) - - studenta1admin2 = insert(:user, %{name: "student a", latest_viewed_course: course1}) - - studentb1 = insert(:user, %{latest_viewed_course: course1}) - studentc1 = insert(:user, %{latest_viewed_course: course1}) - # CourseRegistration and Group - avenger1_cr = insert(:course_registration, %{user: avenger1, course: course1, role: :staff}) - _admin1_cr = insert(:course_registration, %{user: admin1, course: course1, role: :admin}) - group = insert(:group, %{leader: avenger1_cr}) - - student1a_cr = - insert(:course_registration, %{ - user: studenta1admin2, - course: course1, - role: :student, - group: group - }) - - student1b_cr = - insert(:course_registration, %{user: studentb1, course: course1, role: :student, group: group}) - - student1c_cr = - insert(:course_registration, %{user: studentc1, course: course1, role: :student, group: group}) - - students = [student1a_cr, student1b_cr, student1c_cr] - - _admin2cr = - insert(:course_registration, %{user: studenta1admin2, course: course2, role: :admin}) - - # Assessments - for i <- 1..5 do - config = insert(:assessment_config, %{type: "Mission#{i}", order: i, course: course1}) - assessment = insert(:assessment, %{is_published: true, config: config, course: course1}) - - config2 = insert(:assessment_config, %{type: "Homework#{i}", order: i, course: course2}) - _assessment2 = insert(:assessment, %{is_published: true, config: config2, course: course2}) - - programming_questions = - insert_list(3, :programming_question, %{ - assessment: assessment, - max_xp: 1_000 - }) - - mcq_questions = - insert_list(3, :mcq_question, %{ - assessment: assessment, - max_xp: 500 - }) - - submissions = - students - |> Enum.take(2) - |> Enum.map( - &insert(:submission, %{ - assessment: assessment, - student: &1, - status: Enum.random(SubmissionStatus.__enum_map__()) - }) - ) - - # Programming Answers - for submission <- submissions, - question <- programming_questions do - insert(:answer, %{ - xp: Enum.random(0..1_000), - question: question, - submission: submission, - answer: build(:programming_answer) - }) + admin_course = + insert(:course, %{course_name: "Mock Admin Course", course_short_name: "CS0000S"}) + + # Admin, Staff and Group + admin_cr = + from(cr in CourseRegistration, + where: cr.user_id in subquery(from(u in User, where: u.name == ^"admin", select: u.id)), + select: cr + ) + |> Repo.one() + + admin_cr = + if admin_cr == nil do + admin = + insert(:user, %{name: "Test Admin", username: "admin", latest_viewed_course: admin_course}) + + insert(:course_registration, %{user: admin, course: admin_course, role: :admin}) + else + admin_cr end - # MCQ Answers - for submission <- submissions, - question <- mcq_questions do - insert(:answer, %{ - xp: Enum.random(0..500), - question: question, - submission: submission, - answer: build(:mcq_answer) - }) + avenger_course = + insert(:course, %{course_name: "Mock Avenger Course", course_short_name: "CS1111S"}) + + avenger_cr = + from(cr in CourseRegistration, + where: cr.user_id in subquery(from(u in User, where: u.name == ^"staff", select: u.id)), + select: cr + ) + |> Repo.one() + + avenger_cr = + if avenger_cr == nil do + avenger = + insert(:user, %{ + name: "Test Staff", + username: "staff", + latest_viewed_course: avenger_course + }) + + insert(:course_registration, %{user: avenger, course: avenger_course, role: :staff}) + else + avenger_cr end - # # Notifications - # for submission <- submissions do - # case submission.status do - # :submitted -> - # insert(:notification, %{ - # type: :submitted, - # read: false, - # user_id: avenger.id, - # submission_id: submission.id, - # assessment_id: assessment.id - # }) - - # _ -> - # nil - # end - # end - - # for student <- students do - # insert(:notification, %{ - # type: :new, - # user_id: student.id, - # assessment_id: assessment.id - # }) - # end - end + admin_group = insert(:group, %{name: "MockAdminGroup", leader: admin_cr}) + avenger_group = insert(:group, %{name: "MockAvengerGroup", leader: avenger_cr}) + + groups_and_courses = [{admin_group, admin_course}, {avenger_group, avenger_course}] + # Users + + Enum.each(groups_and_courses, fn {group, course} -> + students = + for i <- 1..number_of_students do + student = insert(:user, %{latest_viewed_course: course}) + + student_cr = + insert(:course_registration, %{ + user: student, + course: course, + role: :student, + group: group + }) + + student_cr + end + + # Assessments and Submissions + valid_assessment_types = [{1, "Missions"}, {2, "Paths"}, {3, "Quests"}] + + assessment_configs = + Enum.map(valid_assessment_types, fn {order, type} -> + insert(:assessment_config, %{type: type, order: order, course: course}) + end) + + for i <- 1..number_of_assessments do + assessment = + insert(:assessment, %{ + is_published: true, + config: Enum.random(assessment_configs), + course: course + }) + + questions = + case assessment.config.type do + "Missions" -> + insert_list(number_of_questions, :programming_question, %{ + assessment: assessment, + max_xp: 1_000 + }) + + "Paths" -> + insert_list(number_of_questions, :mcq_question, %{assessment: assessment, max_xp: 500}) + + "Quests" -> + insert_list(number_of_questions, :programming_question, %{ + assessment: assessment, + max_xp: 1_000 + }) + end + + submissions = + students + |> Enum.map( + &insert(:submission, %{ + assessment: assessment, + student: &1, + status: Enum.random(SubmissionStatus.__enum_map__()) + }) + ) + + for submission <- submissions, + question <- questions do + case question.type do + :programming -> + insert(:answer, %{ + xp: Enum.random(0..1_000), + question: question, + submission: submission, + answer: build(:programming_answer) + }) + + :mcq -> + insert(:answer, %{ + xp: Enum.random(0..500), + question: question, + submission: submission, + answer: build(:mcq_answer) + }) + end + end + + # # Notifications + # for submission <- submissions do + # case submission.status do + # :submitted -> + # insert(:notification, %{ + # type: :submitted, + # read: false, + # user_id: avenger.id, + # submission_id: submission.id, + # assessment_id: assessment.id + # }) + + # _ -> + # nil + # end + # end + + # for student <- students do + # insert(:notification, %{ + # type: :new, + # user_id: student.id, + # assessment_id: assessment.id + # }) + # end + end + end) # goal_0 = # insert(:goal, %{