Fix game data not updating

This commit is contained in:
Joakim Hellsén 2026-01-06 23:31:24 +01:00
commit 146b3332f4
No known key found for this signature in database
2 changed files with 91 additions and 9 deletions

View file

@ -446,22 +446,45 @@ class Command(BaseCommand):
if game_data.twitch_id in self.game_cache:
game_obj: Game = self.game_cache[game_data.twitch_id]
# Maintenance: Ensure the existing game is linked to the
# correct owner (Sometimes games are imported without owner
# data first). Use owner_id to avoid triggering a query.
# Correct stale owner linkage that may exist from earlier
# partial imports.
if game_obj.owner_id != org_obj.pk: # type: ignore[attr-defined] # Django adds _id suffix for FK fields
update_fields: list[str] = []
# Ensure owner is correct without triggering a read
if game_obj.owner_id != org_obj.pk: # type: ignore[attr-defined]
game_obj.owner = org_obj
game_obj.save(update_fields=["owner"])
update_fields.append("owner")
# Persist normalized display name when provided
if game_data.display_name and game_obj.display_name != game_data.display_name:
game_obj.display_name = game_data.display_name
update_fields.append("display_name")
# Persist canonical name when provided (Inventory format)
if game_data.name and game_obj.name != game_data.name:
game_obj.name = game_data.name
update_fields.append("name")
# Persist slug when provided by API (Inventory and DropCampaignDetails)
if game_data.slug is not None and game_obj.slug != (game_data.slug or ""):
game_obj.slug = game_data.slug or ""
update_fields.append("slug")
# Persist box art URL when provided
if game_data.box_art_url is not None and game_obj.box_art != (game_data.box_art_url or ""):
game_obj.box_art = game_data.box_art_url or ""
update_fields.append("box_art")
if update_fields:
game_obj.save(update_fields=update_fields)
return game_obj
game_obj, created = Game.objects.update_or_create(
twitch_id=game_data.twitch_id,
defaults={
"display_name": game_data.display_name,
"box_art": game_data.box_art_url,
"display_name": game_data.display_name or (game_data.name or ""),
"name": game_data.name or "",
"slug": game_data.slug or "",
"box_art": game_data.box_art_url or "",
"owner": org_obj,
},
)

View file

@ -8,6 +8,7 @@ from django.test import TestCase
from twitch.management.commands.better_import_drops import Command
from twitch.models import Channel
from twitch.models import DropCampaign
from twitch.models import Game
from twitch.schemas import DropBenefitSchema
if TYPE_CHECKING:
@ -481,3 +482,61 @@ class OperationNameFilteringTests(TestCase):
# Cross-check: Inventory campaign should not be in viewer campaigns
assert not viewer_campaigns.filter(twitch_id="inventory-campaign-1").exists()
assert not inventory_campaigns.filter(twitch_id="viewer-campaign-1").exists()
class GameImportTests(TestCase):
"""Tests for importing and persisting Game fields from campaign data."""
def test_imports_game_slug_from_campaign(self) -> None:
"""Ensure Game.slug is imported from DropCampaign game data when provided."""
command = Command()
command.pre_fill_cache()
payload: dict[str, object] = {
"data": {
"user": {
"id": "17658559",
"dropCampaign": {
"id": "campaign-with-slug",
"name": "Slug Campaign",
"description": "",
"startAt": "2025-01-01T00:00:00Z",
"endAt": "2025-12-31T23:59:59Z",
"accountLinkURL": "https://example.com/link",
"detailsURL": "https://example.com/details",
"imageURL": "",
"status": "ACTIVE",
"self": {"isAccountConnected": True, "__typename": "DropCampaignSelfEdge"},
"game": {
"id": "497057",
"slug": "destiny-2",
"displayName": "Destiny 2",
"boxArtURL": "https://example.com/boxart.png",
"__typename": "Game",
},
"owner": {
"id": "bungie-org",
"name": "Bungie",
"__typename": "Organization",
},
"timeBasedDrops": [],
"__typename": "DropCampaign",
},
"__typename": "User",
},
},
"extensions": {"operationName": "DropCampaignDetails"},
}
success, broken_dir = command.process_responses(
responses=[payload],
file_path=Path("slug.json"),
options={},
)
assert success is True
assert broken_dir is None
game = Game.objects.get(twitch_id="497057")
assert game.slug == "destiny-2"
assert game.display_name == "Destiny 2"