Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
3,738 changes: 1,869 additions & 1,869 deletions evap/development/fixtures/test_data.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generated by Django 6.0.4 on 2026-04-13 18:05

from django.db import migrations, models


def forwards(apps, schema_editor): # pylint: disable=unused-argument
TextAnswer = apps.get_model("evaluation", "TextAnswer")
TextAnswer.objects.filter(review_decision="PR").update(review_decision="PU")


class Migration(migrations.Migration):
dependencies = [
("evaluation", "0163_migrate_cms_links"),
]

operations = [
migrations.RemoveConstraint(
model_name="textanswer",
name="TextAnswer_review_decision_choices",
),
migrations.AlterField(
model_name="textanswer",
name="review_decision",
field=models.CharField(
choices=[("PU", "public"), ("DE", "deleted"), ("UN", "undecided")],
default="UN",
max_length=2,
verbose_name="review decision for the answer",
),
),
migrations.AddConstraint(
model_name="textanswer",
constraint=models.CheckConstraint(
condition=models.Q(("review_decision__in", ["PU", "DE", "UN"])),
name="TextAnswer_review_decision_choices",
),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generated by Django 6.0.4 on 2026-04-13 18:38

from django.db import migrations, models


def forwards(apps, schema_editor): # pylint: disable=unused-argument
TextAnswer = apps.get_model("evaluation", "TextAnswer")
TextAnswer.objects.filter(review_decision="PU").update(review_decision="KE")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed: We need to actually call this -- please also name it a bit more descriptively (what does the method actually do?)



class Migration(migrations.Migration):
dependencies = [
("evaluation", "0164_remove_textanswer_textanswer_review_decision_choices_and_more"),
]

operations = [
migrations.RemoveConstraint(
model_name="textanswer",
name="TextAnswer_review_decision_choices",
),
migrations.AlterField(
model_name="textanswer",
name="review_decision",
field=models.CharField(
choices=[("KE", "keep"), ("DE", "deleted"), ("UN", "undecided")],
default="UN",
max_length=2,
verbose_name="review decision for the answer",
),
),
migrations.AddConstraint(
model_name="textanswer",
constraint=models.CheckConstraint(
condition=models.Q(("review_decision__in", ["KE", "DE", "UN"])),
name="TextAnswer_review_decision_choices",
),
),
]
21 changes: 3 additions & 18 deletions evap/evaluation/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1628,8 +1628,7 @@ class ReviewDecision(models.TextChoices):
When publishing evaluation results, this answer should be ...
"""

PUBLIC = "PU", _("public")
PRIVATE = "PR", _("private") # This answer should only be displayed to the contributor the question was about
KEEP = "KE", _("keep")
DELETED = "DE", _("deleted")

UNDECIDED = "UN", _("undecided")
Expand Down Expand Up @@ -1660,22 +1659,8 @@ def will_be_deleted(self):
return self.review_decision == self.ReviewDecision.DELETED

@property
def will_be_private(self):
return self.review_decision == self.ReviewDecision.PRIVATE

@property
def will_be_public(self):
return self.review_decision == self.ReviewDecision.PUBLIC

# Once evaluation results are published, the review decision is executed
# and thus, an answer _is_ private or _is_ public from that point on.
@property
def is_public(self):
return self.will_be_public

@property
def is_private(self):
return self.will_be_private
def will_be_kept(self):
return self.review_decision == self.ReviewDecision.KEEP

@property
def is_reviewed(self):
Expand Down
15 changes: 7 additions & 8 deletions evap/evaluation/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,21 +381,20 @@ def test_textanswers_to_delete_get_deleted_on_publish(self):
assignment__question__type=QuestionType.TEXT,
assignment__questionnaire=questionnaire,
contribution=evaluation.general_contribution,
answer=iter(["deleted", "public", "private"]),
answer=iter(["deleted", "keep"]),
review_decision=iter(
[
TextAnswer.ReviewDecision.DELETED,
TextAnswer.ReviewDecision.PUBLIC,
TextAnswer.ReviewDecision.PRIVATE,
TextAnswer.ReviewDecision.KEEP,
]
),
_quantity=3,
_quantity=2,
_bulk_create=True,
)

self.assertEqual(evaluation.textanswer_set.count(), 3)
evaluation.publish()
self.assertEqual(evaluation.textanswer_set.count(), 2)
evaluation.publish()
self.assertEqual(evaluation.textanswer_set.count(), 1)
self.assertFalse(TextAnswer.objects.filter(answer="deleted").exists())

def test_original_textanswers_get_deleted_on_publish(self):
Expand All @@ -417,7 +416,7 @@ def test_original_textanswers_get_deleted_on_publish(self):
contribution=evaluation.general_contribution,
answer="published answer",
original_answer="original answer",
review_decision=TextAnswer.ReviewDecision.PUBLIC,
review_decision=TextAnswer.ReviewDecision.KEEP,
)

self.assertEqual(evaluation.textanswer_set.count(), 1)
Expand Down Expand Up @@ -548,7 +547,7 @@ def test_textanswer_review_state(self):
evaluation.TextAnswerReviewState.REVIEW_URGENT, # grades were uploaded
)

textanswer.review_decision = TextAnswer.ReviewDecision.PUBLIC
textanswer.review_decision = TextAnswer.ReviewDecision.KEEP
textanswer.save()
del evaluation.num_reviewed_textanswers # reset cached_property cache

Expand Down
18 changes: 9 additions & 9 deletions evap/results/fixtures/minimal_test_data_results.json
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@
"contribution": 1,
"answer": ".general_orig_published.",
"original_answer": null,
"review_decision": "PU",
"review_decision": "KE",
"is_flagged": false
}
},
Expand All @@ -285,7 +285,7 @@
"contribution": 1,
"answer": ".general_changed_published.",
"original_answer": ".general_orig_published_changed.",
"review_decision": "PU",
"review_decision": "KE",
"is_flagged": false
}
},
Expand All @@ -297,7 +297,7 @@
"contribution": 3,
"answer": ".contributor_orig_published.",
"original_answer": null,
"review_decision": "PU",
"review_decision": "KE",
"is_flagged": false
}
},
Expand All @@ -309,7 +309,7 @@
"contribution": 3,
"answer": ".contributor_orig_private.",
"original_answer": null,
"review_decision": "PR",
"review_decision": "KE",
"is_flagged": false
}
},
Expand All @@ -321,7 +321,7 @@
"contribution": 6,
"answer": ".responsible_contributor_orig_published.",
"original_answer": null,
"review_decision": "PU",
"review_decision": "KE",
"is_flagged": false
}
},
Expand All @@ -345,7 +345,7 @@
"contribution": 6,
"answer": ".responsible_contributor_changed_published.",
"original_answer": ".responsible_contributor_orig_published_changed.",
"review_decision": "PU",
"review_decision": "KE",
"is_flagged": false
}
},
Expand All @@ -357,7 +357,7 @@
"contribution": 6,
"answer": ".responsible_contributor_orig_private.",
"original_answer": null,
"review_decision": "PR",
"review_decision": "KE",
"is_flagged": false
}
},
Expand All @@ -381,7 +381,7 @@
"contribution": 6,
"answer": ".responsible_contributor_additional_orig_published.",
"original_answer": null,
"review_decision": "PU",
"review_decision": "KE",
"is_flagged": false
}
},
Expand All @@ -405,7 +405,7 @@
"contribution": 1,
"answer": ".general_additional_orig_published.",
"original_answer": null,
"review_decision": "PU",
"review_decision": "KE",
"is_flagged": false
}
},
Expand Down
3 changes: 0 additions & 3 deletions evap/results/templates/textanswer_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
<ul>
{% for answer in question_result.answers %}
<li>
{% if answer.is_private %}
<span data-bs-toggle="tooltip" data-bs-placement="left" class="fas fa-circle-info d-print-none" title="{% translate 'This answer is only visible to you. Other contributors and your delegates cannot see it.' %}"></span>
{% endif %}
{{ answer.answer|linebreaksbr }}
</li>
{% endfor %}
Expand Down
2 changes: 1 addition & 1 deletion evap/results/tests/test_exporters.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ def test_text_answer_export(self):
assignment=iter(assignments[idx] for idx in [0, 1, 2, 2, 0]),
contribution__evaluation=evaluation,
contribution__questionnaires=iter(assignments[idx].questionnaire for idx in [0, 1, 2, 2, 0]),
review_decision=TextAnswer.ReviewDecision.PUBLIC,
review_decision=TextAnswer.ReviewDecision.KEEP,
_quantity=5,
)

Expand Down
12 changes: 6 additions & 6 deletions evap/results/tests/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -536,37 +536,37 @@ def setUpTestData(cls):
TextAnswer,
assignment=cls.assignment,
contribution=cls.general_contribution,
review_decision=TextAnswer.ReviewDecision.PUBLIC,
review_decision=TextAnswer.ReviewDecision.KEEP,
)
cls.responsible1_textanswer = baker.make(
TextAnswer,
assignment=cls.assignment,
contribution=cls.responsible1_contribution,
review_decision=TextAnswer.ReviewDecision.PUBLIC,
review_decision=TextAnswer.ReviewDecision.KEEP,
)
cls.responsible1_additional_textanswer = baker.make(
TextAnswer,
assignment=cls.assignment_likert,
contribution=cls.responsible1_contribution,
review_decision=TextAnswer.ReviewDecision.PUBLIC,
review_decision=TextAnswer.ReviewDecision.KEEP,
)
cls.responsible2_textanswer = baker.make(
TextAnswer,
assignment=cls.assignment,
contribution=cls.responsible2_contribution,
review_decision=TextAnswer.ReviewDecision.PUBLIC,
review_decision=TextAnswer.ReviewDecision.KEEP,
)
cls.contributor_own_textanswer = baker.make(
TextAnswer,
assignment=cls.assignment,
contribution=cls.contributor_own_contribution,
review_decision=TextAnswer.ReviewDecision.PUBLIC,
review_decision=TextAnswer.ReviewDecision.KEEP,
)
cls.contributor_general_textanswer = baker.make(
TextAnswer,
assignment=cls.assignment,
contribution=cls.contributor_general_contribution,
review_decision=TextAnswer.ReviewDecision.PUBLIC,
review_decision=TextAnswer.ReviewDecision.KEEP,
)

def test_text_answer_visible_to_non_contributing_responsible(self):
Expand Down
6 changes: 2 additions & 4 deletions evap/results/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ def _get_results_impl(evaluation: Evaluation, *, refetch_related_objects: bool =
((textanswer.contribution_id, textanswer.assignment_id), textanswer)
for contribution in evaluation.contributions.all()
for textanswer in contribution.textanswer_set.all()
if textanswer.review_decision in [TextAnswer.ReviewDecision.PRIVATE, TextAnswer.ReviewDecision.PUBLIC]
if textanswer.review_decision in TextAnswer.ReviewDecision.KEEP

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if textanswer.review_decision in TextAnswer.ReviewDecision.KEEP
if textanswer.review_decision == TextAnswer.ReviewDecision.KEEP

)

racs_per_contribution_assignment: dict[tuple[int, int], list[RatingAnswerCounter]] = unordered_groupby(
Expand Down Expand Up @@ -483,7 +483,7 @@ def can_textanswer_be_seen_by( # noqa: PLR0911,PLR0912
view_general_results: ViewGeneralResults,
view_contributor_results: ViewContributorResults,
) -> bool:
assert textanswer.review_decision in [TextAnswer.ReviewDecision.PRIVATE, TextAnswer.ReviewDecision.PUBLIC]
assert textanswer.review_decision == TextAnswer.ReviewDecision.KEEP
contributor = textanswer.contribution.contributor

# NOTE: when changing this behavior, make sure all changes are also reflected in results.tools.textanswers_visible_to
Expand All @@ -509,8 +509,6 @@ def can_textanswer_be_seen_by( # noqa: PLR0911,PLR0912
case ViewContributorResults.FULL:
if user.is_reviewer:
return True
if textanswer.is_private:
return user == contributor
return contributor in represented_users

return False
4 changes: 1 addition & 3 deletions evap/staff/templates/staff_evaluation_textanswers_quick.html
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,8 @@ <h5 class="modal-title" id="hotkeys-modal-title">Hotkeys</h5>
data-id="{{ answer.id }}"
{% if contributor %} data-contribution="yes"{% endif %}
{% if answer.is_reviewed %}
{% if answer.will_be_public %}
{% if answer.will_be_kept %}
data-review="publish"
{% elif answer.will_be_private %}
data-review="make_private"
{% else %}
data-review="delete"
{% endif %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,9 @@
<input type="hidden" name="answer_id" value="{{ answer.id }}" />

<div class="btn-group btn-group-sm outline-fix" role="group">
<input type="radio" class="btn-check" name="action" value="publish" id="{{ answer.id }}-radio-publish" autocomplete="off" {% if answer.will_be_public %}checked{% endif %}>
<input type="radio" class="btn-check" name="action" value="publish" id="{{ answer.id }}-radio-publish" autocomplete="off" {% if answer.will_be_kept %}checked{% endif %}>
<label class="btn btn-outline-primary" for="{{ answer.id }}-radio-publish">{% translate 'Publish' %}</label>

<input type="radio" class="btn-check" name="action" value="make_private" id="{{ answer.id }}-radio-private" autocomplete="off" {% if answer.will_be_private %}checked{% endif %} {% if not contributor %}disabled{% endif %}>
<label class="btn btn-outline-primary" for="{{ answer.id }}-radio-private">{% translate 'Private' %}</label>

<input type="radio" class="btn-check" name="action" value="unreview" id="{{ answer.id }}-radio-undecided" autocomplete="off" {% if not answer.is_reviewed %}checked{% endif %}>
<label class="btn btn-outline-primary" for="{{ answer.id }}-radio-undecided">{% translate 'Undecided' %}</label>

Expand Down
Loading