diff --git a/backend/utils/achievements.py b/backend/utils/achievements.py index b80e02b..e0a2e7a 100644 --- a/backend/utils/achievements.py +++ b/backend/utils/achievements.py @@ -135,15 +135,18 @@ def _update_database(self): """Обновляем БД по списку новых ачивок. Логика следующая: - для одноразовых ачивок создается запись в UserAchievement - - для многоразовых ачивок если записи нет, создается, если есть, обновляется дата""" + - для многоразовых ачивок если записи нет, создается, если есть, пересоздается.""" if not self._new_achievements: return user_achievements = [ UserAchievement(user_id=self._user, achievement_id=achievement) for achievement in self._new_achievements ] + achievements = [ua.achievement_id for ua in user_achievements] with transaction.atomic(): - UserAchievement.objects.filter(user_id=self._user).exclude(achievement_id__recurring=False).delete() + UserAchievement.objects.filter(user_id=self._user, achievement_id__in=achievements).exclude( + achievement_id__recurring=False + ).delete() UserAchievement.objects.bulk_create(user_achievements) def _check_for_new_backend_achievements(self): diff --git a/test/api_tests/history_tests.py b/test/api_tests/history_tests.py index bfa338c..acfcea7 100644 --- a/test/api_tests/history_tests.py +++ b/test/api_tests/history_tests.py @@ -11,6 +11,13 @@ url = reverse("history") +def achievement_title_in_response(response: list[dict], title: str): + for achievement in response: + if title in achievement["title"]: + return True + return False + + @pytest.fixture def training_end_data(): return { @@ -86,3 +93,35 @@ def test_recurring_non_ios_achievement_is_not_duplicated( training_end_data["training_end"] = add_1_day_to_str(training_end_data["training_end"]) assert response.status_code == status.HTTP_201_CREATED assert user_achievement_count_by_id(user, 21) == 1 + + +@pytest.mark.django_db +def test_recurring_non_ios_achievement_does_not_delete_old_recurring_ios( + user, user_client, load_achievement_fixtures, training_end_data +): + achievements = (21, 22, 26) # Турист, Путешественник, Афтердарк + for a in achievements: + assert user_achievement_count_by_id(user, a) == 0 + + training_end_data["achievements"] = [26] + training_end_data["cities"] = ["1", "2", "3", "4"] + response = user_client.post(url, training_end_data, format="json").data + + assert achievement_title_in_response(response, "Путешественник") + assert achievement_title_in_response(response, "Афтердарк") + assert user_achievement_count_by_id(user, 26) == 1 + assert user_achievement_count_by_id(user, 22) == 1 + assert user_achievement_count_by_id(user, 21) == 0 + + training_end_data["training_start"] = add_1_day_to_str(training_end_data["training_start"]) + training_end_data["training_end"] = add_1_day_to_str(training_end_data["training_end"]) + training_end_data["training_day"] += 1 + training_end_data["cities"] = ["5"] + response = user_client.post(url, training_end_data, format="json").data + + assert achievement_title_in_response(response, "Афтердарк") + assert achievement_title_in_response(response, "Турист") + assert not achievement_title_in_response(response, "Путешественник") + + for a in achievements: + assert user_achievement_count_by_id(user, a) == 1