def test_many_to_many_fields_not_supported(self, migration_apps): """ Test that if an item in the yaml includes a many-to-many field, the function raises NotImplementedError as this is not supported yet. """ yaml_content = """ - model: datahub.core.test.support.book pk: 1 fields: name: name authors: - 1 - 2 published_on: '2010-01-01' """ mocked_read = mock.mock_open(read_data=yaml_content) PersonFactory.create_batch(2, pk=factory.Iterator([1, 2])) with pytest.raises(NotImplementedError) as excinfo: with mock.patch('datahub.core.migration_utils.open', mocked_read, create=True): load_yaml_data_in_migration(migration_apps, 'path-to-file.yaml') assert str(excinfo.value) == 'Many-to-many fields not supported'
def test_aggregates_as_array(self, names, distinct): """ Test that the first names of all authors for each book can be aggregated into an array for various cases, and with distinct on and off. """ authors = PersonFactory.create_batch( len(names), first_name=factory.Iterator( sample(names, len(names)), ), ) BookFactory(authors=authors) queryset = Book.objects.annotate( author_names=get_array_agg_subquery( Book.authors.through, 'book', 'person__first_name', distinct=distinct, ), ) actual_author_names = queryset.first().author_names if distinct: assert Counter(actual_author_names) == Counter(set(names)) else: assert Counter(actual_author_names) == Counter(names)
def test_get_string_agg_subquery(num_authors): """ Test that get_string_agg_subquery() can be used to concatenate the first names of all authors for each book into one field. """ authors = PersonFactory.create_batch(num_authors) BookFactory(authors=authors) queryset = Book.objects.annotate(author_names=get_string_agg_subquery( Book, 'authors__first_name'), ) author_names_str = queryset.first().author_names actual_author_names = sorted( author_names_str.split(', ')) if author_names_str else [] expected_author_names = sorted(author.first_name for author in authors) assert actual_author_names == expected_author_names
def test_can_annotate_queryset(self, names, distinct, expected_result): """ Test that the first names of all authors for each book can be concatenated into one field as a query set annotation for various cases. """ authors = PersonFactory.create_batch( len(names), first_name=factory.Iterator( sample(names, len(names)), ), ) BookFactory(authors=authors) queryset = Book.objects.annotate( author_names=get_string_agg_subquery(Book, 'authors__first_name', distinct=distinct), ) actual_author_names = queryset.first().author_names assert actual_author_names == expected_result
def test_orders_results_when_ordering_specified(self, ordering, expected_names): """Test that the values are ordered corrected when an ordering is specified.""" names = ['Barbara', 'Claire', 'Samantha'] authors = PersonFactory.create_batch( len(names), first_name=factory.Iterator(sample(names, len(names)), ), ) BookFactory(authors=authors) queryset = Book.objects.annotate(author_names=get_array_agg_subquery( Book.authors.through, 'book', 'person__first_name', ordering=ordering, ), ) actual_author_names = queryset.first().author_names assert actual_author_names == expected_names
def test_aggregates_as_filtered_array(self, names, desired_names): """ Test that the desired first names of authors for each book can be aggregated into an array for various cases. """ authors = PersonFactory.create_batch( len(names), first_name=factory.Iterator(sample(names, len(names)), ), ) BookFactory(authors=authors) queryset = Book.objects.annotate(author_names=get_array_agg_subquery( Book.authors.through, 'book', 'person__first_name', filter=Q(person__first_name__in=desired_names), ), ) actual_author_names = queryset.first() assert set(actual_author_names.author_names) == set(desired_names)
def test_loading(self, migration_apps): """ Test that loading a yaml file updates the existing data. """ yaml_content = """ # person with pk=1, last_name should change - model: datahub.core.test.support.person pk: 1 fields: first_name: Existing last_name: Person with changed surname # person with pk=3, first_name should change, last_name shouldn't change - model: datahub.core.test.support.person pk: 3 fields: first_name: Another existing # person with pk=10, a new record should be created - model: datahub.core.test.support.person pk: 10 fields: first_name: New last_name: Person # book with pk=1, fk to person (proofreader) should change - model: datahub.core.test.support.book pk: 1 fields: name: Book name proofreader: 3 published_on: '2010-01-01' """ mocked_read = mock.mock_open(read_data=yaml_content) people = PersonFactory.create_batch( 3, pk=factory.Iterator([1, 2, 3]), first_name='Existing', last_name='Person', ) BookFactory( pk=1, name='Previous book name', proofreader=people[0], published_on=datetime.date(2010, 1, 1), authors=[], ) with mock.patch('datahub.core.migration_utils.open', mocked_read, create=True): load_yaml_data_in_migration(migration_apps, 'path-to-file.yaml') qs = Person.objects.order_by('id').values('id', 'first_name', 'last_name') assert list(qs) == [ {'id': 1, 'first_name': 'Existing', 'last_name': 'Person with changed surname'}, {'id': 2, 'first_name': 'Existing', 'last_name': 'Person'}, {'id': 3, 'first_name': 'Another existing', 'last_name': 'Person'}, {'id': 10, 'first_name': 'New', 'last_name': 'Person'}, ] qs = Book.objects.order_by('id').values('id', 'name', 'proofreader', 'published_on') assert list(qs) == [ { 'id': 1, 'name': 'Book name', 'proofreader': 3, 'published_on': datetime.date(2010, 1, 1), }, ]