Skip to content

Manually assign entries for voting #1097

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 29 commits into from
Apr 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2da5101
rename hasTokenCounter to hasVotingFeature under assessmentConfig
DesSnowy Mar 20, 2024
fe7854c
Added hasVotingFeatures to assessment config
DesSnowy Mar 21, 2024
d2bfd92
Added hasVotingFeature to assessmentConfig
DesSnowy Mar 21, 2024
cb18e73
Added hasTokenCounter and hasVotingFeatures to assessments
DesSnowy Mar 21, 2024
6012b11
hasTokenCounter and hasVotingFeatures to be updated to ones in assess…
DesSnowy Mar 21, 2024
ade5541
Added hasTokenCounter and hasVotingFeatures to be shown when assessme…
DesSnowy Mar 21, 2024
284da06
Added hasTokenCounter into swaggers
DesSnowy Mar 21, 2024
96d1dc7
Changed test cases to include hasVotingFeatures and hasTokenCounter
DesSnowy Mar 21, 2024
9687930
Added a way to change hasTokenCounter and hasVotingFeatures from the …
DesSnowy Mar 22, 2024
0bc2486
fixed format
DesSnowy Mar 22, 2024
6c5f9e6
Merge branch 'source-academy:master' into RenameHasTokenCounterToHasV…
DesSnowy Mar 22, 2024
394cb52
fixed format
DesSnowy Mar 22, 2024
49ac07d
fixed alias format
DesSnowy Mar 22, 2024
4c059eb
Merge branch 'RenameHasTokenCounterToHasVotingFeatures' of github.com…
DesSnowy Mar 22, 2024
74dfaed
added new function to delete voteSubmissions and call InsertVoting
DesSnowy Mar 24, 2024
41c61a3
Added ability to reassign voting
DesSnowy Mar 24, 2024
88f3653
rename update_voting to reassign_voting for clarity
DesSnowy Mar 24, 2024
48205a8
added test case for reassign_voting
DesSnowy Mar 24, 2024
f93efca
rename reassignEntriesForVoting to assignEntriesForVoting
DesSnowy Mar 26, 2024
6ee9e46
added isVotingPublished to AssessmentOverview and changed testCases t…
DesSnowy Mar 26, 2024
f625fff
fixed format
DesSnowy Mar 26, 2024
dcde401
Merge branch 'master' into ControlOfInsertVoting
DesSnowy Mar 28, 2024
7b03f68
Moved is_voting_published to be a function in assessments
DesSnowy Mar 28, 2024
2c8a332
Prevent deletions of submissions if voting has not been published
DesSnowy Mar 28, 2024
2339b36
fix format
DesSnowy Mar 28, 2024
293af4b
fix bug where submission is deleted regardless of reassigning_voting …
DesSnowy Mar 28, 2024
faec738
changed label for better clarity
DesSnowy Mar 29, 2024
bfc2c9e
Merge branch 'master' into ControlOfInsertVoting
DesSnowy Apr 6, 2024
ef820f1
Rename value for clarity and consistency
RichDom2185 Apr 6, 2024
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
52 changes: 52 additions & 0 deletions lib/cadet/assessments/assessments.ex
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,58 @@ defmodule Cadet.Assessments do
Question.changeset(%Question{}, params_with_assessment_id)
end

def reassign_voting(assessment_id, is_reassigning_voting) do
if is_reassigning_voting do
if is_voting_published(assessment_id) do
Submission
|> where(assessment_id: ^assessment_id)
|> delete_submission_association(assessment_id)

Question
|> where(assessment_id: ^assessment_id)
|> Repo.all()
|> Enum.each(fn q ->
delete_submission_votes_association(q)
end)
end

voting_assigned_question_ids =
SubmissionVotes
|> select([v], v.question_id)
|> Repo.all()

unpublished_voting_questions =
Question
|> where(type: :voting)
|> where([q], q.id not in ^voting_assigned_question_ids)
|> where(assessment_id: ^assessment_id)
|> join(:inner, [q], asst in assoc(q, :assessment))
|> select([q, asst], %{course_id: asst.course_id, question: q.question, id: q.id})
|> Repo.all()

for q <- unpublished_voting_questions do
insert_voting(q.course_id, q.question["contest_number"], q.id)
end

{:ok, "voting assigned"}
else
{:ok, "no change to voting"}
end
end

def is_voting_published(assessment_id) do
voting_assigned_question_ids =
SubmissionVotes
|> select([v], v.question_id)
|> Repo.all()

