diff --git a/pokemon_v2/serializers.py b/pokemon_v2/serializers.py index fb85c66cb..b59679826 100644 --- a/pokemon_v2/serializers.py +++ b/pokemon_v2/serializers.py @@ -2933,10 +2933,30 @@ class Meta: "past_types", ) + _FEMALE_FALLBACKS: ClassVar[dict[str, str]] = { + "front_female": "front_default", + "back_female": "back_default", + "front_shiny_female": "front_shiny", + "back_shiny_female": "back_shiny", + } + @extend_schema_field(PokemonSpritesSerializer) - def get_pokemon_sprites(self, obj: Pokemon) -> dict[str, str | None]: + def get_pokemon_sprites(self, obj: Pokemon) -> dict[str, Any]: sprites_list = list(cast("PokemonWithRelations", obj).pokemonsprites.all()) - return sprites_list[0].sprites if sprites_list else {} + if not sprites_list: + return {} + sprites = sprites_list[0].sprites + if obj.pokemon_species and obj.pokemon_species.gender_rate == 8: + self._fill_female_sprites(sprites) + return sprites + + def _fill_female_sprites(self, sprites: dict[str, Any]) -> None: + for female_key, default_key in self._FEMALE_FALLBACKS.items(): + if female_key in sprites and sprites[female_key] is None and sprites.get(default_key) is not None: + sprites[female_key] = sprites[default_key] + for value in sprites.values(): + if isinstance(value, dict): + self._fill_female_sprites(value) @extend_schema_field(PokemonCriesSerializer) def get_pokemon_cries(self, obj: Pokemon) -> dict[str, str | None]: diff --git a/pokemon_v2/tests.py b/pokemon_v2/tests.py index 80e4c4903..49cc7545b 100644 --- a/pokemon_v2/tests.py +++ b/pokemon_v2/tests.py @@ -1631,7 +1631,7 @@ def setup_pokemon_sprites_data( pokemon_sprites = PokemonSprites.objects.create( pokemon=pokemon, - sprites=json.dumps(sprites | {"other": {"showdown": showdown}}), + sprites=sprites | {"other": {"showdown": showdown}}, ) pokemon_sprites.save() @@ -4523,9 +4523,9 @@ def test_pokemon_api(self): "{}{}/pokemon-form/{}/".format(TEST_HOST, API_V2, pokemon_form.pk), ) - sprites_data = json.loads(pokemon_sprites.sprites) + sprites_data = pokemon_sprites.sprites cries_data = json.loads(pokemon_cries.cries) - response_sprites_data = json.loads(response.data["sprites"]) + response_sprites_data = response.data["sprites"] json.loads(response.data["cries"]) # sprite params @@ -4649,6 +4649,26 @@ def test_pokemon_moves_version_group_details_are_deterministically_ordered(self) [1, 2, 3], ) + def test_pokemon_api_female_only_sprites_fallback(self): + pokemon_species = self.setup_pokemon_species_data(name="female only pkmn spcs", gender_rate=8) + pokemon = self.setup_pokemon_data(pokemon_species=pokemon_species, name="female only pkmn") + self.setup_pokemon_form_data(pokemon=pokemon, name="female only pkmn form") + self.setup_pokemon_sprites_data(pokemon=pokemon, front_default=True, front_female=False) + self.setup_pokemon_cries_data(pokemon, latest=True, legacy=True) + + response = self.client.get("{}/pokemon/{}/".format(API_V2, pokemon.pk), headers={"host": "testserver"}) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + + response_sprites = response.data["sprites"] + + self.assertIsNotNone(response_sprites["front_default"]) + self.assertEqual(response_sprites["front_female"], response_sprites["front_default"]) + self.assertEqual( + response_sprites["other"]["showdown"]["front_female"], + response_sprites["other"]["showdown"]["front_default"], + ) + def test_pokemon_form_api(self): pokemon_species = self.setup_pokemon_species_data() pokemon = self.setup_pokemon_data(pokemon_species=pokemon_species)