def test_draft_page(self): # body should have classes "richtextpage draft" page = RichTextPage(title="my draft page", status=CONTENT_STATUS_DRAFT) page.save() request = self.factory.get(page.get_absolute_url()) request.user = AnonymousUser() response = render(request, 'pages/richtextpage.html', {'page': page}) self.assertContains(response, '<body class="richtextpage draft">')
def test_copy_default_minimal(self): """Copy all CMS models from the default site (minimal example).""" # This will be created with the default site # TODO: .create fails somehow related to django-concurrency page = RichTextPage(title='Learn', content='<h1>Title</h1>') page.save() site = Site.objects.create(name='zh-cn', domain='example.com') utils.build_site_content(site) self.assertCopied(page, site)
def test_copy_multiple_models(self): """CMS Pages, RichTextPage, Links should all be copied.""" # TODO: .create fails somehow related to django-concurrency page = RichTextPage(title='Learn', content='<h1>Title</h1>') page.save() link = Link.objects.create(title='External Link') site = Site.objects.create(name='zh-cn', domain='example.com') utils.build_site_content(site) self.assertCopied(page, site) self.assertCopied(link, site)
def test_set_parent(self): old_parent, _ = RichTextPage.objects.get_or_create(title="Old parent") new_parent, _ = RichTextPage.objects.get_or_create(title="New parent") child, _ = RichTextPage.objects.get_or_create(title="Child", slug="kid") self.assertTrue(child.parent is None) self.assertTrue(child.slug == "kid") child.set_parent(old_parent) child.save() self.assertEqual(child.parent_id, old_parent.id) self.assertTrue(child.slug == "old-parent/kid") child = RichTextPage.objects.get(id=child.id) self.assertEqual(child.parent_id, old_parent.id) self.assertTrue(child.slug == "old-parent/kid") child.set_parent(new_parent) child.save() self.assertEqual(child.parent_id, new_parent.id) self.assertTrue(child.slug == "new-parent/kid") child = RichTextPage.objects.get(id=child.id) self.assertEqual(child.parent_id, new_parent.id) self.assertTrue(child.slug == "new-parent/kid") child.set_parent(None) child.save() self.assertTrue(child.parent is None) self.assertTrue(child.slug == "kid") child = RichTextPage.objects.get(id=child.id) self.assertTrue(child.parent is None) self.assertTrue(child.slug == "kid") child = RichTextPage(title="child2") child.set_parent(new_parent) self.assertEqual(child.slug, "new-parent/child2") # Assert that cycles are detected. p1, _ = RichTextPage.objects.get_or_create(title="p1") p2, _ = RichTextPage.objects.get_or_create(title="p2") p2.set_parent(p1) with self.assertRaises(AttributeError): p1.set_parent(p1) with self.assertRaises(AttributeError): p1.set_parent(p2) p2c = RichTextPage.objects.get(title="p2") with self.assertRaises(AttributeError): p1.set_parent(p2c)
def test_set_parent(self): old_parent, _ = RichTextPage.objects.get_or_create(title="Old parent") new_parent, _ = RichTextPage.objects.get_or_create(title="New parent") child, _ = RichTextPage.objects.get_or_create( title="Child", slug="kid") self.assertTrue(child.parent is None) self.assertTrue(child.slug == "kid") child.set_parent(old_parent) child.save() self.assertEqual(child.parent_id, old_parent.id) self.assertTrue(child.slug == "old-parent/kid") child = RichTextPage.objects.get(id=child.id) self.assertEqual(child.parent_id, old_parent.id) self.assertTrue(child.slug == "old-parent/kid") child.set_parent(new_parent) child.save() self.assertEqual(child.parent_id, new_parent.id) self.assertTrue(child.slug == "new-parent/kid") child = RichTextPage.objects.get(id=child.id) self.assertEqual(child.parent_id, new_parent.id) self.assertTrue(child.slug == "new-parent/kid") child.set_parent(None) child.save() self.assertTrue(child.parent is None) self.assertTrue(child.slug == "kid") child = RichTextPage.objects.get(id=child.id) self.assertTrue(child.parent is None) self.assertTrue(child.slug == "kid") child = RichTextPage(title="child2") child.set_parent(new_parent) self.assertEqual(child.slug, "new-parent/child2") # Assert that cycles are detected. p1, _ = RichTextPage.objects.get_or_create(title="p1") p2, _ = RichTextPage.objects.get_or_create(title="p2") p2.set_parent(p1) with self.assertRaises(AttributeError): p1.set_parent(p1) with self.assertRaises(AttributeError): p1.set_parent(p2) p2c = RichTextPage.objects.get(title="p2") with self.assertRaises(AttributeError): p1.set_parent(p2c)
def update_cms_page(self, title=None, content='', parent_title=None, draft=False): if not title: title = 'Untitled' from mezzanine.pages.models import Page, RichTextPage page = get_cms_page_from_title(title) in_menus = [2,3] # create the page from mezzanine.core.models import CONTENT_STATUS_PUBLISHED, CONTENT_STATUS_DRAFT if not page: parent_page = get_cms_page_from_title(parent_title) page = RichTextPage(title=title, content_model='richtextpage', parent=parent_page, content=content, status=CONTENT_STATUS_PUBLISHED) page.save() page.status = CONTENT_STATUS_DRAFT if draft else CONTENT_STATUS_PUBLISHED page.in_menus = in_menus else: # Can't find an easy way to edit page.richtextpage.content, so let's write directly to the DB! from django.db import connection cursor = connection.cursor() cursor.execute('''update pages_richtextpage set content = %s where page_ptr_id = %s''', [content, page.id]) page.save() return page
def test_keywords_widget(self): """ Test that Keywords widget is returning proper value for form rendering and its support for different data types. """ keyword_widget = KeywordsWidget() keywords = set(["how", "now", "brown"]) Keyword.objects.all().delete() keyword_id_list = [] for keyword in keywords: keyword_id = Keyword.objects.get_or_create(title=keyword)[0].id keyword_id_list.append(keyword_id) keyword_id_string = ",".join(map(str, keyword_id_list)) values_from_string = keyword_widget.decompress(keyword_id_string) self.assertIn("how", values_from_string[1]) self.assertIn("now", values_from_string[1]) self.assertIn("brown", values_from_string[1]) for keyword_id in keyword_id_list: AssignedKeyword.objects.create(keyword_id=keyword_id, content_object=RichTextPage(pk=1)) assigned_keywords = AssignedKeyword.objects.all() values_from_relation = keyword_widget.decompress(assigned_keywords) self.assertIn("how", values_from_relation[1]) self.assertIn("now", values_from_relation[1]) self.assertIn("brown", values_from_relation[1]) self.assertEqual(("", ""), keyword_widget.decompress(None))
def test_nested_forms_links(self): """Page hierarchy for forms and links should be preserved on copy.""" # TODO: .create fails somehow related to django-concurrency page = RichTextPage(title='Learn', content='<h1>Title</h1>') page.save() form = Form(title='Contact Us', parent=page) form.save() link = Link(title='Foo', parent=page) link.save() site = Site.objects.create(name='zh-cn', domain='example.com') utils.build_site_content(site) self.assertCopied(page, site) self.assertCopied(form, site) self.assertCopied(link, site) copy = QuerySet(RichTextPage).get(slug=page.slug, site=site) formcopy = QuerySet(Form).get(slug=form.slug, site=site) linkcopy = QuerySet(Link).get(slug=link.slug, site=site) self.assertEqual(formcopy.parent_id, copy.pk) self.assertEqual(linkcopy.parent_id, copy.pk)
def test_delete_unused(self): """ Only ``Keyword`` instances without any assignments should be deleted. """ assigned_keyword = Keyword.objects.create(title="assigned") Keyword.objects.create(title="unassigned") AssignedKeyword.objects.create(keyword_id=assigned_keyword.id, content_object=RichTextPage(pk=1)) Keyword.objects.delete_unused(keyword_ids=[assigned_keyword.id]) self.assertEqual(Keyword.objects.count(), 2) Keyword.objects.delete_unused() self.assertEqual(Keyword.objects.count(), 1) self.assertEqual(Keyword.objects.all()[0].id, assigned_keyword.id)
def test_nested_pages(self): """Page hierarchy should be preserved on copy.""" # TODO: .create fails somehow related to django-concurrency page = RichTextPage(title='Learn', content='<h1>Title</h1>') page.save() subpage = RichTextPage(title='Sub Learn', content='<h1>Title</h1>', parent=page) subpage.save() site = Site.objects.create(name='zh-cn', domain='example.com') utils.build_site_content(site) self.assertCopied(page, site) self.assertCopied(subpage, site) copy = QuerySet(RichTextPage).get(slug=page.slug, site=site) subcopy = QuerySet(RichTextPage).get(slug=subpage.slug, site=site) self.assertEqual(subcopy.parent_id, copy.pk)
def test_update_site(self): from django.conf import settings from mezzanine.utils.sites import current_site_id # setup try: old_site_id = settings.SITE_ID except: old_site_id = None site1 = Site.objects.create(domain="site1.com") site2 = Site.objects.create(domain="site2.com") # default behaviour, page gets assigned current site settings.SITE_ID = site2.pk self.assertEqual(settings.SITE_ID, current_site_id()) page = RichTextPage() page.save() self.assertEqual(page.site_id, site2.pk) # Subsequent saves do not update site to current site page.site = site1 page.save() self.assertEqual(page.site_id, site1.pk) # resave w/ update_site=True, page gets assigned current site settings.SITE_ID = site1.pk page.site = site2 page.save(update_site=True) self.assertEqual(page.site_id, site1.pk) # resave w/ update_site=False, page does not update site settings.SITE_ID = site2.pk page.save(update_site=False) self.assertEqual(page.site_id, site1.pk) # When update_site=True, new page gets assigned current site settings.SITE_ID = site2.pk page = RichTextPage() page.site = site1 page.save(update_site=True) self.assertEqual(page.site_id, site2.pk) # When update_site=False, new page keeps current site settings.SITE_ID = site2.pk page = RichTextPage() page.site = site1 page.save(update_site=False) self.assertEqual(page.site_id, site1.pk) # When site explicitly assigned, new page keeps assigned site settings.SITE_ID = site2.pk page = RichTextPage() page.site = site1 page.save() self.assertEqual(page.site_id, site1.pk) # tear down if old_site_id: settings.SITE_ID = old_site_id else: del settings.SITE_ID site1.delete() site2.delete()
def test_upcoming(self): # no upcoming events - should not error response = self.client.get(reverse('event:upcoming')) assert response.status_code == 200 self.assertContains(response, "Next semester's events are being scheduled") self.assertContains(response, "Check back later") self.assertContains( response, reverse('event:by-semester', args=['fall', '2017'])) # use django timezone util for timezone-aware datetime tomorrow = timezone.now() + timedelta(days=1) event_type = EventType.objects.first() next_event = Event.objects.create(start_time=tomorrow, end_time=tomorrow, slug='some-workshop', event_type=event_type, title='A workshop') today = timezone.now() earlier_today = datetime(today.year, today.month, today.day, tzinfo=timezone.get_default_timezone()) earlier_event = Event.objects.create(start_time=earlier_today, end_time=earlier_today + timedelta(hours=1), slug='another-workshop', event_type=event_type, title='Earlier workshop') response = self.client.get(reverse('event:upcoming')) assert next_event in response.context['events'] assert earlier_event in response.context['events'] # summary fields that should be in list view self.assertContains(response, next_event.title) self.assertContains(response, next_event.get_absolute_url()) # (not testing all fields) # should not include past events past_event = Event.objects.filter(end_time__lte=today).first() assert past_event not in response.context['events'] # should include recent events assert past_event in response.context['past'] self.assertContains(response, 'Past Events') self.assertContains(response, past_event.title) self.assertContains(response, past_event.get_absolute_url()) # should include all semesters and years represented in events date_list = response.context['date_list'] assert ('Fall', 2016) in date_list assert ('Spring', 2017) in date_list assert ('Fall', 2017) in date_list # should link to events by semester for semester, year in date_list: self.assertContains( response, reverse('event:by-semester', args=[semester.lower(), year])) # last modified header should be set on response assert response.has_header('last-modified') modified = Event.objects.upcoming().order_by('updated').first().updated modified = modified.strftime('%a, %d %b %Y %H:%M:%S GMT') assert response['Last-Modified'] == modified # and should return 304 not modified when header is present response = self.client.get(reverse('event:upcoming'), HTTP_IF_MODIFIED_SINCE=modified) assert response.status_code == 304 # no upcoming events OR past events Event.objects.all().delete() response = self.client.get(reverse('event:upcoming')) assert response.status_code == 200 self.assertContains(response, "Next semester's events are being scheduled") self.assertContains(response, "Check back later.") # should include blurb if there is a matching page in hierarchy page = RichTextPage(title='Events') # should have slug 'events' page.content = 'An event blurb' page.save() response = self.client.get(reverse('event:upcoming')) self.assertContains(response, 'An event blurb') # should skip blurb if content is empty page.content = '<p> </p>' page.save() response = self.client.get(reverse('event:upcoming')) self.assertNotContains(response, '  ')