feat: add admin stats
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
from unittest import mock
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from accounts.models import CustomUser
|
||||
from events.models import Event
|
||||
from games.models import EventGame, Game
|
||||
|
||||
from .models import PixelPlacement, PlaceSettings
|
||||
|
||||
URL = "/api/events/event/place/stats"
|
||||
|
||||
|
||||
@mock.patch("place.stats.read_canvas")
|
||||
class PlaceStatsTests(TestCase):
|
||||
def setUp(self):
|
||||
self.event = Event.objects.create(name="Event", path="event")
|
||||
place = Game.objects.create(name="Place", path="place", custom_path=True)
|
||||
EventGame.objects.create(event=self.event, game=place)
|
||||
PlaceSettings.objects.create(event=self.event, width=4, height=2)
|
||||
self.alice = CustomUser.objects.create_user(username="alice", password="x")
|
||||
self.bob = CustomUser.objects.create_user(username="bob", password="x")
|
||||
self.admin = CustomUser.objects.create_user(
|
||||
username="admin", password="x", is_staff=True
|
||||
)
|
||||
|
||||
def place(self, player, x, y, color_index):
|
||||
PixelPlacement.objects.create(
|
||||
event=self.event, player=player, x=x, y=y, color_index=color_index
|
||||
)
|
||||
|
||||
def test_requires_staff(self, _):
|
||||
self.client.force_login(self.alice)
|
||||
|
||||
response = self.client.get(URL)
|
||||
|
||||
self.assertEqual(response.status_code, 401)
|
||||
|
||||
def test_empty_game(self, read_canvas):
|
||||
read_canvas.return_value = b""
|
||||
self.client.force_login(self.admin)
|
||||
|
||||
data = self.client.get(URL).json()
|
||||
|
||||
self.assertEqual(data["total_placements"], 0)
|
||||
self.assertEqual(data["total_players"], 0)
|
||||
self.assertEqual(data["coverage"], 0.0)
|
||||
self.assertEqual(data["avg_placements_per_player"], 0.0)
|
||||
self.assertEqual(data["colors"][0]["on_canvas"], 8)
|
||||
self.assertEqual(data["per_hour"], [])
|
||||
|
||||
def test_stats(self, read_canvas):
|
||||
self.place(self.alice, 0, 0, 5)
|
||||
self.place(self.bob, 0, 0, 3)
|
||||
self.place(self.alice, 0, 0, 5)
|
||||
self.place(self.alice, 1, 0, 3)
|
||||
# Outside the current grid, e.g. from before a shrink
|
||||
self.place(self.bob, 9, 9, 3)
|
||||
# Short canvas, Redis only padded up to the last written pixel
|
||||
read_canvas.return_value = bytes([5, 3])
|
||||
self.client.force_login(self.admin)
|
||||
|
||||
data = self.client.get(URL).json()
|
||||
|
||||
self.assertEqual(data["total_placements"], 5)
|
||||
self.assertEqual(data["total_players"], 2)
|
||||
self.assertEqual(data["pixels_touched"], 2)
|
||||
self.assertEqual(data["coverage"], 0.25)
|
||||
self.assertEqual(data["overwrites"], 2)
|
||||
self.assertEqual(data["avg_placements_per_player"], 2.5)
|
||||
self.assertEqual(
|
||||
data["top_players"],
|
||||
[
|
||||
{"username": "alice", "placements": 3},
|
||||
{"username": "bob", "placements": 2},
|
||||
],
|
||||
)
|
||||
self.assertEqual(
|
||||
data["most_contested_pixels"][0],
|
||||
{"x": 0, "y": 0, "placements": 3, "players": 2},
|
||||
)
|
||||
colors = {row["color_index"]: row for row in data["colors"]}
|
||||
self.assertEqual(colors[5]["placements"], 2)
|
||||
self.assertEqual(colors[3]["placements"], 3)
|
||||
self.assertEqual(colors[5]["on_canvas"], 1)
|
||||
self.assertEqual(colors[0]["on_canvas"], 6)
|
||||
self.assertEqual(sum(row["placements"] for row in data["per_hour"]), 5)
|
||||
Reference in New Issue
Block a user