feat(games): add steam pages with steam price/reduc
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
from unittest import mock
|
||||
|
||||
import httpx
|
||||
from django.core.cache import cache
|
||||
from django.test import TestCase, override_settings
|
||||
|
||||
from accounts.models import CustomUser
|
||||
from events.models import Event
|
||||
|
||||
from .models import EventGame, Game
|
||||
from .services.steam_store import refresh_steam_games
|
||||
from .tasks import refresh_steam_games_task, schedule_steam_refresh
|
||||
|
||||
LOCMEM_CACHE = {"default": {"BACKEND": "django.core.cache.backends.locmem.LocMemCache"}}
|
||||
|
||||
|
||||
def steam_response(app_id, data, success=True):
|
||||
return httpx.Response(
|
||||
200,
|
||||
json={str(app_id): {"success": success, "data": data}},
|
||||
request=httpx.Request("GET", "https://store.steampowered.com"),
|
||||
)
|
||||
|
||||
|
||||
class RefreshSteamGamesTests(TestCase):
|
||||
def setUp(self):
|
||||
self.game = Game.objects.create(name="Noita", path="noita", steam_app_id=881100)
|
||||
|
||||
@mock.patch("games.services.steam_store.httpx.get")
|
||||
def test_stores_price_and_discount(self, get):
|
||||
get.return_value = steam_response(
|
||||
881100,
|
||||
{
|
||||
"is_free": False,
|
||||
"short_description": "Every pixel is simulated.",
|
||||
"header_image": "https://example.com/header.jpg",
|
||||
"price_overview": {
|
||||
"currency": "CHF",
|
||||
"initial": 1950,
|
||||
"final": 780,
|
||||
"discount_percent": 60,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
refresh_steam_games()
|
||||
|
||||
self.game.refresh_from_db()
|
||||
self.assertEqual(self.game.steam_price_initial, 1950)
|
||||
self.assertEqual(self.game.steam_price_final, 780)
|
||||
self.assertEqual(self.game.steam_discount_percent, 60)
|
||||
self.assertEqual(self.game.steam_currency, "CHF")
|
||||
self.assertEqual(self.game.steam_short_description, "Every pixel is simulated.")
|
||||
self.assertIsNotNone(self.game.steam_info_updated_at)
|
||||
|
||||
@mock.patch("games.services.steam_store.httpx.get")
|
||||
def test_free_game_has_no_price(self, get):
|
||||
get.return_value = steam_response(881100, {"is_free": True})
|
||||
|
||||
refresh_steam_games()
|
||||
|
||||
self.game.refresh_from_db()
|
||||
self.assertTrue(self.game.steam_is_free)
|
||||
self.assertIsNone(self.game.steam_price_final)
|
||||
|
||||
@mock.patch("games.services.steam_store.httpx.get")
|
||||
def test_failure_keeps_previous_info(self, get):
|
||||
Game.objects.filter(pk=self.game.pk).update(steam_price_final=999)
|
||||
get.side_effect = httpx.ConnectError("down")
|
||||
|
||||
refresh_steam_games()
|
||||
|
||||
self.game.refresh_from_db()
|
||||
self.assertEqual(self.game.steam_price_final, 999)
|
||||
|
||||
|
||||
@override_settings(CACHES=LOCMEM_CACHE)
|
||||
class ScheduleSteamRefreshTests(TestCase):
|
||||
def setUp(self):
|
||||
cache.clear()
|
||||
|
||||
@mock.patch("games.tasks.refresh_steam_games_task")
|
||||
def test_only_one_loop_is_scheduled(self, task):
|
||||
self.assertTrue(schedule_steam_refresh())
|
||||
self.assertFalse(schedule_steam_refresh())
|
||||
task.enqueue.assert_called_once_with()
|
||||
|
||||
@mock.patch("games.tasks.refresh_steam_games")
|
||||
def test_task_reschedules_itself_even_on_failure(self, refresh):
|
||||
refresh.side_effect = RuntimeError("boom")
|
||||
with mock.patch("games.tasks.refresh_steam_games_task") as patched:
|
||||
with self.assertRaises(RuntimeError):
|
||||
refresh_steam_games_task.call()
|
||||
|
||||
patched.using.return_value.enqueue.assert_called_once_with()
|
||||
|
||||
@mock.patch("games.tasks.refresh_steam_games")
|
||||
def test_one_off_run_does_not_reschedule(self, refresh):
|
||||
with mock.patch("games.tasks.refresh_steam_games_task") as patched:
|
||||
refresh_steam_games_task.call(game_ids=[1], reschedule=False)
|
||||
|
||||
refresh.assert_called_once_with([1])
|
||||
patched.using.assert_not_called()
|
||||
|
||||
|
||||
@override_settings(CACHES=LOCMEM_CACHE)
|
||||
class EventSteamGamesApiTests(TestCase):
|
||||
def setUp(self):
|
||||
self.event = Event.objects.create(name="Event", path="event")
|
||||
noita = Game.objects.create(
|
||||
name="Noita", path="noita", steam_app_id=881100, steam_price_final=780
|
||||
)
|
||||
clock = Game.objects.create(name="Clock", path="clock", custom_path=True)
|
||||
EventGame.objects.create(event=self.event, game=noita)
|
||||
EventGame.objects.create(event=self.event, game=clock)
|
||||
user = CustomUser.objects.create_user(username="user", password="x")
|
||||
self.client.force_login(user)
|
||||
|
||||
@mock.patch("games.api.schedule_steam_refresh")
|
||||
def test_lists_only_steam_games_with_store_info(self, schedule):
|
||||
response = self.client.get("/api/events/event/games/steam")
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
[game] = response.json()
|
||||
self.assertEqual(game["name"], "Noita")
|
||||
self.assertEqual(game["price_final"], 780)
|
||||
self.assertEqual(game["store_url"], "https://store.steampowered.com/app/881100")
|
||||
schedule.assert_called_once()
|
||||
|
||||
|
||||
class EventGamesDescriptionTests(TestCase):
|
||||
def setUp(self):
|
||||
self.event = Event.objects.create(name="Event", path="event")
|
||||
self.user = CustomUser.objects.create_user(username="user", password="x")
|
||||
self.client.force_login(self.user)
|
||||
|
||||
def test_steam_description_is_fallback_for_admin_one(self):
|
||||
steam = Game.objects.create(
|
||||
name="Noita",
|
||||
path="noita",
|
||||
steam_app_id=881100,
|
||||
steam_short_description="From Steam",
|
||||
)
|
||||
custom = Game.objects.create(
|
||||
name="Opus",
|
||||
path="opus",
|
||||
steam_app_id=558990,
|
||||
description="From admin",
|
||||
steam_short_description="From Steam",
|
||||
)
|
||||
EventGame.objects.create(event=self.event, game=steam)
|
||||
EventGame.objects.create(event=self.event, game=custom)
|
||||
|
||||
response = self.client.get("/api/events/event/games")
|
||||
|
||||
descriptions = {g["name"]: g["description"] for g in response.json()}
|
||||
self.assertEqual(descriptions, {"Noita": "From Steam", "Opus": "From admin"})
|
||||
Reference in New Issue
Block a user