Skip to content

Commit

Permalink
Merge 14ea9c0 into feda6a0
Browse files Browse the repository at this point in the history
  • Loading branch information
vkurup committed May 25, 2015
2 parents feda6a0 + 14ea9c0 commit fba494e
Show file tree
Hide file tree
Showing 91 changed files with 393 additions and 501 deletions.
9 changes: 4 additions & 5 deletions .travis.yml
Expand Up @@ -2,11 +2,10 @@ language: python
python:
- "2.7"
env:
- TOXENV=py26-1.4.X,py27-1.4.X
- TOXENV=py26-1.5.X,py27-1.5.X
- TOXENV=py26-1.6.X,py27-1.6.X
- TOXENV=py27-1.7.X
- TOXENV=py27-trunk
- TOXENV=py27-1.7.X,py33-1.7.X,py34-1.7.X
- TOXENV=py27-1.8.X,py33-1.8.X,py34-1.8.X
- TOXENV=py27-trunk,py33-trunk,py34-trunk
- TOXENV=docs
- TOXENV=flake8
- TOXENV=coverage
Expand All @@ -19,7 +18,7 @@ after_success:
- coveralls
matrix:
allow_failures:
- env: TOXENV=py27-trunk
- env: TOXENV=py27-trunk,py33-trunk,py34-trunk
notifications:
irc:
- "irc.freenode.org#rapidsms"
1 change: 0 additions & 1 deletion README.rst
Expand Up @@ -49,7 +49,6 @@ RapidSMS is best installed via `PyPI`_. To install the latest version, run::
Dependencies
------------

* `django-nose <http://pypi.python.org/pypi/django-nose>`_
* `djappsettings <http://pypi.python.org/pypi/djappsettings>`_
* `django-tables2 <https://pypi.python.org/pypi/django-tables2>`_
* `django-selectable <http://pypi.python.org/pypi/django-selectable>`_
Expand Down
3 changes: 1 addition & 2 deletions docs/developing/testing.rst
Expand Up @@ -8,8 +8,7 @@ behavior. Having as complete a set of tests as possible is important so
we can have confidence that when we make a change in one place, we haven't
broken something else.

RapidSMS uses `nose <http://pypi.python.org/pypi/nose/>`_ to run its test suite
and provides several configuration options and entry points for continuous
RapidSMS provides several configuration options and entry points for continuous
integration. The unit tests can be run in the current python environment or
automated to run in several environments and can include coverage reports.

Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/tutorial01.rst
Expand Up @@ -79,7 +79,7 @@ Install the dependencies:
(rapidsms-tut-venv)~/rapidsms_tut $ pip install -r requirements/base.txt
[... lots of output omitted ...]
Successfully installed RapidSMS South requests django-nose django-tables2 djappsettings django-selectable nose
Successfully installed RapidSMS South requests django-tables2 djappsettings django-selectable
Cleaning up...
(rapidsms-tut-venv)~/rapidsms_tut $
Expand Down
10 changes: 4 additions & 6 deletions rapidsms/apps/base.py
@@ -1,12 +1,13 @@
#!/usr/bin/env python
# vim: ai ts=4 sts=4 et sw=4

from django.utils.encoding import python_2_unicode_compatible

from ..utils.modules import try_import, get_class
from ..log.mixin import LoggerMixin


class AppBase(object, LoggerMixin):
@python_2_unicode_compatible
class AppBase(object):
"""
"""

Expand All @@ -31,9 +32,6 @@ def find(cls, app_name):
def __init__(self, router):
self.router = router

def _logger_name(self): # pragma: no cover
return "app/%s" % self.name

