Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Saving name and description about a popit api instance #861

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
11 changes: 11 additions & 0 deletions global_test_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from django.test import RequestFactory
from django.test.client import Client
import logging
import vcr

_LOCALS = threading.local()

Expand Down Expand Up @@ -167,13 +168,23 @@ class WriteItClient(WriteItRequestFactory, Client):
pass


def popit_about_url_matcher(r1, r2):
url_contains_popit = 'popit' in r1.url
ends_in_about = (r1.url.endswith('/about/') or r1.url.endswith('/about'))
if url_contains_popit and ends_in_about:
return True
return False


class WriteItTestCaseMixin(object):
client_class = WriteItClient
fixtures = ['example_data.yaml']

def setUp(self):
self.site = Site.objects.get_current()
self.factory = WriteItRequestFactory()
self.vcr = vcr.VCR()
self.vcr.register_matcher('popit_url', popit_about_url_matcher)

def assertRedirects(self, response, expected_url, status_code=302, target_status_code=200, host=None, msg_prefix=''):
self.assertEquals(response.status_code, status_code)
Expand Down
295 changes: 295 additions & 0 deletions nuntium/migrations/0065_auto__add_aboutpopitapiinstance.py

Large diffs are not rendered by default.

31 changes: 31 additions & 0 deletions nuntium/popit_api_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from contactos.models import Contact
from mailit import MailChannel
from datetime import datetime
from django.db import models
import slumber


Expand Down Expand Up @@ -93,7 +94,16 @@ def create_contact(cls, obj, doc, writeitinstance):
contact.save()


class AboutPopitApiInstance(models.Model):
popit_api_instance = models.OneToOneField('PopitApiInstance', related_name='about')
name = models.CharField(max_length=512)
description = models.TextField()


class PopitApiInstance(ApiInstance):
about_class = AboutPopitApiInstance


class Meta:
proxy = True

Expand All @@ -105,3 +115,24 @@ def fetch_all_from_api(self, writeitinstance):
models = [PopitPerson]
for model in models:
model.fetch_all_from_api(instance=self, writeitinstance=writeitinstance)

