Skip to content

Commit

Permalink
Update GCSE gid and complete xml view testing
Browse files Browse the repository at this point in the history
  • Loading branch information
saschwarz committed Jul 15, 2014
1 parent a8028ff commit e545a57
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 105 deletions.
19 changes: 13 additions & 6 deletions gcse/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@


settings.GCSE_CONFIG = dict({
'NUM_FACET_ITEMS_PER_FACET': 4,
'NUM_FACET_ITEMS_PER_FACET': 4,
'NUM_ANNOTATIONS_PER_FILE': 1000,
},
**getattr(settings, 'GCSE_CONFIG' , {}))
Expand Down Expand Up @@ -208,8 +208,8 @@ class CustomSearchEngine(TimeStampedModel):
</CustomSearchEngine>"""

def annotations(self):
return Annotation.objects.filter(status=Annotation.STATUS.active,
labels__in=self.background_labels.all()).select_subclasses()
return Annotation.objects.filter(status=Annotation.STATUS.active,
labels__in=self.background_labels.all()).select_subclasses().order_by('id')

def annotation_count(self):
return self.annotations().count()
Expand Down Expand Up @@ -270,6 +270,10 @@ def _add_google_customizations(cls, doc):
doc = root
return doc

def _update_gid(self, doc):
el = doc.xpath(".//CustomSearchEngine")[0]
el.attrib['id'] = self.gid

def _update_include(self, doc):
for el in doc.findall(".//Include"):
el.getparent().remove(el)
Expand All @@ -287,23 +291,24 @@ def _annotations_url(self, index):
return '//' + Site.objects.get_current().domain + url

def _update_xml(self):
"""Parse the input_xml and update it with the current database values in this instance."""
"""Parse the input_xml and update output_xml with the values in this instance."""
input_xml = self.input_xml
if not self.input_xml:
# need to replace id attribute with id of this CSE
input_xml = self.DEFAULT_XML

doc = ET.fromstring(input_xml)
# handle case where user gives us only CustomSearchEngine without
# external Annotations file - wrap CSE with GoogleCustomizations element:
doc = self._add_google_customizations(doc)
self._update_gid(doc)
self._create_or_update_xml_element_text(doc, "title")
self._create_or_update_xml_element_text(doc, "description")

# update Context's Facet and BackgroundLabels
self._update_background_labels(doc)
self._update_facets(doc)

# Add Include of Annotations with link keyed on this CSE
self._update_include(doc)
self.output_xml = ET.tostring(doc, encoding='UTF-8', xml_declaration=True)
Expand Down Expand Up @@ -688,3 +693,5 @@ def endElementNS(self, ns_name, qname):
# - delete old FacetItems and their Labels on import (with flag?) if unused by any Annotation.
# - management command to insert GCSE and Annotations.
# - import of CSE to optionally import linked Annotations.
# - CSE output_xml of Included Annotation files can change as Annotations are added/deleted
# need either update on Annotation create/delete or dynamically update output_xml on GET.
63 changes: 0 additions & 63 deletions gcse/templates/gcse/cse.xml

This file was deleted.

7 changes: 5 additions & 2 deletions gcse/urls.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from django.conf.urls import patterns, url
from django.views.generic import TemplateView
from .feeds import RssLatestFeed, AtomLatestFeed
from .views import (CSEAnnotations,)
from .views import (CSEAnnotations, CustomSearchEngineDetail)


feeds = {
'rss': RssLatestFeed,
Expand All @@ -16,7 +17,9 @@
urlpatterns += patterns('gcse.views',
url(r'^$', 'index', name='home'),
# urls for Google search related resources
url(r'^(?P<gid>[\w-]+).xml$', TemplateView.as_view(template_name='gcse/cse.xml'), name='cse'),
url(r'^(?P<gid>[\w-]+).xml$',
CustomSearchEngineDetail.as_view(),
name='cse'),
url(r'^annotations/(?P<gid>[\w-]+).(?P<page>\w+).xml$',
CSEAnnotations.as_view(),
name='cse_annotations'),
Expand Down
13 changes: 12 additions & 1 deletion gcse/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
from django.db.models import Q
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.views.decorators.cache import never_cache
from django.views.generic import (DetailView,ListView, TemplateView)
from django.views.generic.base import View
from django.views.generic import (DetailView, ListView, TemplateView)
from django.core.mail import mail_managers
from django.core import urlresolvers
from django.contrib.sites.models import Site
Expand All @@ -25,6 +26,16 @@
import json


class CustomSearchEngineDetail(View):
"""
Have CustomSearchEngine model
"""
def get(self, request, *args, **kwargs):
cse = get_object_or_404(CustomSearchEngine,
gid=kwargs['gid'])
return HttpResponse(cse.output_xml)


class CSEAnnotations(ListView):
"""
Generate paginated Annotation XML for a specified CustomSearchEngine.
Expand Down
27 changes: 20 additions & 7 deletions tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,34 +197,45 @@ def _extractPathAsString(xml, path):

