def test_category_index_basic(db, client): """ Category index view should list every category. """ category1 = CategoryFactory(title="category1") category2 = CategoryFactory(title="category2") response = client.get("/") assert response.status_code == 200 dom = html_pyquery(response) items = dom.find(".category-list li") expected_titles = [ "category1", "category2", ] expected_urls = [ "/{category_pk}/".format(category_pk=category1.id), "/{category_pk}/".format(category_pk=category2.id), ] assert expected_titles == [item.find("a").text for item in items] assert expected_urls == [item.find("a").get("href") for item in items]
def test_article_admin_modelchoice_change_labels(db, admin_client): """ Admin change form should have language names in model choices fields. """ # Create new objects CategoryFactory(title="garlic", language="en") CategoryFactory(title="ail", language="fr") ArticleFactory(title="egg", language="en") obj_fr = ArticleFactory(title="baguette", language="fr") ArticleFactory(title="omelette", language="fr") # Build form and get its simple HTML representation to parse it f = ArticleAdminForm({}, instance=obj_fr) content = f.as_p() dom = html_pyquery(content) originals = dom.find("#id_original option") assert [item.text for item in originals] == [ f.fields["original"].empty_label, "egg [English]", ] relateds = dom.find("#id_related option") assert [item.text for item in relateds] == [ "omelette [Français]", ] categories = dom.find("#id_categories option") assert [item.text for item in categories] == [ "ail [Français]", ]
def test_category_admin_original_choices(db, admin_client): """ Choices for 'original' should not list item in same language and not the category itself. """ # Create new object to check obj = CategoryFactory(language="en") # Create some objects in same language CategoryFactory(language="en") CategoryFactory(language="en") # Create some other objects in various other languages, these are the only # elligible categories for original field choices fillers_langs = [ CategoryFactory(language="fr"), CategoryFactory(language="fr"), CategoryFactory(language="de"), ] # Get the obj detail page url = get_admin_change_url(obj) response = admin_client.get(url) assert response.status_code == 200 dom = html_pyquery(response) # Get available choice ids from their values options = dom.find("#id_original option") option_ids = [int(item.get("value")) for item in options if item.get("value")] assert sorted(option_ids) == sorted([item.id for item in fillers_langs])
def test_category_detail_article_pagination(settings, db, client): """ Category index detail has a paginated list of article and so not every category articles are listed on the same page. """ category1 = CategoryFactory(title="category1") category_url = "/{category_pk}/".format(category_pk=category1.id) article_total = (settings.ARTICLE_PAGINATION * 2) + 1 ArticleFactory.create_batch(article_total, category=category1) assert article_total == Article.objects.all().count() # First result page response = client.get(category_url) assert response.status_code == 200 dom = html_pyquery(response) items = dom.find(".article-list li") assert settings.ARTICLE_PAGINATION == len(items) # Check pagination is correct pages = dom.find(".pagination a") assert 3 == len(pages) # Second result page response = client.get(category_url + "?page=2") assert response.status_code == 200 dom = html_pyquery(response) items = dom.find(".article-list li") assert settings.ARTICLE_PAGINATION == len(items) # Check current page is correct active = dom.find(".pagination a.active") assert 1 == len(active) assert "2" == active.text() # Third result page response = client.get(category_url + "?page=3") assert response.status_code == 200 dom = html_pyquery(response) items = dom.find(".article-list li") assert 1 == len(items)
def test_category_index_pagination(settings, db, client): """ Category index view is paginated from setting limit, not every category is listed on the same page. """ # Twice the category pagination limit plus one entry so we can expect three # result pages category_total = (settings.BLOG_PAGINATION * 2) + 1 CategoryFactory.create_batch(category_total) assert category_total == Category.objects.all().count() # First result page response = client.get("/") assert response.status_code == 200 dom = html_pyquery(response) items = dom.find(".category-list li") assert settings.BLOG_PAGINATION == len(items) # Check pagination is correct pages = dom.find(".pagination a") assert 3 == len(pages) # Second result page response = client.get("/?page=2") assert response.status_code == 200 dom = html_pyquery(response) items = dom.find(".category-list li") assert settings.BLOG_PAGINATION == len(items) # Check current page is correct active = dom.find(".pagination a.active") assert 1 == len(active) assert "2" == active.text() # Third result page response = client.get("/?page=3") assert response.status_code == 200 dom = html_pyquery(response) items = dom.find(".category-list li") assert 1 == len(items)
def test_article_admin_original_choices(db, admin_client): """ Choices should be limited to some constraints: * 'original' field should not list items in same language and not the article itself; * 'related' field should not list items in different language and not the article itself; * 'categories' field should not list items in different language; """ # Create new object to check obj = ArticleFactory(language="en") # Create some objects in same language fillers_en = [ ArticleFactory(language="en"), ArticleFactory(language="en"), ] # Create some other objects in various other languages, these are the only # elligible articles for original field choices fillers_langs = [ ArticleFactory(language="fr"), ArticleFactory(language="fr"), ArticleFactory(language="de"), ] # Create some categories cat_en = CategoryFactory(language="en") CategoryFactory(language="fr") # Get the obj detail page url = get_admin_change_url(obj) response = admin_client.get(url) assert response.status_code == 200 dom = html_pyquery(response) # Get available 'original' choice ids from their values options = dom.find("#id_original option") option_ids = [ int(item.get("value")) for item in options if item.get("value") ] assert sorted(option_ids) == sorted([item.id for item in fillers_langs]) # Get available 'related' choice ids from their values options = dom.find("#id_related option") option_ids = [ int(item.get("value")) for item in options if item.get("value") ] assert sorted(option_ids) == sorted([item.id for item in fillers_en]) # Get available 'categories' choice ids from their values options = dom.find("#id_categories option") option_ids = [cat_en.id]
def test_article_view_detail_content(db, admin_client): """ Detail view should contain all expected content and relations. Note we are requesting with admin mode to be able to see a draft article to check for the "draft" CSS class. Also, this does not care about textual content (title, lead, content, etc..). """ picsou = AuthorFactory(first_name="Picsou", last_name="McDuck") AuthorFactory(first_name="Flairsou", last_name="Cresus") cat_1 = CategoryFactory(title="cat_1") CategoryFactory(title="cat_2") CategoryFactory(title="cat_3") ArticleFactory(title="Foo") article_2 = ArticleFactory(title="Bar") article_3 = ArticleFactory( title="Ping", fill_categories=[cat_1], fill_related=[article_2], fill_authors=[picsou], status=STATUS_DRAFT, pinned=True, featured=True, private=True, ) # Get detail HTML page response = admin_client.get(article_3.get_absolute_url(), {'admin': 1}) assert response.status_code == 200 # Parse HTML response to get content and relations dom = html_pyquery(response) container = dom.find("#lotus-content .article-detail")[0] categories = [ item.text for item in dom.find("#lotus-content .categories li a") ] authors = [item.text for item in dom.find("#lotus-content .authors li")] relateds = [ item.text for item in dom.find("#lotus-content .relateds li a") ] cover = dom.find("#lotus-content .cover img")[0].get("src") large_img = dom.find("#lotus-content .image img")[0].get("src") classes = sorted( [v for v in container.get("class").split() if v != "article-detail"]) assert categories == ["cat_1"] assert authors == ["Picsou McDuck"] assert relateds == ["Bar"] assert classes == ["draft", "featured", "pinned", "private"] assert cover == article_3.cover.url assert large_img == article_3.image.url
def test_category_index_empty(db, client): """ Without any existing category, index view should just return the empty text. """ response = client.get("/") assert response.status_code == 200 dom = html_pyquery(response) content = dom.find(".category-list li")[0].text assert "No categorys yet." == content
def test_category_admin_modelchoice_create_labels(db, admin_client): """ Admin create form should have language names in model choices fields. """ # Create new objects CategoryFactory(title="egg", language="en") CategoryFactory(title="baguette", language="fr") # Build form and get its simple HTML representation to parse it f = CategoryAdminForm() content = f.as_p() dom = html_pyquery(content) originals = dom.find("#id_original option") assert [item.text for item in originals] == [ f.fields["original"].empty_label, "baguette [Français]", "egg [English]", ]
def test_category_detail_no_article(db, client): """ Without any related article, category detail view should just contains its content and return the empty text for article list. """ category1 = CategoryFactory(title="category1") url = "/{category_pk}/".format(category_pk=category1.id) response = client.get(url) assert response.status_code == 200 dom = html_pyquery(response) category_title = dom.find(".category-detail h2") assert category_title.text() == category1.title content = dom.find(".article-list li")[0].text assert "No articles yet." == content
def test_article_detail_content(db, client): """ Article content should be displayed correctly. """ article = ArticleFactory() url = "/{article_pk}/".format(article_pk=article.id, ) response = client.get(url) assert response.status_code == 200 dom = html_pyquery(response) article_title = dom.find(".article-detail h2") article_content = dom.find(".article-detail div.content") assert article_title.text() == article.title # Avoid text() method to remove white spaces since content may contain some # line breaks assert article_content.text(squash_space=False) == article.content
def test_article_view_list_publication(db, admin_client, client, user_kind, client_kwargs, expected): """ View list should respect publication criterias (dates and state, private article and order. Tested again profiles: * non authenticated; * non authenticated trying to user admin mode; * authenticated user lambda; * authenticated user lambda trying to user admin mode; * admin without admin mode; * admin with admin mode; """ # Available Django clients as a dict to be able to switch on client_for = { "anonymous": client, "user": client, "admin": admin_client, } # Date references now = timezone.now() yesterday = now - datetime.timedelta(days=1) past_hour = now - datetime.timedelta(hours=1) tomorrow = now + datetime.timedelta(days=1) next_hour = now + datetime.timedelta(hours=1) # Create 10 articles (according to pagination limit) with different publication # parameters # Numerate titles to enforce ordering since articles share the exact same datetimes # which would lead to arbitrary order from a session to another ArticleFactory( title="01. draft yesterday", publish_date=yesterday.date(), publish_time=yesterday.time(), status=STATUS_DRAFT, ) ArticleFactory( title="02. published yesterday", publish_date=yesterday.date(), publish_time=yesterday.time(), ) ArticleFactory( title="03. published yesterday, ended one hour ago", publish_date=yesterday.date(), publish_time=yesterday.time(), publish_end=past_hour, ) ArticleFactory( title="04. published past hour", publish_date=past_hour.date(), publish_time=past_hour.time(), ) ArticleFactory( title="05. pinned, published past hour", publish_date=past_hour.date(), publish_time=past_hour.time(), pinned=True, ) ArticleFactory( title="06. featured, published past hour", publish_date=past_hour.date(), publish_time=past_hour.time(), featured=True, ) ArticleFactory( title="07. private, published past hour", publish_date=past_hour.date(), publish_time=past_hour.time(), private=True, ) ArticleFactory( title="08. published past hour, end next hour", publish_date=past_hour.date(), publish_time=past_hour.time(), publish_end=next_hour, ) ArticleFactory( title="09. publish next hour", publish_date=next_hour.date(), publish_time=next_hour.time(), ) ArticleFactory( title="10. publish next hour, end tomorrow", publish_date=next_hour.date(), publish_time=next_hour.time(), publish_end=tomorrow, ) # Select the right client to use for user kind enabled_client = client_for[user_kind] # We have to force authenticated user (non admin) if user_kind == "user": user = AuthorFactory() client.force_login(user) # Get all available items from HTML page urlname = "lotus:article-index" response = enabled_client.get(reverse(urlname), client_kwargs) assert response.status_code == 200 # Parse HTML dom = html_pyquery(response) items = dom.find("#lotus-content .article-list-container .list .item") # Get useful content from list items content = [] for item in items: title = item.cssselect("h3 > a")[0].text # Drop item class since it's useless for test classes = [v for v in item.get("class").split() if v != "item"] content.append([title, classes]) assert content == expected