fixed pseudoanonymize on client

This commit is contained in:
Joshua Sangmeister 2020-04-15 09:42:22 +02:00
parent b7566fcc69
commit 9864ff3847
3 changed files with 101 additions and 21 deletions

View File

@ -50,7 +50,6 @@ export class AssignmentPollDetailComponent extends BasePollDetailComponent<ViewA
} }
protected createVotesData(): void { protected createVotesData(): void {
const votes = {};
const definitions: PblColumnDefinition[] = [ const definitions: PblColumnDefinition[] = [
{ {
prop: 'user', prop: 'user',
@ -66,9 +65,13 @@ export class AssignmentPollDetailComponent extends BasePollDetailComponent<ViewA
} }
]; ];
const votes = {};
let isPseudoanonymized = true;
for (const option of this.poll.options) { for (const option of this.poll.options) {
for (const vote of option.votes) { for (const vote of option.votes) {
const userId = vote.user_id; const userId = vote.user_id;
if (userId) {
isPseudoanonymized = false;
if (!votes[userId]) { if (!votes[userId]) {
votes[userId] = { votes[userId] = {
user: vote.user, user: vote.user,
@ -84,11 +87,16 @@ export class AssignmentPollDetailComponent extends BasePollDetailComponent<ViewA
votes[userId].votes.push(this.voteValueToLabel(vote.value)); votes[userId].votes.push(this.voteValueToLabel(vote.value));
} }
} else { } else {
votes[userId].votes.push(`${option.user.getShortName()}: ${this.voteValueToLabel(vote.value)}`); votes[userId].votes.push(
`${option.user.getShortName()}: ${this.voteValueToLabel(vote.value)}`
);
} }
} }
} }
} }
}
// if the poll was not pseudoanonymized, add all other users as empty votes
if (!isPseudoanonymized) {
for (const user of this.poll.voted) { for (const user of this.poll.voted) {
if (!votes[user.id]) { if (!votes[user.id]) {
votes[user.id] = { votes[user.id] = {
@ -97,6 +105,7 @@ export class AssignmentPollDetailComponent extends BasePollDetailComponent<ViewA
}; };
} }
} }
}
this.setVotesData(Object.values(votes)); this.setVotesData(Object.values(votes));
this.candidatesLabels = this.pollService.getChartLabels(this.poll); this.candidatesLabels = this.pollService.getChartLabels(this.poll);

View File

@ -167,7 +167,7 @@ class BasePollViewSet(ModelViewSet):
if poll.state not in (BasePoll.STATE_FINISHED, BasePoll.STATE_PUBLISHED): if poll.state not in (BasePoll.STATE_FINISHED, BasePoll.STATE_PUBLISHED):
raise ValidationError( raise ValidationError(
{"detail": "Pseudoanonmizing can only be done after a finished poll"} {"detail": "Pseudoanonymizing can only be done after finishing a poll"}
) )
if poll.type != BasePoll.TYPE_NAMED: if poll.type != BasePoll.TYPE_NAMED:
raise ValidationError( raise ValidationError(

View File

@ -2191,3 +2191,74 @@ class VoteAssignmentPollPseudoanonymousAutoupdates(
}, },
}, },
) )
class PseudoanonymizeAssignmentPoll(TestCase):
def advancedSetUp(self):
self.assignment = Assignment.objects.create(
title="test_assignment_QLydMOqkyOHG68yZFJxl", open_posts=1
)
self.assignment.add_candidate(self.admin)
self.poll = AssignmentPoll.objects.create(
assignment=self.assignment,
title="test_title_3LbUCNirKirpJhRHRxzW",
pollmethod=AssignmentPoll.POLLMETHOD_YNA,
type=BasePoll.TYPE_NAMED,
state=AssignmentPoll.STATE_FINISHED,
)
self.poll.groups.add(GROUP_ADMIN_PK)
self.poll.create_options()
self.option = self.poll.options.get()
self.user1, _ = self.create_user()
self.vote1 = AssignmentVote.objects.create(
user=self.user1, option=self.option, value="Y", weight=Decimal(1)
)
self.poll.voted.add(self.user1)
self.user2, _ = self.create_user()
self.vote2 = AssignmentVote.objects.create(
user=self.user2, option=self.option, value="N", weight=Decimal(1)
)
self.poll.voted.add(self.user2)
def test_pseudoanonymize_poll(self):
response = self.client.post(
reverse("assignmentpoll-pseudoanonymize", args=[self.poll.pk])
)
self.assertHttpStatusVerbose(response, status.HTTP_200_OK)
poll = AssignmentPoll.objects.get()
self.assertEqual(poll.get_votes().count(), 2)
self.assertEqual(poll.amount_users_voted(), 2)
self.assertEqual(poll.votesvalid, Decimal("2"))
self.assertEqual(poll.votesinvalid, Decimal("0"))
self.assertEqual(poll.votescast, Decimal("2"))
option = poll.options.get()
self.assertEqual(option.yes, Decimal("1"))
self.assertEqual(option.no, Decimal("1"))
self.assertEqual(option.abstain, Decimal("0"))
self.assertTrue(self.user1 in poll.voted.all())
self.assertTrue(self.user2 in poll.voted.all())
for vote in poll.get_votes().all():
self.assertTrue(vote.user is None)
def test_pseudoanonymize_wrong_state(self):
self.poll.state = AssignmentPoll.STATE_CREATED
self.poll.save()
response = self.client.post(
reverse("assignmentpoll-pseudoanonymize", args=[self.poll.pk])
)
self.assertHttpStatusVerbose(response, status.HTTP_400_BAD_REQUEST)
poll = AssignmentPoll.objects.get()
self.assertTrue(poll.get_votes().filter(user=self.user1).exists())
self.assertTrue(poll.get_votes().filter(user=self.user2).exists())
def test_pseudoanonymize_wrong_type(self):
self.poll.type = AssignmentPoll.TYPE_ANALOG
self.poll.save()
response = self.client.post(
reverse("assignmentpoll-pseudoanonymize", args=[self.poll.pk])
)
self.assertHttpStatusVerbose(response, status.HTTP_400_BAD_REQUEST)
poll = AssignmentPoll.objects.get()
self.assertTrue(poll.get_votes().filter(user=self.user1).exists())
self.assertTrue(poll.get_votes().filter(user=self.user2).exists())