Question
|> where(type: :voting)
|> where(assessment_id: ^assessment_id)
|> where([q], q.id in ^voting_assigned_question_ids)
|> Repo.exists?()
end

def update_final_contest_entries do
# 1435 = 1 day - 5 minutes
if Log.log_execution("update_final_contest_entries", Duration.from_minutes(1435)) do
Expand Down
11 changes: 10 additions & 1 deletion lib/cadet_web/admin_controllers/admin_assessments_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ defmodule CadetWeb.AdminAssessmentsController do
max_team_size = params |> Map.get("maxTeamSize")
has_token_counter = params |> Map.get("hasTokenCounter")
has_voting_features = params |> Map.get("hasVotingFeatures")
assign_entries_for_voting = params |> Map.get("assignEntriesForVoting")

updated_assessment =
if is_nil(is_published) do
Expand Down Expand Up @@ -114,8 +115,16 @@ defmodule CadetWeb.AdminAssessmentsController do
Map.put(updated_assessment, :has_voting_features, has_voting_features)
end

is_reassigning_voting =
if is_nil(assign_entries_for_voting) do
false
else
assign_entries_for_voting
end

with {:ok, assessment} <- check_dates(open_at, close_at, updated_assessment),
{:ok, _nil} <- Assessments.update_assessment(assessment_id, assessment) do
{:ok, _nil} <- Assessments.update_assessment(assessment_id, assessment),
{:ok, _nil} <- Assessments.reassign_voting(assessment_id, is_reassigning_voting) do
text(conn, "OK")
else
{:error, {status, message}} ->
Expand Down
19 changes: 18 additions & 1 deletion lib/cadet_web/admin_views/admin_assessments_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ defmodule CadetWeb.AdminAssessmentsView do
use CadetWeb, :view
use Timex
import CadetWeb.AssessmentsHelpers
import Ecto.Query
alias Cadet.Assessments.{Question, SubmissionVotes}
alias Cadet.Repo

def render("index.json", %{assessments: assessments}) do
render_many(assessments, CadetWeb.AdminAssessmentsView, "overview.json", as: :assessment)
Expand Down Expand Up @@ -31,7 +34,8 @@ defmodule CadetWeb.AdminAssessmentsView do
earlySubmissionXp: & &1.config.early_submission_xp,
maxTeamSize: :max_team_size,
hasVotingFeatures: :has_voting_features,
hasTokenCounter: :has_token_counter
hasTokenCounter: :has_token_counter,
isVotingPublished: &is_voting_assigned(&1.id)
})
end

Expand Down Expand Up @@ -65,4 +69,17 @@ defmodule CadetWeb.AdminAssessmentsView do
defp password_protected?(nil), do: false

defp password_protected?(_), do: true

defp is_voting_assigned(assessment_id) do
voting_assigned_question_ids =
SubmissionVotes
|> select([v], v.question_id)
|> Repo.all()

Question
|> where(type: :voting)
|> where(assessment_id: ^assessment_id)
|> where([q], q.id in ^voting_assigned_question_ids)
|> Repo.exists?()
end
end
19 changes: 18 additions & 1 deletion lib/cadet_web/views/assessments_view.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
defmodule CadetWeb.AssessmentsView do
use CadetWeb, :view
use Timex
import Ecto.Query
alias Cadet.Assessments.{Question, SubmissionVotes}
alias Cadet.Repo

import CadetWeb.AssessmentsHelpers

Expand Down Expand Up @@ -32,7 +35,8 @@ defmodule CadetWeb.AssessmentsView do
earlySubmissionXp: & &1.config.early_submission_xp,
maxTeamSize: :max_team_size,
hasVotingFeatures: :has_voting_features,
hasTokenCounter: :has_token_counter
hasTokenCounter: :has_token_counter,
isVotingPublished: &is_voting_assigned(&1.id)
})
end

Expand Down Expand Up @@ -66,4 +70,17 @@ defmodule CadetWeb.AssessmentsView do
defp password_protected?(nil), do: false

defp password_protected?(_), do: true

defp is_voting_assigned(assessment_id) do
voting_assigned_question_ids =
SubmissionVotes
|> select([v], v.question_id)
|> Repo.all()

Question
|> where(type: :voting)
|> where(assessment_id: ^assessment_id)
|> where([q], q.id in ^voting_assigned_question_ids)
|> Repo.exists?()
end
end
71 changes: 71 additions & 0 deletions test/cadet/assessments/assessments_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,77 @@ defmodule Cadet.AssessmentsTest do
assert SubmissionVotes |> where(question_id: ^question.id) |> Repo.all() |> length() == 0
end

