def test_simple_search_form_quick_filters(self, admin_client): """ Test quick filters result """ ArticleFactory( title='title1', description='description1', published=True ) ArticleFactory( title='title2', description='Dead rabbit is walking without leg.', published=False ) response = admin_client.get(reverse('articles:list'), {'published': 'published'}) list_items = response.context_data['list_items'] assert len(list_items) == 1 assert list_items[0]['fields'][0]['value'] == 'title1' response = admin_client.get(reverse('articles:list'), {'published': 'drafts'}) list_items = response.context_data['list_items'] assert list_items[0]['fields'][0]['value'] == 'title2'
def test_published(): today = timezone.now() ArticleFactory.create(title="first", date=today, publish=True) ArticleFactory.create(title="second", date=today, publish=False) queryset = Article.objects.published() assert queryset.count() == 1 assert queryset.first().title == "first"
def test_foreign_key_contains_operator(): user = UserFactory(first_name="First Name") user2 = UserFactory(first_name="Name") a1 = ArticleFactory(user=user) ArticleFactory(user=user2) filter_obj = ContainsFKFilter(data={"author_first_name": "First"}) result = filter_obj.apply().all() assert len(result) == 1 assert result[0] == a1
def test_m2m_merge_with_audit_trail(self): primary_object = ArticleFactory.create(reporter=None) related_object = ReporterFactory.create() alias_object = ArticleFactory.create(number_of_publications=3, reporter=related_object) related_objects = set(alias_object.publications.all()) _, audit_trail = MergedModelInstance.create_with_audit_trail( primary_object, [alias_object]) assert set(audit_trail) == related_objects
def test_field_classes(self, admin_client): """ Virtual field displayed in ListView """ ArticleFactory(published=True) ArticleFactory(published=False) response = self._request(admin_client) list_items = response.context_data['list_items'] assert list_items[0]['fields'][2]['class'] == 'online' assert list_items[1]['fields'][2]['class'] == 'offline'
def test_field_actions(self, admin_client): ArticleFactory(title='title1', description='description1', published=True) ArticleFactory(title='title2', description='description2', published=False) response = admin_client.get(reverse('articles:list'), {'description': ''}) list_items = response.context_data['list_items'] assert len(list_items[0]['actions']) == 1 assert len(list_items[1]['actions']) == 2
def test_merge_generic_foreign_keys(self): primary_object = ArticleFactory() alias_object = ArticleFactory() primary_object.tags.create(content_object=primary_object, tag='django') alias_object.tags.create(content_object=alias_object, tag='python') merged_object = MergedModelInstance.create(primary_object, [alias_object], keep_old=False) assert merged_object.tags.count() == 2
def test_daily_digest(): ArticleFactory.create_batch(10) subscriptions = SubscriptionFactory.create_batch(10) daily_digest() for subscription in subscriptions: emails = Email.objects.filter(receivers=subscription.email) if subscription.confirmed_at: assert emails.exists() is True else: assert emails.exists() is False
def test_virtual_ordering_field(self, admin_client): """ ordering by 'virtual ordering field' """ ArticleFactory(title='Article 0') ArticleFactory(title='Article 1') response = self._request(admin_client) lst_headers = response.context_data['list_header'] lst_items = response.context_data['list_items'] assert lst_headers[3]['order_url'] == '/articles/?order=category__name' assert lst_headers[3]['order_direction'] == 'desc' assert len(lst_items) == 2 assert lst_items[0]['fields'][0]['value'] == 'Article 1' assert lst_items[1]['fields'][0]['value'] == 'Article 0'
def test_merge_model_with_m2m_relationship(self): primary_object = ArticleFactory.create(reporter=None) related_object = ReporterFactory.create() alias_object = ArticleFactory.create(number_of_publications=3, reporter=related_object) assert primary_object.reporter is None assert primary_object.publications.count() == 0 merged_object = MergedModelInstance.create(primary_object, [alias_object]) assert merged_object.reporter == related_object assert merged_object.publications.count() == 3
def test_import_articles(admin_client): author = AuthorFactory() source = SourceFactory() contents = [] count = 5 for article in ArticleFactory.build_batch(count): contents.append({ "title": article.title, "url": article.url, "date": article.date.isoformat(), }) file = SimpleUploadedFile( "articles.json", json.dumps(contents).encode("utf-8"), content_type="application/json", ) response = admin_client.post( "/admin/lynx/article/import/", data={ "author": author.pk, "source": source.pk, "file": file }, follow=True, ) assert redirects_to(response, "..") assert success_message_shown(response) assert Article.objects.count() == count assert author.articles.count() == count assert source.articles.count() == count
def test_simple_search_form(self, admin_client): """ Test simple search form """ ArticleFactory(title='title1') ArticleFactory(title='title2') # empty search, return all response = admin_client.get(reverse('articles:list'), {'search': ''}) assert len(response.context_data['list_items']) == 2 # search filled, filter content response = admin_client.get(reverse('articles:list'), {'search': 'le1'}) assert len(response.context_data['list_items']) == 1 assert response.context_data['list_items'][0][0]['value'] == 'title1'
def test_site_statistics(): ArticleFactory.create_batch(10, publish=True) site_statistics() recent = dt.date.today() - dt.timedelta(days=28) for source in Source.objects.all(): events = Event.objects.views().for_source(source) articles = source.articles.published() latest_article_date = ( articles.order_by("-date").first().date.strftime("%Y-%m-%d") ) recent_views = events.filter(created_at__date__gte=recent).count() assert source.data["article_count"] == articles.count() assert source.data["latest_article_date"] == latest_article_date assert source.data["recent_views"] == recent_views
def test_advanced_search_form(self, admin_client): """ Test simple search form """ ArticleFactory(title='title1', description='description1') ArticleFactory(title='title2', description='description2') # empty search, return all response = admin_client.get(reverse('articles:list'), {'description': ''}) assert len(response.context_data['list_items']) == 2 # search filled, filter content response = admin_client.get(reverse('articles:list'), {'description': 'tion2'}) list_items = response.context_data['list_items'] assert len(list_items) == 1 assert list_items[0]['fields'][0]['value'] == 'title2'
def test_paginated_items(self, admin_client): """ Paginated List view """ [ArticleFactory() for i in range(10)] response = self._request(admin_client) self._assert_list_items_len(response, 2) assert response.context_data['page_obj'].paginator.num_pages == 5
def test_single_item(self, admin_client): """ Single item in ListView """ article = ArticleFactory() response = self._request(admin_client) self._assert_list_items_len(response, 1) field = response.context_data['list_items'][0][0]['field'] assert response.context_data['list_items'][0][0]['value'] == \ getattr(article, field)
def test_show_articles_action(admin_client): topics = TopicFactory.create_batch(5) selected = choice(topics) ArticleFactory.create_batch(10) url = reverse("admin:lynx_topic_changelist") data = { "post": "yes", "_selected_action": [selected.pk], "action": "show_articles", } response = admin_client.post(url, data, follow=True) request = response.request slugs = selected.slug assert request["PATH_INFO"] == reverse("admin:lynx_article_changelist") assert request["QUERY_STRING"] == f"topics__slug__in={slugs}"
def test_multiple_filters(): user = UserFactory(first_name="First Name") user2 = UserFactory(last_name="Last Name") a1 = ArticleFactory(user=user) a2 = ArticleFactory(user=user2) filter_obj = MultipleFKFilter( data={"author_first_name": "Name", "author_last_name_istarts": "lasT"}, operator=OrOperator, ) result = filter_obj.apply().order_by(User.id.asc()).all() assert len(result) == 2 assert result == [a1, a2] filter_obj = MultipleFKFilter( data={"author_first_name": "Name", "author_last_name_istarts": "Name"}, operator=OrOperator, ) result = filter_obj.apply().order_by(User.id.asc()).all() assert len(result) == 1 assert result == [a1]
def test_for_date(): today = timezone.now() ArticleFactory.create(title="first", date=today - dt.timedelta(days=1)) ArticleFactory.create(title="second", date=today) ArticleFactory.create(title="first", date=today + dt.timedelta(days=1)) queryset = Article.objects.for_date(today) assert queryset.count() == 1 assert queryset.first().title == "second"
def test_digest_for_date(faker): today = timezone.now() ArticleFactory.create(date=today - dt.timedelta(days=1)), ArticleFactory.create(date=today), ArticleFactory.create(date=today + dt.timedelta(days=1)), digest_for_date(today)
def test_virtual_field(self, admin_client): """ Virtual field displayed in ListView """ article = ArticleFactory() view = ArticleListView() view.fields = ['title', 'description', 'published', 'category'] response = self._request(admin_client) self._assert_list_items_len(response, 1) item = response.context_data['list_items'][0] assert item[0]['value'] == article.title assert item[1]['value'] == article.description assert item[3]['value'] == article.category.name
def test_field_actions_allowing(self, admin_client): def get_field_actions(self, obj): action_links = [ ('detail', 'articles:detail', 'fa-edit'), ('categories', 'articles:category-list', 'fa-edit'), ] if not obj.published: action_links.append( ('delete', 'articles:delete', 'fa-trash'), ) return action_links ArticleListView.get_field_actions = get_field_actions ArticleFactory(title='title1', description='description1', published=True) ArticleFactory(title='title2', description='description2', published=False) response = admin_client.get(reverse('articles:list'), {'description': ''}) list_items = response.context_data['list_items'] assert len(list_items[0]['actions']) == 1 assert len(list_items[1]['actions']) == 2
def test_export_csv_file(self, admin_client): """ Test csv file export functional """ for i in range(30): ArticleFactory(title="title{}".format(i), description='description{}'.format(i)) response = admin_client.get(reverse('articles:list'), {'format': 'csv'}) assert response.status_code == 200 assert response._headers['content-type'][1] == 'text/csv' attach_file = 'Articles.csv' assert attach_file in response._headers['content-disposition'][1] # 2 more rows in file: titles and blank line assert len(response._container) == 32
def test_readonly_fields(self, admin_client): article = ArticleFactory() view = ArticleUpdateView # Check with readonly field enabled view.readonly_fields = ['title'] response = admin_client.get(self.get_url(article.pk)) assert response.context_data['form'].fields['title']\ .widget.attrs.get('readonly') # Check with readonly field disabled view.readonly_fields = [] response = admin_client.get(self.get_url(article.pk)) assert not response.context_data['form'].fields['title']\ .widget.attrs.get('readonly')
def test_missing_virtual_field_execution_attribute_error( self, admin_client): """ Error happens on wrong virtual field name """ article = ArticleFactory() view = ArticleListView() view.fields = ['title', 'description', 'published', 'broken'] view.get_broken_field = lambda obj: obj.unknown_field exc = pytest.raises(AttributeError, view.get_field_value, 'broken', article) assert str(exc.value) == \ "'Article' object has no attribute 'unknown_field'", \ exc.value.message
def test_missing_virtual_field(self, admin_client): """ Error happens on wrong virtual field name """ article = ArticleFactory() # noqa view = ArticleListView() view.fields = ['title', 'description', 'published', 'virtual_field'] response = self._request(admin_client) search_virtual_field = False for field in response.context_data['list_items'][0]: if field['type'] == 'field' and 'virtual_field' in field['field']: search_virtual_field = True assert search_virtual_field is False
def test_2_foreign_keys(): user = UserFactory(first_name="First Name", last_name="some last name") user2 = UserFactory(first_name="Name", last_name="test name") a1 = ArticleFactory(user=user) a2 = ArticleFactory(user=user2) filter_obj = Contains2FKFilter(data={"author_first_name": "Name"}) result = filter_obj.apply().all() assert len(result) == 2 assert {result[0], result[1]} == {a1, a2} filter_obj = Contains2FKFilter( data={"author_first_name": "Name", "author_last_name": "some"} ) result = filter_obj.apply().all() assert len(result) == 1 assert result[0] == a1 filter_obj = Contains2FKFilter( data={"author_first_name": "Name", "author_last_name": "test"}, operator=OrOperator, ) result = filter_obj.apply().all() assert len(result) == 2 assert {result[0], result[1]} == {a1, a2}
def test_merge_authors_action(admin_client): authors = AuthorFactory.create_batch(5) article = ArticleFactory(authors=authors) selected = choice(authors) url = reverse("admin:lynx_author_changelist") data = { "post": "yes", "_selected_action": [author.pk for author in authors], "action": "merge_authors", "selected": selected.pk, } admin_client.post(url, data, follow=True) # Merged authors are deleted actual = [author.pk for author in Author.objects.all()] assert actual == [selected.pk] # Merged author are replaced actual = [author.pk for author in article.authors.all()] assert actual == [selected.pk]
def test_merge_topics_action(admin_client): topics = TopicFactory.create_batch(5) article = ArticleFactory(topics=topics) selected = choice(topics) url = reverse("admin:lynx_topic_changelist") data = { "post": "yes", "_selected_action": [topic.pk for topic in topics], "action": "merge_topics", "selected": selected.pk, } admin_client.post(url, data, follow=True) # Merged topics are deleted actual = [topic.pk for topic in Topic.objects.all()] assert actual == [selected.pk] # Merged topics are replaced actual = [topic.pk for topic in article.topics.all()] assert actual == [selected.pk]
def __init__(self): self.object = ArticleFactory() self.form = ArticleForm(instance=self.object) self.get_form = get_form(self.form)