@property
def name(self):
"""
Expand All @@ -43,7 +41,7 @@ def name(self):

return self.__module__.split(".")[-2]

def __unicode__(self):
def __str__(self):
return self.name

def __repr__(self):
Expand Down
15 changes: 7 additions & 8 deletions rapidsms/backends/base.py
@@ -1,11 +1,13 @@
#!/usr/bin/env python
# vim: ai ts=4 sts=4 et sw=4

from django.utils.encoding import python_2_unicode_compatible

from rapidsms.utils.modules import import_class
from rapidsms.log.mixin import LoggerMixin


class BackendBase(object, LoggerMixin):
@python_2_unicode_compatible
class BackendBase(object):
"""Base class for outbound backend functionality."""

@classmethod
Expand All @@ -25,10 +27,7 @@ def __init__(self, router, name, **kwargs):
self._config = kwargs
self.configure(**kwargs)

def _logger_name(self): # pragma: no cover
return "backend/%s" % self.name

def __unicode__(self):
def __str__(self):
return self.name

def __repr__(self):
Expand All @@ -42,7 +41,7 @@ def configure(self, **kwargs):
"""
pass

def send(self, id_, text, identities, context={}):
def send(self, id_, text, identities, context=None):
"""
Backend sending logic. The router will call this method for each
outbound message. This method must be overridden by sub-classes.
Expand All @@ -56,7 +55,7 @@ def send(self, id_, text, identities, context={}):
:param id\_: Message ID
:param text: Message text
:param identities: List of identities
:param context: Optional extra context provided by router to backend
:param context: Optional dictionary with extra context provided by router to backend
"""
# subclasses should override this
raise NotImplementedError()
Expand Down
4 changes: 3 additions & 1 deletion rapidsms/backends/database/models.py
Expand Up @@ -2,6 +2,7 @@
# vim: ai ts=4 sts=4 et sw=4

from django.db import models
from django.utils.encoding import python_2_unicode_compatible


INCOMING = 'I'
Expand All @@ -13,6 +14,7 @@
)


@python_2_unicode_compatible
class BackendMessage(models.Model):
name = models.CharField(max_length=255)
date = models.DateTimeField(auto_now_add=True)
Expand All @@ -23,5 +25,5 @@ class BackendMessage(models.Model):
identity = models.CharField(max_length=100)
text = models.TextField()

def __unicode__(self):
def __str__(self):
return self.text[:60]
5 changes: 3 additions & 2 deletions rapidsms/backends/database/outgoing.py
Expand Up @@ -15,8 +15,9 @@ class DatabaseBackend(BackendBase):
Simple backend that uses the database for storage. Mostly used for testing.
"""

def send(self, id_, text, identities, context):
logger.info('Storing message: %s' % text)
def send(self, id_, text, identities, context=None):
logger.info('Storing message: %s', text)
context = context or {}
kwargs = {'name': self.name, 'direction': 'O', 'text': text,
'message_id': id_}
if 'external_id' in context:
Expand Down
21 changes: 9 additions & 12 deletions rapidsms/backends/http/tests.py
@@ -1,6 +1,6 @@
from django.test import TestCase
from django.core.urlresolvers import reverse
from django.conf.urls import patterns, url
from django.conf.urls import url

from rapidsms.tests.harness import RapidTest
from rapidsms.backends.http import views
Expand All @@ -14,17 +14,14 @@ class CustomHttpBackend(views.GenericHttpBackendView):
params = {'identity_name': 'phone', 'text_name': 'message'}


urlpatterns = patterns('',
url(r"^backend/http/$",
views.GenericHttpBackendView.as_view(
backend_name='http-backend'),
name='http-backend'
),
url(r"^backend/http-custom/$",
CustomHttpBackend.as_view(),
name='custom-http-backend'
),
)
urlpatterns = (
url(r"^backend/http/$",
views.GenericHttpBackendView.as_view(backend_name='http-backend'),
name='http-backend'),
url(r"^backend/http-custom/$",
CustomHttpBackend.as_view(),
name='custom-http-backend'),
)


class HttpFormTest(TestCase):
Expand Down
4 changes: 2 additions & 2 deletions rapidsms/backends/http/views.py
Expand Up @@ -58,10 +58,10 @@ def form_invalid(self, form):
If the form failed to validate, logs the errors and returns a bad
response to the client.
"""
logger.error("%s data:" % self.request.method)
logger.error("%s data:", self.request.method)
logger.error(pprint.pformat(form.data))
errors = dict((k, v[0]) for k, v in form.errors.items())
logger.error(unicode(errors))
logger.error(str(errors))
if form.non_field_errors():
logger.error(form.non_field_errors())
return HttpResponseBadRequest('form failed to validate')
Expand Down
3 changes: 2 additions & 1 deletion rapidsms/backends/kannel/forms.py
@@ -1,3 +1,4 @@
from six import string_types
from django import forms