test "function that reassign voting after voting is assigned" do
course = insert(:course)
config = insert(:assessment_config)
# contest assessment that has closed
closed_contest_assessment =
insert(:assessment,
is_published: true,
open_at: Timex.shift(Timex.now(), days: -5),
close_at: Timex.shift(Timex.now(), hours: -1),
course: course,
config: config
)

contest_question = insert(:programming_question, assessment: closed_contest_assessment)
voting_assessment = insert(:assessment, %{course: course})

question =
insert(:voting_question, %{
assessment: voting_assessment,
question:
build(:voting_question_content, contest_number: closed_contest_assessment.number)
})

students =
insert_list(6, :course_registration, %{
role: :student,
course: course
})

Enum.map(students, fn student ->
submission =
insert(:submission,
student: student,
assessment: contest_question.assessment,
status: "submitted"
)

insert(:answer,
answer: %{code: "return 2;"},
submission: submission,
question: contest_question
)
end)

unattempted_student = insert(:course_registration, %{role: :student, course: course})

# unattempted submission will automatically be submitted after the assessment closes.
unattempted_submission =
insert(:submission,
student: unattempted_student,
assessment: contest_question.assessment,
status: "submitted"
)

insert(:answer,
answer: %{
code: "// question was left blank by student"
},
submission: unattempted_submission,
question: contest_question
)

Assessments.insert_voting(course.id, contest_question.assessment.number, question.id)
Assessments.reassign_voting(voting_assessment.id, true)

# students with own contest submissions will vote for 5 entries
# students without own contest submissin will vote for 6 entries
assert SubmissionVotes |> where(question_id: ^question.id) |> Repo.all() |> length() ==
6 * 5 + 6
end

test "function that checks for closed contests and releases entries into voting pool" do
course = insert(:course)
config = insert(:assessment_config)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule CadetWeb.AdminAssessmentsControllerTest do
import Ecto.Query
import ExUnit.CaptureLog

alias Cadet.Repo
alias Cadet.{Assessments, Repo}
alias Cadet.Accounts.CourseRegistration
alias Cadet.Assessments.{Assessment, Submission}
alias Cadet.Test.XMLGenerator
Expand Down Expand Up @@ -93,7 +93,8 @@ defmodule CadetWeb.AdminAssessmentsControllerTest do
"xp" => (800 + 500 + 100) * 3,
"earlySubmissionXp" => &1.config.early_submission_xp,
"hasVotingFeatures" => &1.has_voting_features,
"hasTokenCounter" => &1.has_token_counter
"hasTokenCounter" => &1.has_token_counter,
"isVotingPublished" => Assessments.is_voting_published(&1.id)
}
)

Expand Down Expand Up @@ -143,7 +144,8 @@ defmodule CadetWeb.AdminAssessmentsControllerTest do
"xp" => 0,
"earlySubmissionXp" => &1.config.early_submission_xp,
"hasVotingFeatures" => &1.has_voting_features,
"hasTokenCounter" => &1.has_token_counter
"hasTokenCounter" => &1.has_token_counter,
"isVotingPublished" => Assessments.is_voting_published(&1.id)
}
)

Expand Down
7 changes: 5 additions & 2 deletions test/cadet_web/controllers/assessments_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ defmodule CadetWeb.AssessmentsControllerTest do
"questionCount" => 9,
"earlySubmissionXp" => &1.config.early_submission_xp,
"hasVotingFeatures" => &1.has_voting_features,
"hasTokenCounter" => &1.has_token_counter
"hasTokenCounter" => &1.has_token_counter,
"isVotingPublished" => Assessments.is_voting_published(&1.id)
}
)

Expand Down Expand Up @@ -169,7 +170,8 @@ defmodule CadetWeb.AssessmentsControllerTest do
"questionCount" => 9,
"earlySubmissionXp" => &1.config.early_submission_xp,
"hasVotingFeatures" => &1.has_voting_features,
"hasTokenCounter" => &1.has_token_counter
"hasTokenCounter" => &1.has_token_counter,
"isVotingPublished" => Assessments.is_voting_published(&1.id)
}
)

Expand Down Expand Up @@ -282,6 +284,7 @@ defmodule CadetWeb.AssessmentsControllerTest do
"questionCount" => 9,
"hasVotingFeatures" => &1.has_voting_features,
"hasTokenCounter" => &1.has_token_counter,
"isVotingPublished" => Assessments.is_voting_published(&1.id),
"earlySubmissionXp" => &1.config.early_submission_xp,
"isPublished" =>
if &1.config.type == hd(configs).type do
Expand Down