class TestCSEUpdateXML(TestCase):

def test_input_matches_output_xml_when_no_changes_to_instance(self):
cse = CustomSearchEngine(gid="c12345-r678",
def test_output_xml_has_new_gid_when_no_changes_to_instance(self):
cse = CustomSearchEngine(gid="c12345-r999",
input_xml=CSE_XML)
cse.save()
self.assertEqual('c12345-r999',
_extractPath(cse.output_xml,
"/GoogleCustomizations/CustomSearchEngine")[0].attrib['id'])

self.assertEqual('', cse.title) # no title set so leave XML alone
self.assertEqual("AgilityNerd Site Search", _extractPathElementText(cse.output_xml, "/GoogleCustomizations/CustomSearchEngine/Title"))
self.assertEqual("AgilityNerd Site Search",
_extractPathElementText(cse.output_xml, "/GoogleCustomizations/CustomSearchEngine/Title"))

def test_output_xml_has_new_title_when_title_is_changed(self):
cse = CustomSearchEngine(gid="c12345-r678",
title="""Here's a new title in need of escaping: &<>""",
input_xml=CSE_XML)
cse.save()
self.assertEqual(cse.title, _extractPathElementText(cse.output_xml, "/GoogleCustomizations/CustomSearchEngine/Title"))
self.assertEqual(cse.title,
_extractPathElementText(cse.output_xml,
"/GoogleCustomizations/CustomSearchEngine/Title"))

def test_output_xml_has_new_title_element_when_there_is_no_title_element(self):
input_xml = """<CustomSearchEngine id="c12345-r678" keywords="" language="en" encoding="ISO-8859-1" domain="www.google.com" safesearch="true"><Context/></CustomSearchEngine>"""
cse = CustomSearchEngine(gid="c12345-r678",
title="""Here's a new title in need of escaping: &<>""",
input_xml=input_xml)
cse.save()
self.assertEqual(cse.title, _extractPathElementText(cse.output_xml, "/GoogleCustomizations/CustomSearchEngine/Title"))
self.assertEqual(cse.title,
_extractPathElementText(cse.output_xml,
"/GoogleCustomizations/CustomSearchEngine/Title"))

def test_output_xml_has_new_description_when_description_is_changed(self):
cse = CustomSearchEngine(gid="c12345-r678",
description="""Here's a new description in need of escaping: &<>""",
input_xml=CSE_XML)
cse.save()
self.assertEqual(cse.description, _extractPathElementText(cse.output_xml, "/GoogleCustomizations/CustomSearchEngine/Description"))
self.assertEqual(cse.description,
_extractPathElementText(cse.output_xml,
"/GoogleCustomizations/CustomSearchEngine/Description"))

def test_output_xml_has_new_description_element_when_there_is_no_description_element(self):
input_xml = """<CustomSearchEngine id="c12345-r678" keywords="" language="en" encoding="ISO-8859-1" domain="www.google.com" safesearch="true"><Context/></CustomSearchEngine>"""
Expand All @@ -233,7 +244,9 @@ def test_output_xml_has_new_description_element_when_there_is_no_description_ele
input_xml=input_xml)
cse.save()

self.assertEqual(cse.description, _extractPathElementText(cse.output_xml, "/GoogleCustomizations/CustomSearchEngine/Description"))
self.assertEqual(cse.description,
_extractPathElementText(cse.output_xml,
"/GoogleCustomizations/CustomSearchEngine/Description"))

def test_output_xml_has_new_title_and_description_when_neither_exist(self):
input_xml = """<CustomSearchEngine id="c12345-r678" keywords="" language="en" encoding="ISO-8859-1" domain="www.google.com" safesearch="true"><Context/></CustomSearchEngine>"""
Expand Down
62 changes: 36 additions & 26 deletions tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,18 @@ def setUp(self):
self.annotation.save()
self.annotation.labels.add(self.label)
self.annotation.save()
self.cse = CustomSearchEngine.objects.create(gid="12345678", title="CSE 1234568")
self.cse = CustomSearchEngine.objects.create(gid="g123-456-AZ0", title="CSE 1234568")
self.cse.background_labels.add(self.label)
self.cse.save()
self.old_pagination = CSEAnnotations.paginate_by

