# -*- coding: utf-8 -*- from __future__ import unicode_literals from copy import copy from django.contrib.auth.models import Permission from django.test import TestCase, Client from django.core.paginator import EmptyPage from bs4 import BeautifulSoup from utils import create_tests_data, delete_tests_data from newsbox.urls import get_urls from .models import News, NewsSEO, NewsExpired, NewsComplete, NewsExtended class NewsboxAutoURLsBaseTests(object): def setUp(self): self.current_app_name = self.__module__.split('.')[0] super(NewsboxAutoURLsBaseTests, self).setUp() def test_01_auto_urls(self): expected_model_names = copy(self.expected_model_names) urls = get_urls() self.assertEqual(len(urls), len(expected_model_names)) for master_url in urls: self.assertTrue(hasattr(master_url, 'url_patterns')) self.assertEqual(master_url.namespace, self.current_app_name) # 5 urls : archive, year, month, day, detail self.assertEqual(len(master_url.url_patterns), 5) current_model_name = None nb_list = nb_detail = 0 for url in master_url.url_patterns: model_name, action_name = url.name.split('_', ) if not current_model_name: current_model_name = model_name self.assertTrue(current_model_name in expected_model_names) expected_model_names.remove(current_model_name) else: # all suburls must be for the same model self.assertEqual(current_model_name, model_name) self.assertTrue(action_name in ('list', 'detail')) if action_name == 'list': nb_list += 1 else: nb_detail += 1 self.assertEqual(nb_detail, 1) # only one detail url self.assertEqual(nb_list, 4) # 4 list urls : archive, year, month, day class NewsboxAutoURLsTests(NewsboxAutoURLsBaseTests, TestCase): def setUp(self): self.expected_model_names = [News._meta.model_name, NewsSEO._meta.model_name, NewsExpired._meta.model_name, NewsComplete._meta.model_name, NewsExtended._meta.model_name] super(NewsboxAutoURLsTests, self).setUp() class NewsboxModelsTests(TestCase): def setUp(self): create_tests_data('myapp') def tearDown(self): delete_tests_data('myapp') # fixtures = ['tests_data.json', ] def has_readmore_link(self, news): return bool(news.find('a', class_='readmore')) def get_news_in_list_by_summary(self, response, summary): soup = BeautifulSoup(response.content, "html.parser") for news in soup.find_all('article'): readmore_summary = news.find('p', text=summary) if readmore_summary: return news return None def test_01_manager_published(self): """ Test if we only get really published news via the manager """ newsClasses = [News, NewsSEO, NewsExpired, NewsComplete, NewsExtended, ] for cls in newsClasses: returned_ids = list(cls.objects.published().values_list( 'id', flat=True).order_by('id')) self.assertEqual((cls.__name__, returned_ids), (cls.__name__, [1, 4, 6, 7, ])) def test_02_view_archive_200(self): """ Test if generic archive view return right informations. """ c = Client() r = c.get('/myapp/news/') self.assertEqual(r.status_code, 200) self.assertIn('object_list', r.context) self.assertEqual(len(r.context['object_list']), 1) self.assertEqual(r.context['page_obj'].number, 1) self.assertEqual(r.context['paginator'].num_pages, 4) self.assertFalse(r.context['page_obj'].has_previous()) self.assertTrue(r.context['page_obj'].has_next()) with self.assertRaises(EmptyPage): r.context['page_obj'].previous_page_number() self.assertEqual(r.context['page_obj'].next_page_number(), 2) def test_03_view_year_archive_200(self): """ Test if generic year views return right informations. """ c = Client() r = c.get('/myapp/news/2005/') self.assertEqual(r.status_code, 200) self.assertEqual(r.context['object_list'][0].pk, 6) self.assertFalse(r.context['is_paginated']) r = c.get('/myapp/news/2014/') self.assertEqual(r.status_code, 200) self.assertEqual(r.context['paginator'].num_pages, 3) r = c.get('/myapp/news/2020/') self.assertEqual(r.status_code, 404) def test_04_view_year_archive_404(self): """ Test if generic year views return a 404 with an URL with a year without any news. """ c = Client() r = c.get('/myapp/news/1984/') self.assertEqual(r.status_code, 404) def test_05_view_month_archive_200(self): """ Test if generic month views return right informations. """ c = Client() r = c.get('/myapp/news/2005/07/') self.assertEqual(r.status_code, 200) self.assertEqual(r.context['object_list'].count(), 1) self.assertEqual(len(r.context['date_list']), 1) self.assertEqual(r.context['date_list'][0].year, 2005) self.assertEqual(r.context['date_list'][0].month, 7) self.assertEqual(r.context['current_date'], r.context['object_list'][0].newsbox_publication_start_date) def test_06_view_month_archive_404(self): """ Test if generic month views return a 404 with an URL with a year + month without any news. """ c = Client() r = c.get('/myapp/news/2005/08/') self.assertEqual(r.status_code, 404) def test_07_view_day_archive_200(self): """ Test if generic day views return right informations. """ c = Client() r = c.get('/myapp/news/2005/07/15/') self.assertEqual(r.status_code, 200) self.assertEqual(r.context['object_list'].count(), 1) self.assertEqual(r.context['day'].year, 2005) self.assertEqual(r.context['day'].month, 7) self.assertEqual(r.context['day'].day, 15) self.assertEqual(r.context['current_date'], r.context['object_list'][0].newsbox_publication_start_date) def test_08_view_day_archive_404(self): """ Test if generic day views return a 404 with an URL with a date without any news. """ c = Client() r = c.get('/myapp/news/2005/07/14/') self.assertEqual(r.status_code, 404) def test_09_view_detail_200(self): """ Test if generic day views return right informations. """ c = Client() r = c.get('/myapp/news/2005/07/15/news-6/') self.assertEqual(r.status_code, 200) self.assertEqual(r.context['object'].pk, 6) def test_10_view_detail_404(self): """ Test if generic day views return a 404 with an URL with an invalid slug """ c = Client() r = c.get('/myapp/news/2005/07/15/my-birthday/') self.assertEqual(r.status_code, 404) def test_11_view_detail_404_not_published(self): """ Test if generic day views return a 404 with an URL with a not published news """ c = Client() r = c.get('/myapp/news/2005/07/15/news-2/') self.assertEqual(r.status_code, 404) def test_12_view_detail_404_wrong_date(self): """ Test if generic day views return a 404 with an URL with an invalide date """ c = Client() r = c.get('/myapp/news/1984/04/01/news-6/') self.assertEqual(r.status_code, 404) def test_13_news_are_ordered(self): """ Test if news are correctly ordered """ c = Client() r = c.get('/myapp/news/?page=1') news = self.get_news_in_list_by_summary(r, 'Summary of the news 7') self.assertIsNotNone(news) r = c.get('/myapp/news/?page=2') news = self.get_news_in_list_by_summary(r, 'Summary of the news 4') self.assertIsNotNone(news) r = c.get('/myapp/news/?page=3') news = self.get_news_in_list_by_summary(r, 'Summary of the news 1') self.assertIsNotNone(news) r = c.get('/myapp/news/?page=4') news = self.get_news_in_list_by_summary(r, 'Summary of the news 6') self.assertIsNotNone(news) def test_14_news_without_no_readmore_link(self): """ Test if readmore link is not present in news 4 """ c = Client() r = c.get('/myapp/news/?page=2') news = self.get_news_in_list_by_summary(r, 'Summary of the news 4') self.assertIsNotNone(news) found = self.has_readmore_link(news) self.assertFalse(found) def test_15_news_with_readmore_link(self): """ Test if readmore link is present in news 6 """ c = Client() r = c.get('/myapp/news/2005/') news = self.get_news_in_list_by_summary(r, 'Summary of the news 6') self.assertIsNotNone(news) found = self.has_readmore_link(news) self.assertTrue(found) def test_16_is_published_property(self): """ Test if is_published property is similar to the q_published method """ for model in [News, NewsSEO, NewsExpired, NewsComplete, NewsExtended]: for news in model.objects.filter(model.q_published()): self.assertTrue(news.is_published) for news in model.objects.exclude(model.q_published()): self.assertFalse(news.is_published) # def test_17_permissions(self): # """ # Test if permissions are correctly created for all models # """ # for model in [News, NewsSEO, NewsExpired, NewsComplete, NewsExtended]: # Permission.objects.filter(content_type__app_label='myapp', # content_type__model=model._meta.model_name)