from rapidsms.backends.http.forms import BaseHttpForm
Expand All @@ -15,7 +16,7 @@ def clean_text(self):
# have a unicode string
charset = self.cleaned_data.get('charset', None)
text = self.cleaned_data['text']
if charset and not isinstance(text, unicode):
if charset and not isinstance(text, string_types):
text = text.decode(charset)
return text

Expand Down
5 changes: 3 additions & 2 deletions rapidsms/backends/kannel/outgoing.py
Expand Up @@ -46,8 +46,9 @@ def prepare_request(self, id_, text, identities, context):
kwargs['params'] = query
return kwargs

def send(self, id_, text, identities, context={}):
logger.debug('Sending message: %s' % text)
def send(self, id_, text, identities, context=None):
logger.debug('Sending message: %s', text)
context = context or {}
kwargs = self.prepare_request(id_, text, identities, context)
r = requests.get(**kwargs)
if r.status_code != requests.codes.ok:
Expand Down
13 changes: 2 additions & 11 deletions rapidsms/backends/kannel/tests.py
@@ -1,22 +1,13 @@
from django.test import TestCase
from django.core.urlresolvers import reverse
from django.conf.urls import patterns, url
from django.utils.timezone import now

from rapidsms.backends.kannel import views
from rapidsms.backends.kannel import KannelBackend
from rapidsms.backends.kannel.forms import KannelForm
from rapidsms.backends.kannel.models import DeliveryReport
from rapidsms.tests.harness import RapidTest, CreateDataMixin


urlpatterns = patterns('',
url(r"^backend/kannel/$",
views.KannelBackendView.as_view(backend_name='kannel-backend'),
name='kannel-backend'),
)


class KannelFormTest(TestCase):

def test_valid_form(self):
Expand Down Expand Up @@ -46,7 +37,7 @@ def test_get_incoming_data(self):

class KannelViewTest(RapidTest):

urls = 'rapidsms.backends.kannel.tests'
urls = 'rapidsms.backends.kannel.urls'
disable_phases = True

def test_valid_response_get(self):
Expand Down Expand Up @@ -101,9 +92,9 @@ def test_outgoing_keys(self):
self.assertEqual(config['sendsms_params']['password'],
data['password'])
self.assertEqual(message.connection.identity, data['to'])
self.assertEqual(message.text, data['text'])
self.assertEqual(config['coding'], data['coding'])
self.assertEqual(config['charset'], data['charset'])
self.assertEqual(message.text, data['text'].decode(data['charset']))

def test_outgoing_unicode_characters(self):
"""Ensure outgoing messages are encoded properly."""
Expand Down
13 changes: 9 additions & 4 deletions rapidsms/backends/kannel/urls.py
@@ -1,8 +1,13 @@
from django.conf.urls import patterns, url
from rapidsms.backends.kannel.views import DeliveryReportView
from django.conf.urls import include, url
from rapidsms.backends.kannel import views