def _add_annotation(self):
annotation = Annotation(comment='Site Name 2',
original_url='http://example.com/',
status=Annotation.STATUS.active)
annotation.save()
annotation.labels.add(self.label)

def tearDown(self):
settings.ROOT_URLCONF = self.ROOT_URLCONF
settings.TEMPLATE_CONTEXT_PROCESSORS = self.TEMPLATE_CONTEXT_PROCESSORS
Expand All @@ -41,38 +48,51 @@ def test_annotations(self):
self.assertContains(response, '<Annotations start="1" num="1" total="1">', count=1)

def test_multiple_page_annotations(self):
annotation = Annotation(comment='Site Name 2',
original_url='http://example.com/',
status=Annotation.STATUS.active)
annotation.save()
annotation.labels.add(self.label)

self._add_annotation()
CSEAnnotations.paginate_by = 1 # one per page

response = self.client.get(reverse('cse_annotations', args=(self.cse.gid, 1)))
self.assertEqual(200, response.status_code)
self.assertTemplateUsed(response, 'gcse/annotation.xml')
self.assertContains(response, '<Annotations start="1" num="1" total="2">', count=1)
self.assertContains(response, '<Comment>Site Name</Comment>', count=1)

# get page 2
response = self.client.get(reverse('cse_annotations', args=(self.cse.gid, 2)))
self.assertEqual(200, response.status_code)
self.assertTemplateUsed(response, 'gcse/annotation.xml')
self.assertContains(response, '<Annotations start="2" num="2" total="2">', count=1)
self.assertContains(response, '<Comment>Site Name 2</Comment>', count=1)

# def test_results(self):
# response = self.client.get(reverse('cse_results'))
# self.assertEquals(200, response.status_code)
# self.assertTemplateUsed(response, 'gcse/results.html')

# def test_cse(self):
# response = self.client.get(reverse('cse'))
# self.assertEquals(200, response.status_code)
# self.assertTemplateUsed(response, 'gcse/cse.xml')

# def test_map(self):
# response = self.client.get(reverse('cse_map'))
# self.assertEquals(200, response.status_code)
# self.assertTemplateUsed(response, 'gcse/map.html')
def test_cse(self):
response = self.client.get(reverse('cse', args=(self.cse.gid,)))
self.assertEqual(200, response.status_code)
self.assertContains(response,
'<CustomSearchEngine id="g123-456-AZ0" language="en" encoding="utf-8" enable_suggest="true">')
self.assertContains(response,
'<Include type="Annotations" href="//example.com/annotations/g123-456-AZ0.0.xml"/>')

def test_cse_multiple_annotations(self):
self._add_annotation()
# force update of CSE... change to signal on Annotation insert/delete?
with override_settings(GCSE_CONFIG={'NUM_FACET_ITEMS_PER_FACET': 2,
'NUM_ANNOTATIONS_PER_FILE': 1}):
self.cse.save()

response = self.client.get(reverse('cse', args=(self.cse.gid,)))
self.assertEqual(200, response.status_code)
self.assertContains(response,
'<CustomSearchEngine id="g123-456-AZ0" language="en" encoding="utf-8" enable_suggest="true">')
self.assertContains(response,
'<Include type="Annotations" href="//example.com/annotations/g123-456-AZ0.0.xml"/>')
print(response.content)
self.assertContains(response,
'<Include type="Annotations" href="//example.com/annotations/g123-456-AZ0.1.xml"/>')

# def test_browse(self):
# response = self.client.get(reverse('cse_browse'))
Expand All @@ -99,16 +119,6 @@ def test_multiple_page_annotations(self):
# self.assertEquals(200, response.status_code)
# self.assertTemplateUsed(response, 'gcse/browse_by_label_tabbed.html')

# def test_browse_by_label_grid(self):
# response = self.client.get(reverse('cse_browse_by_label_grid', kwargs={"label":self.label.name}))
# self.assertEquals(200, response.status_code)
# self.assertTemplateUsed(response, 'gcse/browse_by_label_grid.html')

# def test_directions(self):
# response = self.client.get(reverse('cse_directions', kwargs={"id":self.annotation.id}))
# self.assertEquals(200, response.status_code)
# self.assertTemplateUsed(response, 'gcse/directions.html')

# def test_add(self):
# response = self.client.get(reverse('cse_add'))
# self.assertEquals(200, response.status_code)
Expand Down

0 comments on commit e545a57

Please sign in to comment.