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: if game_data.twitch_id in self.game_cache:
game_obj: Game = self.game_cache[game_data.twitch_id] game_obj: Game = self.game_cache[game_data.twitch_id]
# Maintenance: Ensure the existing game is linked to the update_fields: list[str] = []
# correct owner (Sometimes games are imported without owner
# data first). Use owner_id to avoid triggering a query. # Ensure owner is correct without triggering a read
# Correct stale owner linkage that may exist from earlier if game_obj.owner_id != org_obj.pk: # type: ignore[attr-defined]
# partial imports.
if game_obj.owner_id != org_obj.pk: # type: ignore[attr-defined] # Django adds _id suffix for FK fields
game_obj.owner = org_obj 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 return game_obj
game_obj, created = Game.objects.update_or_create( game_obj, created = Game.objects.update_or_create(
twitch_id=game_data.twitch_id, twitch_id=game_data.twitch_id,
defaults={ defaults={
"display_name": game_data.display_name, "display_name": game_data.display_name or (game_data.name or ""),
"box_art": game_data.box_art_url, "name": game_data.name or "",
"slug": game_data.slug or "",
"box_art": game_data.box_art_url or "",
"owner": org_obj, "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.management.commands.better_import_drops import Command
from twitch.models import Channel from twitch.models import Channel
from twitch.models import DropCampaign from twitch.models import DropCampaign
from twitch.models import Game
from twitch.schemas import DropBenefitSchema from twitch.schemas import DropBenefitSchema
if TYPE_CHECKING: if TYPE_CHECKING:
@ -481,3 +482,61 @@ class OperationNameFilteringTests(TestCase):
# Cross-check: Inventory campaign should not be in viewer campaigns # Cross-check: Inventory campaign should not be in viewer campaigns
assert not viewer_campaigns.filter(twitch_id="inventory-campaign-1").exists() assert not viewer_campaigns.filter(twitch_id="inventory-campaign-1").exists()
assert not inventory_campaigns.filter(twitch_id="viewer-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"