urlpatterns = patterns('',
url(r"^delivery-report/$", DeliveryReportView.as_view(),
urlpatterns = (
url(r'^account/', include('rapidsms.urls.login_logout')),
url(r"^delivery-report/$",
views.DeliveryReportView.as_view(),
name="kannel-delivery-report"),
url(r"^backend/kannel/$",
views.KannelBackendView.as_view(backend_name='kannel-backend'),
name='kannel-backend'),
)
5 changes: 3 additions & 2 deletions rapidsms/backends/kannel/views.py
Expand Up @@ -36,6 +36,7 @@ def form_valid(self, form):
class DeliveryReportView(CreateView):

model = DeliveryReport
fields = ('date_sent', 'message_id', 'identity', 'sms_id', 'smsc', 'status', 'status_text', )
http_method_names = ['get']

def get(self, *args, **kwargs):
Expand All @@ -57,10 +58,10 @@ def form_invalid(self, form):
If the form failed to validate, logs the errors and returns a bad
response to the client.
"""
logger.error("%s data:" % self.request.method)
logger.error("%s data:", self.request.method)
logger.error(pprint.pformat(form.data))
errors = dict((k, v[0]) for k, v in form.errors.items())
logger.error(unicode(errors))
logger.error(str(errors))
if form.non_field_errors():
logger.error(form.non_field_errors())
return HttpResponseBadRequest('form failed to validate')
16 changes: 8 additions & 8 deletions rapidsms/backends/test_base.py
Expand Up @@ -14,26 +14,26 @@ class BackendBaseTest(TestCase):

def test_backend_has_name(self):
backend = BackendBase(None, "mock")
self.assertEquals(repr(backend), "<backend: mock>")
self.assertEquals(unicode(backend), "mock")
self.assertEquals(backend.name, "mock")
self.assertEqual(repr(backend), "<backend: mock>")
self.assertEqual(str(backend), "mock")
self.assertEqual(backend.name, "mock")

def test_backend_has_model(self):
backend = BackendBase(None, "mock")
# the row should be created when .model is called.
self.assertEquals(backend.model.__class__, Backend)
self.assertEquals(backend.model.name, "mock")
self.assertEqual(backend.model.__class__, Backend)
self.assertEqual(backend.model.name, "mock")
# check that the backend stub was committed to the db.
self.assertEquals(Backend.objects.filter(name="mock").count(), 1)
self.assertEqual(Backend.objects.filter(name="mock").count(), 1)

def test_backend_passes_kwargs_to_configure(self):
class ConfigurableBackend(BackendBase):
def configure(self, **kwargs):
self.conf = kwargs
conf_backend = ConfigurableBackend(None, "mock", a=1, b=2)
self.assertEquals(conf_backend.conf, {"a": 1, "b": 2})
self.assertEqual(conf_backend.conf, {"a": 1, "b": 2})

def test_backend_finds_valid_backend_class(self):
"""Class should be returned if valid."""
backend = BackendBase.find('rapidsms.backends.test_base.TestBackend')
self.assertEquals(TestBackend, backend)
self.assertEqual(TestBackend, backend)
5 changes: 3 additions & 2 deletions rapidsms/backends/vumi/outgoing.py
Expand Up @@ -39,8 +39,9 @@ def prepare_request(self, id_, text, identities, context):
kwargs['data'] = json.dumps(payload)
return kwargs

def send(self, id_, text, identities, context={}):
logger.debug('Sending message: %s' % text)
def send(self, id_, text, identities, context=None):
logger.debug('Sending message: %s', text)
context = context or {}
kwargs = self.prepare_request(id_, text, identities, context)
r = requests.post(**kwargs)
if r.status_code != requests.codes.ok:
Expand Down
11 changes: 1 addition & 10 deletions rapidsms/backends/vumi/tests.py
Expand Up @@ -3,21 +3,12 @@

from django.test import TestCase
from django.core.urlresolvers import reverse
from django.conf.urls import patterns, url

from rapidsms.backends.vumi import views
from rapidsms.backends.vumi.outgoing import VumiBackend
from rapidsms.backends.vumi.forms import VumiForm
from rapidsms.tests.harness import RapidTest, CreateDataMixin


urlpatterns = patterns('',
url(r"^backend/vumi/$",
views.VumiBackendView.as_view(backend_name='vumi-backend'),
name='vumi-backend'),
)


class VumiFormTest(TestCase):

def setUp(self):
Expand Down Expand Up @@ -63,7 +54,7 @@ def test_get_incoming_data(self):

class VumiViewTest(RapidTest):

urls = 'rapidsms.backends.vumi.tests'
urls = 'rapidsms.backends.vumi.urls'
disable_phases = True

def setUp(self):
Expand Down

0 comments on commit fba494e

Please sign in to comment.