def get_about(self):
api = slumber.API(self.url)
'''
Right here I depend a bit on popit and how it is going to behave in the future
so here it is the thing for example for https://yournextmp.popit.mysociety.org/api/v0.1
there is no /about because the /about is in the root of the api in other words
https://yournextmp.popit.mysociety.org/api/about, so is ```about``` going to be part of /v0.1?
if the answer to that is No then we should strip the version of the api from the URL
which I'm not doing right now.
'''
about = self.about_class(popit_api_instance=self)
try:
result = api.about().get()
for key in result['result'].keys():
if hasattr(about, key):
setattr(about, key, result['result'][key])
except slumber.exceptions.HttpClientError:
pass
about.save()
return about
29 changes: 29 additions & 0 deletions nuntium/tests/fixtures/popit_about_404.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
interactions:
- request:
body: null
headers:
Connection: [close]
Host: [yournextmp.popit.mysociety.org]
User-Agent: [Python-urllib/2.7]
method: GET
uri: https://yournextmp.popit.mysociety.org/api/v0.1/about
response:
body: {string: !!python/unicode "{\n \"errors\": [\n \"collection 'about'
not found\"\n ]\n}"}
headers:
accept-ranges: [bytes]
access-control-allow-origin: ['*']
age: ['0']
connection: [close]
content-length: ['56']
content-type: [application/json; charset=utf-8]
date: ['Sat, 11 Apr 2015 00:44:13 GMT']
etag: [W/"38-8b9a338f"]
server: [nginx]
set-cookie: [connect.sess=s%3Aj%3A%7B%22passport%22%3A%7B%7D%7D.UywPBji0dFbUMZW5r1RdSpofbQAIv7kGfQeO1FGtXmc;
Domain=.popit.mysociety.org; Path=/; HttpOnly; Secure]
vary: ['X-HTTP-Method-Override,Origin']
x-content-type-options: [nosniff]
x-url: [/api/v0.1/about]
status: {code: 404, message: Not Found}
version: 1
30 changes: 30 additions & 0 deletions nuntium/tests/fixtures/uk_parliament_popit_about.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
interactions:
- request:
body: null
headers:
Connection: [close]
Host: [parliament.popit.mysociety.org]
User-Agent: [Python-urllib/2.7]
method: GET
uri: http://parliament.popit.mysociety.org/api/about/
response:
body: {string: !!python/unicode "{\n \"result\": {\n \"name\": \"UK Parliament\",\n
\ \"description\": \"A list of everybody in both houses of the UK Parliament,
based on the Members' Data Platform.\",\n \"language\": \"en\",\n \"license\":
\"The **{{name}}** PopIt instance is made available under the [Open Database
License](http://opendatacommons.org/licenses/odbl/1.0/). Any rights in individual
contents of the database are licensed under the [Database Contents License](http://opendatacommons.org/licenses/dbcl/1.0/).\",\n
\ \"person_count\": 4138,\n \"organization_count\": 333\n }\n}"}
headers:
accept-ranges: [bytes]
age: ['0']
connection: [close]
content-length: ['543']
content-type: [application/json; charset=utf-8]
date: ['Fri, 10 Apr 2015 15:27:58 GMT']
etag: [W/"21f-818edeb2"]
vary: [X-HTTP-Method-Override]
x-content-type-options: [nosniff]
x-url: [/api/about]
status: {code: 200, message: OK}
version: 1
53 changes: 52 additions & 1 deletion nuntium/tests/popit_api_instance_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,58 @@
from django.utils.unittest import skipUnless
from django.conf import settings
from django.contrib.auth.models import User
from nuntium.popit_api_instance import is_current_membership
from nuntium.popit_api_instance import is_current_membership, PopitApiInstance, AboutPopitApiInstance


class PopitApiInstanceAboutTestsCase(TestCase):
'''
Ok so what I thought was:
PopitApiInstance is a proxy Model (https://docs.djangoproject.com/en/1.6/topics/db/models/#proxy-models)
which means that it doesn't have a database representation of its own
and I could make it proxy = True but then I would have to create a datamigration and
call me a chicken but I really really don't want to go that way, cause it looks scary =(.
So what I thought was that I could create a statellite class called AboutPopitApiInstance which would have some other information
about the PopitApiInstance like name and description in this TestCase I'm testing its creation as well as when I go and do instance.get_about()
it should go to popit get the about and store it.
'''
def setUp(self):
super(PopitApiInstanceAboutTestsCase, self).setUp()

def test_a_popit_instance_can_have_about(self):
'''A PopitApiInstance can have a about info'''

popit_api_instance = PopitApiInstance.objects.get(id=1)
AboutPopitApiInstance.objects.create(
popit_api_instance=popit_api_instance,
name="UK Parliament",
description="A list of everybody in both houses of the UK Parliament, based on the Members' Data Platform.")
self.assertEquals(popit_api_instance.about.name, "UK Parliament")
self.assertEquals(popit_api_instance.about.description, "A list of everybody in both houses of the UK Parliament, based on the Members' Data Platform.")

def test_importing_name_and_description_from_popit(self):
'''Getting it and retrieving the data'''
with self.vcr.use_cassette('nuntium/tests/fixtures/uk_parliament_popit_about.yaml', match_on=['popit_url']):
popit_api_instance = PopitApiInstance.objects.get(id=1)
about = popit_api_instance.get_about()
self.assertEquals(about.name,
"UK Parliament")
self.assertEquals(about.description,
"A list of everybody in both houses of the UK Parliament, based on the Members' Data Platform.")

def test_cope_with_404_or_other_errors(self):
'''
Even if there is an error with the url it creates an AboutPopitApiInstance object
'''
with self.vcr.use_cassette('nuntium/tests/fixtures/popit_about_404.yaml', match_on=['popit_url']):
popit_api_instance = PopitApiInstance.objects.get(id=1)
about = popit_api_instance.get_about()
'''
So the AboutPopitApiInstance is not None but the content in name and description are empty
'''
self.assertTrue(about)
self.assertFalse(about.name)
self.assertFalse(about.description)
self.assertTrue(about.id)


@skipUnless(settings.LOCAL_POPIT, "No local popit running")
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ celery-haystack==0.8
django-celery-transactions<0.2.0
django-downloadview==1.6
django-subdomains==2.0.4
vcrpy==1.4.0
2 changes: 1 addition & 1 deletion writeit/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,10 @@
'annoying',
'celery_haystack',

'nuntium',
'djangoplugins',
'pagination',
'popit',
'nuntium',
'south',
'contactos',
'mailit',
Expand Down