|
1 | 1 | from pytest_django.asserts import assertQuerySetEqual as assert_queryset_equal |
| 2 | +from pytest_django.fixtures import DjangoAssertNumQueries |
2 | 3 |
|
3 | 4 | from environments.dynamodb.migrator import IdentityMigrator |
4 | 5 | from environments.dynamodb.types import ( |
5 | 6 | DynamoProjectMetadata, |
6 | 7 | ProjectIdentityMigrationStatus, |
7 | 8 | ) |
8 | 9 | from environments.identities.models import Identity |
| 10 | +from environments.identities.traits.models import Trait |
9 | 11 | from environments.models import Environment, EnvironmentAPIKey |
| 12 | +from projects.models import Project |
10 | 13 |
|
11 | 14 |
|
12 | 15 | def test_migrate_calls_internal_methods_with_correct_arguments( # type: ignore[no-untyped-def] |
@@ -48,7 +51,7 @@ def test_migrate_calls_internal_methods_with_correct_arguments( # type: ignore[ |
48 | 51 | assert kwargs == {} |
49 | 52 |
|
50 | 53 | assert_queryset_equal( |
51 | | - args[0], Identity.objects.filter(environment__project__id=project.id) |
| 54 | + list(args[0]), Identity.objects.filter(environment__project__id=project.id) |
52 | 55 | ) |
53 | 56 | # and |
54 | 57 | args, kwargs = mocked_environment_wrapper.return_value.write_environments.call_args |
@@ -168,3 +171,70 @@ def test_get_migration_status_returns_correct_migraion_status_for_in_progress_mi |
168 | 171 | # Then |
169 | 172 | assert status == ProjectIdentityMigrationStatus.MIGRATION_IN_PROGRESS |
170 | 173 | mocked_project_metadata.get_or_new.assert_called_with(project_id) |
| 174 | + |
| 175 | + |
| 176 | +def test_iter_identities_in_chunks__multiple_chunks__yields_all_in_pk_order( |
| 177 | + project: Project, |
| 178 | + environment: Environment, |
| 179 | +) -> None: |
| 180 | + # Given |
| 181 | + identities = [ |
| 182 | + Identity.objects.create(identifier=f"identity_{i}", environment=environment) |
| 183 | + for i in range(5) |
| 184 | + ] |
| 185 | + for identity in identities: |
| 186 | + Trait.objects.create( |
| 187 | + identity=identity, |
| 188 | + trait_key="key", |
| 189 | + value_type="unicode", |
| 190 | + string_value="val", |
| 191 | + ) |
| 192 | + |
| 193 | + # When |
| 194 | + result = list(IdentityMigrator.iter_identities_in_chunks(project.id, chunk_size=2)) |
| 195 | + |
| 196 | + # Then |
| 197 | + expected_pks = sorted(i.pk for i in identities) |
| 198 | + assert [i.pk for i in result] == expected_pks |
| 199 | + assert len(result) == 5 |
| 200 | + |
| 201 | + |
| 202 | +def test_iter_identities_in_chunks__preserves_prefetch_related( |
| 203 | + project: Project, |
| 204 | + environment: Environment, |
| 205 | + django_assert_num_queries: DjangoAssertNumQueries, |
| 206 | +) -> None: |
| 207 | + # Given |
| 208 | + identities = [ |
| 209 | + Identity.objects.create(identifier=f"identity_{i}", environment=environment) |
| 210 | + for i in range(3) |
| 211 | + ] |
| 212 | + for identity in identities: |
| 213 | + Trait.objects.create( |
| 214 | + identity=identity, |
| 215 | + trait_key="key", |
| 216 | + value_type="unicode", |
| 217 | + string_value="val", |
| 218 | + ) |
| 219 | + |
| 220 | + result = list(IdentityMigrator.iter_identities_in_chunks(project.id)) |
| 221 | + |
| 222 | + # When — accessing prefetched relations should cause no additional queries. |
| 223 | + with django_assert_num_queries(0): |
| 224 | + for identity in result: |
| 225 | + list(identity.identity_traits.all()) |
| 226 | + |
| 227 | + |
| 228 | +def test_iter_identities_in_chunks__empty_queryset__yields_nothing( |
| 229 | + project: Project, |
| 230 | + environment: Environment, |
| 231 | + django_assert_num_queries: DjangoAssertNumQueries, |
| 232 | +) -> None: |
| 233 | + # Given — no identities created. |
| 234 | + |
| 235 | + # When |
| 236 | + with django_assert_num_queries(1): |
| 237 | + result = list(IdentityMigrator.iter_identities_in_chunks(project.id)) |
| 238 | + |
| 239 | + # Then |
| 240 | + assert result == [] |
0 commit comments