Exemplo n.º 1
0
class TestAccountApiClient(TestCase):
    API_URL = "http://example.com/go"
    AUTH_TOKEN = "auth_token"

    def setUp(self):
        self.account_backend = FakeAccountApi("go/", self.AUTH_TOKEN)
        self.session = TestSession()
        self.adapter = FakeAccountApiAdapter(self.account_backend)
        self.simulate_api_up()

    def simulate_api_down(self):
        self.session.mount(self.API_URL, TestAdapter("API is down", 500))

    def simulate_api_up(self):
        self.session.mount(self.API_URL, self.adapter)

    def make_client(self, auth_token=AUTH_TOKEN):
        return AccountApiClient(auth_token,
                                api_url=self.API_URL,
                                session=self.session)

    def assert_http_error(self, expected_status, func, *args, **kw):
        try:
            func(*args, **kw)
        except HTTPError as err:
            self.assertEqual(err.response.status_code, expected_status)
        else:
            self.fail("Expected HTTPError with status %s." %
                      (expected_status, ))

    def assert_jsonrpc_exception(self, f, *args, **kw):
        try:
            f(*args, **kw)
        except Exception as err:
            self.assertTrue(isinstance(err, JsonRpcException))
            self.assertTrue(isinstance(err.fault, unicode))
            self.assertTrue(isinstance(err.fault_code, int))
            self.assertTrue(isinstance(err.fault_string, unicode))
        return err

    def test_assert_http_error(self):
        self.session.mount("http://bad.example.com/", TestAdapter("", 500))

        def bad_req():
            r = self.session.get("http://bad.example.com/")
            r.raise_for_status()

        # Fails when no exception is raised.
        self.assertRaises(self.failureException, self.assert_http_error, 404,
                          lambda: None)

        # Fails when an HTTPError with the wrong status code is raised.
        self.assertRaises(self.failureException, self.assert_http_error, 404,
                          bad_req)

        # Passes when an HTTPError with the expected status code is raised.
        self.assert_http_error(500, bad_req)

        # Non-HTTPError exceptions aren't caught.
        def raise_error():
            raise ValueError()

        self.assertRaises(ValueError, self.assert_http_error, 404, raise_error)

    def test_default_session(self):
        client = AccountApiClient(self.AUTH_TOKEN)
        self.assertTrue(isinstance(client.session, Session))

    def test_default_api_url(self):
        client = AccountApiClient(self.AUTH_TOKEN)
        self.assertEqual(client.api_url, "https://go.vumi.org/api/v1/go")

    def test_auth_failure(self):
        client = self.make_client(auth_token="bogus_token")
        self.assert_http_error(403, client.campaigns)

    def test_jsonrpc_error_handling(self):
        client = self.make_client()
        self.account_backend.add_error_response("campaigns", [],
                                                fault="Fault",
                                                fault_code=8002,
                                                fault_string="Meep")
        err = self.assert_jsonrpc_exception(client.campaigns)
        self.assertEqual(err.fault, "Fault")
        self.assertEqual(err.fault_code, 8002)
        self.assertEqual(err.fault_string, "Meep")

    def test_campaigns(self):
        client = self.make_client()
        self.account_backend.add_success_response("campaigns", [],
                                                  fixtures.campaigns)
        self.assertEqual(client.campaigns(), fixtures.campaigns)

    def test_conversations(self):
        client = self.make_client()
        self.account_backend.add_success_response("conversations",
                                                  ["campaign-1"],
                                                  fixtures.conversations)
        self.assertEqual(client.conversations("campaign-1"),
                         fixtures.conversations)

    def test_channels(self):
        client = self.make_client()
        self.account_backend.add_success_response("channels", ["campaign-1"],
                                                  fixtures.channels)
        self.assertEqual(client.channels("campaign-1"), fixtures.channels)

    def test_routers(self):
        client = self.make_client()
        self.account_backend.add_success_response("routers", ["campaign-1"],
                                                  fixtures.routers)
        self.assertEqual(client.routers("campaign-1"), fixtures.routers)

    def test_routing_entries(self):
        client = self.make_client()
        self.account_backend.add_success_response("routing_entries",
                                                  ["campaign-1"],
                                                  fixtures.routing_entries)
        self.assertEqual(client.routing_entries("campaign-1"),
                         fixtures.routing_entries)

    def test_routing_table(self):
        client = self.make_client()
        self.account_backend.add_success_response("routing_table",
                                                  ["campaign-1"],
                                                  fixtures.routing_table)
        self.assertEqual(client.routing_table("campaign-1"),
                         fixtures.routing_table)

    def test_update_routing_tabel(self):
        client = self.make_client()
        self.account_backend.add_success_response(
            "update_routing_table", ["campaign-1", fixtures.routing_table],
            None)
        self.assertEqual(
            client.update_routing_table("campaign-1", fixtures.routing_table),
            None)
Exemplo n.º 2
0
class TestAccountApiClient(TestCase):
    API_URL = "http://example.com/go"
    AUTH_TOKEN = "auth_token"

    def setUp(self):
        self.account_backend = FakeAccountApi("go/", self.AUTH_TOKEN)
        self.session = TestSession()
        self.adapter = FakeAccountApiAdapter(self.account_backend)
        self.simulate_api_up()

    def simulate_api_down(self):
        self.session.mount(self.API_URL, TestAdapter("API is down", 500))

    def simulate_api_up(self):
        self.session.mount(self.API_URL, self.adapter)

    def make_client(self, auth_token=AUTH_TOKEN):
        return AccountApiClient(
            auth_token, api_url=self.API_URL, session=self.session)

    def assert_http_error(self, expected_status, func, *args, **kw):
        try:
            func(*args, **kw)
        except HTTPError as err:
            self.assertEqual(err.response.status_code, expected_status)
        else:
            self.fail(
                "Expected HTTPError with status %s." % (expected_status,))

    def assert_jsonrpc_exception(self, f, *args, **kw):
        try:
            f(*args, **kw)
        except Exception as err:
            self.assertTrue(isinstance(err, JsonRpcException))
            self.assertTrue(isinstance(err.fault, unicode))
            self.assertTrue(isinstance(err.fault_code, int))
            self.assertTrue(isinstance(err.fault_string, unicode))
        return err

    def test_assert_http_error(self):
        self.session.mount("http://bad.example.com/", TestAdapter("", 500))

        def bad_req():
            r = self.session.get("http://bad.example.com/")
            r.raise_for_status()

        # Fails when no exception is raised.
        self.assertRaises(
            self.failureException, self.assert_http_error, 404, lambda: None)

        # Fails when an HTTPError with the wrong status code is raised.
        self.assertRaises(
            self.failureException, self.assert_http_error, 404, bad_req)

        # Passes when an HTTPError with the expected status code is raised.
        self.assert_http_error(500, bad_req)

        # Non-HTTPError exceptions aren't caught.
        def raise_error():
            raise ValueError()

        self.assertRaises(ValueError, self.assert_http_error, 404, raise_error)

    def test_default_session(self):
        client = AccountApiClient(self.AUTH_TOKEN)
        self.assertTrue(isinstance(client.session, Session))

    def test_default_api_url(self):
        client = AccountApiClient(self.AUTH_TOKEN)
        self.assertEqual(
            client.api_url, "https://go.vumi.org/api/v1/go")

    def test_auth_failure(self):
        client = self.make_client(auth_token="bogus_token")
        self.assert_http_error(403, client.campaigns)

    def test_jsonrpc_error_handling(self):
        client = self.make_client()
        self.account_backend.add_error_response(
            "campaigns", [],
            fault="Fault", fault_code=8002, fault_string="Meep")
        err = self.assert_jsonrpc_exception(client.campaigns)
        self.assertEqual(err.fault, "Fault")
        self.assertEqual(err.fault_code, 8002)
        self.assertEqual(err.fault_string, "Meep")

    def test_campaigns(self):
        client = self.make_client()
        self.account_backend.add_success_response(
            "campaigns", [], fixtures.campaigns)
        self.assertEqual(client.campaigns(), fixtures.campaigns)

    def test_conversations(self):
        client = self.make_client()
        self.account_backend.add_success_response(
            "conversations", ["campaign-1"], fixtures.conversations)
        self.assertEqual(
            client.conversations("campaign-1"),
            fixtures.conversations)

    def test_channels(self):
        client = self.make_client()
        self.account_backend.add_success_response(
            "channels", ["campaign-1"], fixtures.channels)
        self.assertEqual(
            client.channels("campaign-1"),
            fixtures.channels)

    def test_routers(self):
        client = self.make_client()
        self.account_backend.add_success_response(
            "routers", ["campaign-1"], fixtures.routers)
        self.assertEqual(
            client.routers("campaign-1"),
            fixtures.routers)

    def test_routing_entries(self):
        client = self.make_client()
        self.account_backend.add_success_response(
            "routing_entries", ["campaign-1"], fixtures.routing_entries)
        self.assertEqual(
            client.routing_entries("campaign-1"),
            fixtures.routing_entries)

    def test_routing_table(self):
        client = self.make_client()
        self.account_backend.add_success_response(
            "routing_table", ["campaign-1"], fixtures.routing_table)
        self.assertEqual(
            client.routing_table("campaign-1"),
            fixtures.routing_table)

    def test_update_routing_tabel(self):
        client = self.make_client()
        self.account_backend.add_success_response(
            "update_routing_table", ["campaign-1", fixtures.routing_table],
            None)
        self.assertEqual(
            client.update_routing_table("campaign-1", fixtures.routing_table),
            None)
Exemplo n.º 3
0
class TestContactsApiClient(TestCase):
    API_URL = "http://example.com/go"
    AUTH_TOKEN = "auth_token"

    MAX_CONTACTS_PER_PAGE = 10

    def setUp(self):
        self.contacts_data = {}
        self.groups_data = {}
        self.contacts_backend = FakeContactsApi(
            "go/", self.AUTH_TOKEN, self.contacts_data, self.groups_data,
            contacts_limit=self.MAX_CONTACTS_PER_PAGE)
        self.session = TestSession()
        self.adapter = FakeContactsApiAdapter(self.contacts_backend)
        self.simulate_api_up()

    def simulate_api_down(self):
        self.session.mount(self.API_URL, TestAdapter("API is down", 500))

    def simulate_api_up(self):
        self.session.mount(self.API_URL, self.adapter)

    def make_client(self, auth_token=AUTH_TOKEN):
        return ContactsApiClient(
            auth_token, api_url=self.API_URL, session=self.session)

    def make_existing_contact(self, contact_data):
        existing_contact = make_contact_dict(contact_data)
        self.contacts_data[existing_contact[u"key"]] = existing_contact
        return existing_contact

    def make_existing_group(self, group_data):
        existing_group = make_group_dict(group_data)
        self.groups_data[existing_group[u'key']] = existing_group
        return existing_group

    def make_n_contacts(self, n, groups=None):
        contacts = []
        for i in range(n):
            data = {
                u"msisdn": u"+155564%d" % (i,),
                u"name": u"Arthur",
                u"surname": u"of Camelot",
            }
            if groups is not None:
                data["groups"] = groups
            contacts.append(self.make_existing_contact(data))
        return contacts

    def assert_contacts_equal(self, contacts_a, contacts_b):
        contacts_a.sort(key=lambda d: d['msisdn'])
        contacts_b.sort(key=lambda d: d['msisdn'])
        self.assertEqual(contacts_a, contacts_b)

    def assert_contact_status(self, contact_key, exists=True):
        exists_status = (contact_key in self.contacts_data)
        self.assertEqual(exists_status, exists)

    def assert_group_status(self, group_key, exists=True):
        exists_status = (group_key in self.groups_data)
        self.assertEqual(exists_status, exists)

    def assert_http_error(self, expected_status, func, *args, **kw):
        try:
            func(*args, **kw)
        except HTTPError as err:
            self.assertEqual(err.response.status_code, expected_status)
        else:
            self.fail(
                "Expected HTTPError with status %s." % (expected_status,))

    def assert_paged_exception(self, f, *args, **kw):
        try:
            f(*args, **kw)
        except Exception as err:
            self.assertTrue(isinstance(err, PagedException))
            self.assertTrue(isinstance(err.cursor, unicode))
            self.assertTrue(isinstance(err.error, Exception))
        return err

    def test_assert_http_error(self):
        self.session.mount("http://bad.example.com/", TestAdapter("", 500))

        def bad_req():
            r = self.session.get("http://bad.example.com/")
            r.raise_for_status()

        # Fails when no exception is raised.
        self.assertRaises(
            self.failureException, self.assert_http_error, 404, lambda: None)

        # Fails when an HTTPError with the wrong status code is raised.
        self.assertRaises(
            self.failureException, self.assert_http_error, 404, bad_req)

        # Passes when an HTTPError with the expected status code is raised.
        self.assert_http_error(500, bad_req)

        # Non-HTTPError exceptions aren't caught.
        def raise_error():
            raise ValueError()

        self.assertRaises(ValueError, self.assert_http_error, 404, raise_error)

    def test_default_session(self):
        import requests
        contacts = ContactsApiClient(self.AUTH_TOKEN)
        self.assertTrue(isinstance(contacts.session, requests.Session))

    def test_default_api_url(self):
        contacts = ContactsApiClient(self.AUTH_TOKEN)
        self.assertEqual(
            contacts.api_url, "https://go.vumi.org/api/v1/go")

    def test_auth_failure(self):
        contacts = self.make_client(auth_token="bogus_token")
        self.assert_http_error(403, contacts.get_contact, "foo")

    def test_contacts_single_page(self):
        [expected_contact] = self.make_n_contacts(1)
        contacts_api = self.make_client()
        [contact] = list(contacts_api.contacts())
        self.assertEqual(contact, expected_contact)

    def test_contacts_no_results(self):
        contacts_api = self.make_client()
        contacts = list(contacts_api.contacts())
        self.assertEqual(contacts, [])

    def test_contacts_multiple_pages(self):
        expected_contacts = self.make_n_contacts(
            self.MAX_CONTACTS_PER_PAGE + 1)
        contacts_api = self.make_client()
        contacts = list(contacts_api.contacts())
        self.assert_contacts_equal(contacts, expected_contacts)

    def test_contacts_multiple_pages_with_cursor(self):
        expected_contacts = self.make_n_contacts(
            self.MAX_CONTACTS_PER_PAGE + 1)
        contacts_api = self.make_client()
        first_page = contacts_api._api_request("GET", "contacts", "")
        cursor = first_page['cursor']
        contacts = list(contacts_api.contacts(start_cursor=cursor))
        contacts.extend(first_page['data'])
        self.assert_contacts_equal(contacts, expected_contacts)

    def test_contacts_multiple_pages_with_failure(self):
        expected_contacts = self.make_n_contacts(
            self.MAX_CONTACTS_PER_PAGE + 1)

        contacts_api = self.make_client()
        it = contacts_api.contacts()
        contacts = [it.next() for _ in range(self.MAX_CONTACTS_PER_PAGE)]
        self.simulate_api_down()
        err = self.assert_paged_exception(it.next)

        self.simulate_api_up()
        [last_contact] = list(contacts_api.contacts(start_cursor=err.cursor))

        self.assert_contacts_equal(
            contacts + [last_contact], expected_contacts)

    def test_create_contact(self):
        contacts = self.make_client()
        contact_data = {
            u"msisdn": u"+15556483",
            u"name": u"Arthur",
            u"surname": u"of Camelot",
        }
        contact = contacts.create_contact(contact_data)

        expected_contact = make_contact_dict(contact_data)
        # The key is generated for us.
        expected_contact[u"key"] = contact[u"key"]
        self.assertEqual(contact, expected_contact)
        self.assert_contact_status(contact[u"key"], exists=True)

    def test_create_contact_with_extras(self):
        contacts = self.make_client()
        contact_data = {
            u"msisdn": u"+15556483",
            u"name": u"Arthur",
            u"surname": u"of Camelot",
            u"extra": {
                u"quest": u"Grail",
                u"sidekick": u"Percy",
            },
        }
        contact = contacts.create_contact(contact_data)

        expected_contact = make_contact_dict(contact_data)
        # The key is generated for us.
        expected_contact[u"key"] = contact[u"key"]
        self.assertEqual(contact, expected_contact)
        self.assert_contact_status(contact[u"key"], exists=True)

    def test_create_contact_with_key(self):
        contacts = self.make_client()
        contact_data = {
            u"key": u"foo",
            u"msisdn": u"+15556483",
            u"name": u"Arthur",
            u"surname": u"of Camelot",
        }
        self.assert_http_error(400, contacts.create_contact, contact_data)
        self.assert_contact_status(u"foo", exists=False)

    def test_get_contact(self):
        contacts = self.make_client()
        existing_contact = self.make_existing_contact({
            u"msisdn": u"+15556483",
            u"name": u"Arthur",
            u"surname": u"of Camelot",
        })

        contact = contacts.get_contact(existing_contact[u"key"])
        self.assertEqual(contact, existing_contact)

    def test_get_contact_with_extras(self):
        contacts = self.make_client()
        existing_contact = self.make_existing_contact({
            u"msisdn": u"+15556483",
            u"name": u"Arthur",
            u"surname": u"of Camelot",
            u"extra": {
                u"quest": u"Grail",
                u"sidekick": u"Percy",
            },
        })

        contact = contacts.get_contact(existing_contact[u"key"])
        self.assertEqual(contact, existing_contact)

    def test_get_missing_contact(self):
        contacts = self.make_client()
        self.assert_http_error(404, contacts.get_contact, "foo")

    def test_get_contact_from_field(self):
        contacts = self.make_client()
        existing_contact = self.make_existing_contact({
            u"msisdn": u"+15556483",
            u"name": u"Arthur",
            u"surname": u"of Camelot",
        })

        contact = contacts.get_contact(msisdn='+15556483')
        self.assertEqual(contact, existing_contact)

    def test_get_contact_from_field_missing(self):
        contacts = self.make_client()
        self.make_existing_contact({
            u"msisdn": u"+15556483",
            u"name": u"Arthur",
            u"surname": u"of Camelot",
        })

        self.assert_http_error(
            400, contacts.get_contact, msisdn='+12345')

    def test_update_contact(self):
        contacts = self.make_client()
        existing_contact = self.make_existing_contact({
            u"msisdn": u"+15556483",
            u"name": u"Arthur",
            u"surname": u"of Camelot",
        })

        new_contact = existing_contact.copy()
        new_contact[u"surname"] = u"Pendragon"

        contact = contacts.update_contact(
            existing_contact[u"key"], {u"surname": u"Pendragon"})
        self.assertEqual(contact, new_contact)

    def test_update_contact_with_extras(self):
        contacts = self.make_client()
        existing_contact = self.make_existing_contact({
            u"msisdn": u"+15556483",
            u"name": u"Arthur",
            u"surname": u"of Camelot",
            u"extra": {
                u"quest": u"Grail",
                u"sidekick": u"Percy",
            },
        })

        new_contact = existing_contact.copy()
        new_contact[u"surname"] = u"Pendragon"
        new_contact[u"extra"] = {
            u"quest": u"lunch",
            u"knight": u"Lancelot",
        }

        contact = contacts.update_contact(existing_contact[u"key"], {
            u"surname": u"Pendragon",
            u"extra": {
                u"quest": u"lunch",
                u"knight": u"Lancelot",
            },
        })
        self.assertEqual(contact, new_contact)

    def test_update_missing_contact(self):
        contacts = self.make_client()
        self.assert_http_error(404, contacts.update_contact, "foo", {})

    def test_delete_contact(self):
        contacts = self.make_client()
        existing_contact = self.make_existing_contact({
            u"msisdn": u"+15556483",
            u"name": u"Arthur",
            u"surname": u"of Camelot",
        })

        self.assert_contact_status(existing_contact[u"key"], exists=True)
        contact = contacts.delete_contact(existing_contact[u"key"])
        self.assertEqual(contact, existing_contact)
        self.assert_contact_status(existing_contact[u"key"], exists=False)

    def test_delete_missing_contact(self):
        contacts = self.make_client()
        self.assert_http_error(404, contacts.delete_contact, "foo")

    def test_create_group(self):
        client = self.make_client()
        group_data = {
            u'name': u'Bob',
        }
        group = client.create_group(group_data)

        expected_group = make_group_dict(group_data)
        # The key is generated for us.
        expected_group[u'key'] = group[u'key']
        self.assertEqual(group, expected_group)
        self.assert_group_status(group[u'key'], exists=True)

    def test_create_smart_group(self):
        client = self.make_client()
        group_data = {
            u'name': u'Bob',
            u'query': u'test-query',
        }
        group = client.create_group(group_data)

        expected_group = make_group_dict(group_data)
        # The key is generated for us
        expected_group[u'key'] = group[u'key']
        self.assertEqual(group, expected_group)
        self.assert_group_status(group[u'key'], exists=True)

    def test_create_group_with_key(self):
        client = self.make_client()
        group_data = {
            u'key': u'foo',
            u'name': u'Bob',
            u'query': u'test-query',
        }
        self.assert_http_error(400, client.create_group, group_data)

    def test_get_group(self):
        client = self.make_client()
        existing_group = self.make_existing_group({
            u'name': 'Bob',
        })
        group = client.get_group(existing_group[u'key'])
        self.assertEqual(group, existing_group)

    def test_get_smart_group(self):
        client = self.make_client()
        existing_group = self.make_existing_group({
            u'name': 'Bob',
            u'query': 'test-query',
        })
        group = client.get_group(existing_group[u'key'])
        self.assertEqual(group, existing_group)

    def test_get_missing_group(self):
        client = self.make_client()
        self.assert_http_error(404, client.get_group, 'foo')

    def test_update_group(self):
        client = self.make_client()
        existing_group = self.make_existing_group({
            u'name': u'Bob',
        })

        new_group = existing_group.copy()
        new_group[u'name'] = u'Susan'

        group = client.update_group(existing_group[u'key'],
                                    {'name': 'Susan'})
        self.assertEqual(existing_group, group)
        self.assertEqual(group, new_group)

    def test_update_smart_group(self):
        client = self.make_client()
        existing_group = self.make_existing_group({
            u'name': u'Bob',
            u'query': u'test-query',
        })

        new_group = existing_group.copy()
        new_group[u'query'] = u'another-query'

        group = client.update_group(existing_group[u'key'],
                                    {'query': 'another-query'})
        self.assertEqual(existing_group, group)
        self.assertEqual(group, new_group)

    def test_update_missing_group(self):
        client = self.make_client()
        self.assert_http_error(404, client.update_group, 'foo', {})

    def test_delete_group(self):
        client = self.make_client()
        existing_group = self.make_existing_group({
            u'name': u'Bob'
        })

        self.assert_group_status(existing_group[u'key'], exists=True)
        group = client.delete_group(existing_group[u'key'])
        self.assertEqual(existing_group, group)
        self.assert_group_status(group[u'key'], exists=False)

    def test_delete_missing_group(self):
        client = self.make_client()
        self.assert_http_error(404, client.delete_group, 'foo')

    def test_group_contacts_multiple_pages_with_cursor(self):
        self.make_existing_group({
            u'name': 'key',
        })
        expected_contacts = self.make_n_contacts(
            self.MAX_CONTACTS_PER_PAGE + 1, groups=["key"])

        client = self.make_client()
        first_page = client._api_request("GET", "groups/key", "contacts")
        cursor = first_page['cursor']
        contacts = list(client.group_contacts(group_key="key",
                                              start_cursor=cursor))
        contacts.extend(first_page['data'])
        contacts.sort(key=lambda d: d['msisdn'])
        expected_contacts.sort(key=lambda d: d['msisdn'])
        self.assertEqual(contacts, expected_contacts)

    def test_group_contacts_multiple_pages(self):
        self.make_existing_group({
            u'name': 'key',
        })
        self.make_existing_group({
            u'name': 'diffkey',
        })
        expected_contacts = self.make_n_contacts(
            self.MAX_CONTACTS_PER_PAGE + 1, groups=["key"])
        self.make_existing_contact({
            u"msisdn": u"+1234567",
            u"name": u"Nancy",
            u"surname": u"of Camelot",
            u"groups": ["diffkey"],
        })

        client = self.make_client()
        contacts = list(client.group_contacts("key"))
        self.assert_contacts_equal(contacts, expected_contacts)

    def test_group_contacts_multiple_pages_with_failure(self):
        self.make_existing_group({
            u'name': 'key',
        })
        self.make_existing_group({
            u'name': 'diffkey',
        })
        expected_contacts = self.make_n_contacts(
            self.MAX_CONTACTS_PER_PAGE + 1, groups=["key"])
        self.make_existing_contact({
            u"msisdn": u"+1234567",
            u"name": u"Nancy",
            u"surname": u"of Camelot",
            u"groups": ["diffkey"],
        })

        contacts_api = self.make_client()
        it = contacts_api.group_contacts("key")
        contacts = [it.next() for _ in range(self.MAX_CONTACTS_PER_PAGE)]
        self.simulate_api_down()
        err = self.assert_paged_exception(it.next)

        self.simulate_api_up()
        [last_contact] = list(contacts_api.group_contacts(
            "key", start_cursor=err.cursor))

        self.assert_contacts_equal(
            contacts + [last_contact], expected_contacts)

    def test_group_contacts_none_found(self):
        self.make_existing_group({
            u'name': 'key',
        })
        self.make_existing_group({
            u'name': 'diffkey',
        })
        self.make_n_contacts(
            self.MAX_CONTACTS_PER_PAGE + 1, groups=["diffkey"])

        client = self.make_client()
        contacts = list(client.group_contacts("key"))
        self.assert_contacts_equal(contacts, [])
class TestContentStoreApiClient(TestCase):
    API_URL = "http://example.com/contentstore"
    AUTH_TOKEN = "auth_token"

    def setUp(self):
        self.messageset_data = {}
        self.schedule_data = {}
        self.message_data = {}
        self.binary_content_data = {}
        self.contentstore_backend = FakeContentStoreApi(
            "contentstore/", self.AUTH_TOKEN,
            messageset_data=self.messageset_data,
            schedule_data=self.schedule_data, message_data=self.message_data,
            binary_content_data=self.binary_content_data)
        self.session = TestSession()
        adapter = FakeContentStoreApiAdapter(self.contentstore_backend)
        self.session.mount(self.API_URL, adapter)
        self.client = self.make_client()

    def make_client(self, auth_token=AUTH_TOKEN):
        return ContentStoreApiClient(
            auth_token, api_url=self.API_URL, session=self.session)

    def make_existing_messageset(self, messageset_data):
        existing_messageset = make_messageset_dict(messageset_data)
        self.messageset_data[existing_messageset[u"id"]] = existing_messageset
        return existing_messageset

    def make_existing_message(self, message_data):
        existing_message = make_message_dict(message_data)
        self.message_data[existing_message[u"id"]] = existing_message
        return existing_message

    def make_existing_schedule(self, schedule_data):
        existing_schedule = make_schedule_dict(schedule_data)
        self.schedule_data[existing_schedule[u"id"]] = existing_schedule
        return existing_schedule

    def assert_messageset_status(self, messageset_id, exists=True):
        exists_status = (messageset_id in self.messageset_data)
        self.assertEqual(exists_status, exists)

    def assert_http_error(self, expected_status, func, *args, **kw):
        try:
            func(*args, **kw)
        except HTTPError as err:
            self.assertEqual(err.response.status_code, expected_status)
        else:
            self.fail(
                "Expected HTTPError with status %s." % (expected_status,))

    def test_assert_http_error(self):
        self.session.mount("http://bad.example.com/", TestAdapter("", 500))

        def bad_req():
            r = self.session.get("http://bad.example.com/")
            r.raise_for_status()

        # Fails when no exception is raised.
        self.assertRaises(
            self.failureException, self.assert_http_error, 404, lambda: None)

        # Fails when an HTTPError with the wrong status code is raised.
        self.assertRaises(
            self.failureException, self.assert_http_error, 404, bad_req)

        # Passes when an HTTPError with the expected status code is raised.
        self.assert_http_error(500, bad_req)

        # Non-HTTPError exceptions aren't caught.
        def raise_error():
            raise ValueError()

        self.assertRaises(ValueError, self.assert_http_error, 404, raise_error)

    def test_default_session(self):
        import requests
        contentstore = ContentStoreApiClient(self.AUTH_TOKEN)
        self.assertTrue(isinstance(contentstore.session, requests.Session))

    def test_default_api_url(self):
        contentstore = ContentStoreApiClient(self.AUTH_TOKEN)
        self.assertEqual(
            contentstore.api_url, "http://testserver/contentstore")

    def test_auth_failure(self):
        contentstore = self.make_client(auth_token="bogus_token")
        self.assert_http_error(403, contentstore.get_messagesets)

    def test_get_messageset(self):
        expected_messageset = self.make_existing_messageset({
            u"short_name": u"Full Set",
            u"notes": u"A full set of messages.",
            u"default_schedule": 1
        })
        [messageset] = list(self.client.get_messagesets())
        self.assertEqual(messageset, expected_messageset)

    def test_create_messageset(self):
        new_messageset = self.client.create_messageset({
            u"short_name": u"Full Set1",
            u"notes": u"A full and new set of messages.",
            u"default_schedule": 1
        })
        [messageset] = list(self.client.get_messagesets())
        self.assertEqual(
            messageset["short_name"], new_messageset["short_name"])
        self.assertEqual(
            messageset["notes"], new_messageset["notes"])
        self.assertEqual(
            messageset["default_schedule"], new_messageset["default_schedule"])

    def test_delete_messageset(self):
        new_messageset = self.make_existing_messageset({
            u"short_name": u"Full Set",
            u"notes": u"A full set of messages that will go.",
            u"default_schedule": 1
        })
        [messageset] = list(self.client.get_messagesets())
        self.assertEqual(messageset, new_messageset)
        self.client.delete_messageset(new_messageset["id"])
        messageset = list(self.client.get_messagesets())
        self.assertEqual(messageset, [])

    def test_get_message(self):
        expected_message = self.make_existing_message({
            "messageset": 1,
            "sequence_number": 2,
            "lang": "afr_ZA",
            "text_content": "Message two"
        })
        [message] = list(self.client.get_messages())
        self.assertEqual(message, expected_message)

    def test_get_message_content(self):
        expected_message = self.make_existing_message({
            "messageset": 1,
            "sequence_number": 2,
            "lang": "afr_ZA",
            "text_content": "Message two"
        })
        message = self.client.get_message_content(expected_message[u"id"])
        self.assertEqual(message, expected_message)

    def test_get_messageset_messages(self):
        new_messageset = self.client.create_messageset({
            u"short_name": u"Full Set1",
            u"notes": u"A full and new set of messages.",
            u"default_schedule": 1
        })
        messageset_id = new_messageset["id"]
        expected_message = self.make_existing_message({
            "messageset": messageset_id,
            "sequence_number": 2,
            "lang": "afr_ZA",
            "text_content": "Message two"
        })
        expected_message2 = self.make_existing_message({
            "messageset": messageset_id,
            "sequence_number": 1,
            "lang": "afr_ZA",
            "text_content": "Message one"
        })
        messageset_messages = self.client.get_messageset_messages(
            messageset_id)
        self.assertEqual(len(messageset_messages["messages"]), 2)
        # should be sorted by sequence_number
        self.assertEqual(messageset_messages["messages"][0]["id"],
                         expected_message2["id"])
        self.assertEqual(messageset_messages["messages"][1]["id"],
                         expected_message["id"])

    def test_create_message(self):
        new_message = self.client.create_message({
            "messageset": 1,
            "sequence_number": 2,
            "lang": "afr_ZA",
            "text_content": "Message two"
        })
        [message] = list(self.client.get_messages())
        self.assertEqual(message["text_content"],
                         new_message["text_content"])
        self.assertEqual(message["sequence_number"],
                         new_message["sequence_number"])
        self.assertEqual(message["messageset"],
                         new_message["messageset"])
        self.assertEqual(message["lang"],
                         new_message["lang"])

    def test_get_schedule(self):
        expected_schedule = self.make_existing_schedule({
            "minute": "1",
            "hour": "2",
            "day_of_week": "3",
            "day_of_month": "4",
            "month_of_year": "5",
        })
        [schedule] = list(self.client.get_schedules())
        self.assertEqual(schedule, expected_schedule)

    def test_create_schedule(self):
        new_schedule = self.client.create_schedule({
            "minute": "1",
            "hour": "2",
            "day_of_week": "3",
            "day_of_month": "4",
            "month_of_year": "5",
        })
        [schedule] = list(self.client.get_schedules())
        self.assertEqual(schedule["minute"],
                         new_schedule["minute"])
        self.assertEqual(schedule["hour"],
                         new_schedule["hour"])
        self.assertEqual(schedule["day_of_week"],
                         new_schedule["day_of_week"])
        self.assertEqual(schedule["day_of_month"],
                         new_schedule["day_of_month"])
        self.assertEqual(schedule["month_of_year"],
                         new_schedule["month_of_year"])
Exemplo n.º 5
0
class TestContactsApiClient(TestCase):
    API_URL = "http://example.com/go"
    AUTH_TOKEN = "auth_token"

    MAX_CONTACTS_PER_PAGE = 10

    def setUp(self):
        self.contacts_data = {}
        self.groups_data = {}
        self.contacts_backend = FakeContactsApi(
            "go/",
            self.AUTH_TOKEN,
            self.contacts_data,
            self.groups_data,
            contacts_limit=self.MAX_CONTACTS_PER_PAGE)
        self.session = TestSession()
        self.adapter = FakeContactsApiAdapter(self.contacts_backend)
        self.simulate_api_up()

    def simulate_api_down(self):
        self.session.mount(self.API_URL, TestAdapter("API is down", 500))

    def simulate_api_up(self):
        self.session.mount(self.API_URL, self.adapter)

    def make_client(self, auth_token=AUTH_TOKEN):
        return ContactsApiClient(auth_token,
                                 api_url=self.API_URL,
                                 session=self.session)

    def make_existing_contact(self, contact_data):
        existing_contact = make_contact_dict(contact_data)
        self.contacts_data[existing_contact[u"key"]] = existing_contact
        return existing_contact

    def make_existing_group(self, group_data):
        existing_group = make_group_dict(group_data)
        self.groups_data[existing_group[u'key']] = existing_group
        return existing_group

    def make_n_contacts(self, n, groups=None):
        contacts = []
        for i in range(n):
            data = {
                u"msisdn": u"+155564%d" % (i, ),
                u"name": u"Arthur",
                u"surname": u"of Camelot",
            }
            if groups is not None:
                data["groups"] = groups
            contacts.append(self.make_existing_contact(data))
        return contacts

    def assert_contacts_equal(self, contacts_a, contacts_b):
        contacts_a.sort(key=lambda d: d['msisdn'])
        contacts_b.sort(key=lambda d: d['msisdn'])
        self.assertEqual(contacts_a, contacts_b)

    def assert_contact_status(self, contact_key, exists=True):
        exists_status = (contact_key in self.contacts_data)
        self.assertEqual(exists_status, exists)

    def assert_group_status(self, group_key, exists=True):
        exists_status = (group_key in self.groups_data)
        self.assertEqual(exists_status, exists)

    def assert_http_error(self, expected_status, func, *args, **kw):
        try:
            func(*args, **kw)
        except HTTPError as err:
            self.assertEqual(err.response.status_code, expected_status)
        else:
            self.fail("Expected HTTPError with status %s." %
                      (expected_status, ))

    def assert_paged_exception(self, f, *args, **kw):
        try:
            f(*args, **kw)
        except Exception as err:
            self.assertTrue(isinstance(err, PagedException))
            self.assertTrue(isinstance(err.cursor, unicode))
            self.assertTrue(isinstance(err.error, Exception))
        return err

    def test_assert_http_error(self):
        self.session.mount("http://bad.example.com/", TestAdapter("", 500))

        def bad_req():
            r = self.session.get("http://bad.example.com/")
            r.raise_for_status()

        # Fails when no exception is raised.
        self.assertRaises(self.failureException, self.assert_http_error, 404,
                          lambda: None)

        # Fails when an HTTPError with the wrong status code is raised.
        self.assertRaises(self.failureException, self.assert_http_error, 404,
                          bad_req)

        # Passes when an HTTPError with the expected status code is raised.
        self.assert_http_error(500, bad_req)

        # Non-HTTPError exceptions aren't caught.
        def raise_error():
            raise ValueError()

        self.assertRaises(ValueError, self.assert_http_error, 404, raise_error)

    def test_default_session(self):
        import requests
        contacts = ContactsApiClient(self.AUTH_TOKEN)
        self.assertTrue(isinstance(contacts.session, requests.Session))

    def test_default_api_url(self):
        contacts = ContactsApiClient(self.AUTH_TOKEN)
        self.assertEqual(contacts.api_url, "https://go.vumi.org/api/v1/go")

    def test_auth_failure(self):
        contacts = self.make_client(auth_token="bogus_token")
        self.assert_http_error(403, contacts.get_contact, "foo")

    def test_contacts_single_page(self):
        [expected_contact] = self.make_n_contacts(1)
        contacts_api = self.make_client()
        [contact] = list(contacts_api.contacts())
        self.assertEqual(contact, expected_contact)

    def test_contacts_no_results(self):
        contacts_api = self.make_client()
        contacts = list(contacts_api.contacts())
        self.assertEqual(contacts, [])

    def test_contacts_multiple_pages(self):
        expected_contacts = self.make_n_contacts(self.MAX_CONTACTS_PER_PAGE +
                                                 1)
        contacts_api = self.make_client()
        contacts = list(contacts_api.contacts())
        self.assert_contacts_equal(contacts, expected_contacts)

    def test_contacts_multiple_pages_with_cursor(self):
        expected_contacts = self.make_n_contacts(self.MAX_CONTACTS_PER_PAGE +
                                                 1)
        contacts_api = self.make_client()
        first_page = contacts_api._api_request("GET", "contacts", "")
        cursor = first_page['cursor']
        contacts = list(contacts_api.contacts(start_cursor=cursor))
        contacts.extend(first_page['data'])
        self.assert_contacts_equal(contacts, expected_contacts)

    def test_contacts_multiple_pages_with_failure(self):
        expected_contacts = self.make_n_contacts(self.MAX_CONTACTS_PER_PAGE +
                                                 1)

        contacts_api = self.make_client()
        it = contacts_api.contacts()
        contacts = [it.next() for _ in range(self.MAX_CONTACTS_PER_PAGE)]
        self.simulate_api_down()
        err = self.assert_paged_exception(it.next)

        self.simulate_api_up()
        [last_contact] = list(contacts_api.contacts(start_cursor=err.cursor))

        self.assert_contacts_equal(contacts + [last_contact],
                                   expected_contacts)

    def test_create_contact(self):
        contacts = self.make_client()
        contact_data = {
            u"msisdn": u"+15556483",
            u"name": u"Arthur",
            u"surname": u"of Camelot",
        }
        contact = contacts.create_contact(contact_data)

        expected_contact = make_contact_dict(contact_data)
        # The key is generated for us.
        expected_contact[u"key"] = contact[u"key"]
        self.assertEqual(contact, expected_contact)
        self.assert_contact_status(contact[u"key"], exists=True)

    def test_create_contact_with_extras(self):
        contacts = self.make_client()
        contact_data = {
            u"msisdn": u"+15556483",
            u"name": u"Arthur",
            u"surname": u"of Camelot",
            u"extra": {
                u"quest": u"Grail",
                u"sidekick": u"Percy",
            },
        }
        contact = contacts.create_contact(contact_data)

        expected_contact = make_contact_dict(contact_data)
        # The key is generated for us.
        expected_contact[u"key"] = contact[u"key"]
        self.assertEqual(contact, expected_contact)
        self.assert_contact_status(contact[u"key"], exists=True)

    def test_create_contact_with_key(self):
        contacts = self.make_client()
        contact_data = {
            u"key": u"foo",
            u"msisdn": u"+15556483",
            u"name": u"Arthur",
            u"surname": u"of Camelot",
        }
        self.assert_http_error(400, contacts.create_contact, contact_data)
        self.assert_contact_status(u"foo", exists=False)

    def test_get_contact(self):
        contacts = self.make_client()
        existing_contact = self.make_existing_contact({
            u"msisdn":
            u"+15556483",
            u"name":
            u"Arthur",
            u"surname":
            u"of Camelot",
        })

        contact = contacts.get_contact(existing_contact[u"key"])
        self.assertEqual(contact, existing_contact)

    def test_get_contact_with_extras(self):
        contacts = self.make_client()
        existing_contact = self.make_existing_contact({
            u"msisdn": u"+15556483",
            u"name": u"Arthur",
            u"surname": u"of Camelot",
            u"extra": {
                u"quest": u"Grail",
                u"sidekick": u"Percy",
            },
        })

        contact = contacts.get_contact(existing_contact[u"key"])
        self.assertEqual(contact, existing_contact)

    def test_get_missing_contact(self):
        contacts = self.make_client()
        self.assert_http_error(404, contacts.get_contact, "foo")

    def test_get_contact_from_field(self):
        contacts = self.make_client()
        existing_contact = self.make_existing_contact({
            u"msisdn":
            u"+15556483",
            u"name":
            u"Arthur",
            u"surname":
            u"of Camelot",
        })

        contact = contacts.get_contact(msisdn='+15556483')
        self.assertEqual(contact, existing_contact)

    def test_get_contact_from_field_missing(self):
        contacts = self.make_client()
        self.make_existing_contact({
            u"msisdn": u"+15556483",
            u"name": u"Arthur",
            u"surname": u"of Camelot",
        })

        self.assert_http_error(400, contacts.get_contact, msisdn='+12345')

    def test_update_contact(self):
        contacts = self.make_client()
        existing_contact = self.make_existing_contact({
            u"msisdn":
            u"+15556483",
            u"name":
            u"Arthur",
            u"surname":
            u"of Camelot",
        })

        new_contact = existing_contact.copy()
        new_contact[u"surname"] = u"Pendragon"

        contact = contacts.update_contact(existing_contact[u"key"],
                                          {u"surname": u"Pendragon"})
        self.assertEqual(contact, new_contact)

    def test_update_contact_with_extras(self):
        contacts = self.make_client()
        existing_contact = self.make_existing_contact({
            u"msisdn": u"+15556483",
            u"name": u"Arthur",
            u"surname": u"of Camelot",
            u"extra": {
                u"quest": u"Grail",
                u"sidekick": u"Percy",
            },
        })

        new_contact = existing_contact.copy()
        new_contact[u"surname"] = u"Pendragon"
        new_contact[u"extra"] = {
            u"quest": u"lunch",
            u"knight": u"Lancelot",
        }

        contact = contacts.update_contact(
            existing_contact[u"key"], {
                u"surname": u"Pendragon",
                u"extra": {
                    u"quest": u"lunch",
                    u"knight": u"Lancelot",
                },
            })
        self.assertEqual(contact, new_contact)

    def test_update_missing_contact(self):
        contacts = self.make_client()
        self.assert_http_error(404, contacts.update_contact, "foo", {})

    def test_delete_contact(self):
        contacts = self.make_client()
        existing_contact = self.make_existing_contact({
            u"msisdn":
            u"+15556483",
            u"name":
            u"Arthur",
            u"surname":
            u"of Camelot",
        })

        self.assert_contact_status(existing_contact[u"key"], exists=True)
        contact = contacts.delete_contact(existing_contact[u"key"])
        self.assertEqual(contact, existing_contact)
        self.assert_contact_status(existing_contact[u"key"], exists=False)

    def test_delete_missing_contact(self):
        contacts = self.make_client()
        self.assert_http_error(404, contacts.delete_contact, "foo")

    def test_create_group(self):
        client = self.make_client()
        group_data = {
            u'name': u'Bob',
        }
        group = client.create_group(group_data)

        expected_group = make_group_dict(group_data)
        # The key is generated for us.
        expected_group[u'key'] = group[u'key']
        self.assertEqual(group, expected_group)
        self.assert_group_status(group[u'key'], exists=True)

    def test_create_smart_group(self):
        client = self.make_client()
        group_data = {
            u'name': u'Bob',
            u'query': u'test-query',
        }
        group = client.create_group(group_data)

        expected_group = make_group_dict(group_data)
        # The key is generated for us
        expected_group[u'key'] = group[u'key']
        self.assertEqual(group, expected_group)
        self.assert_group_status(group[u'key'], exists=True)

    def test_create_group_with_key(self):
        client = self.make_client()
        group_data = {
            u'key': u'foo',
            u'name': u'Bob',
            u'query': u'test-query',
        }
        self.assert_http_error(400, client.create_group, group_data)

    def test_get_group(self):
        client = self.make_client()
        existing_group = self.make_existing_group({
            u'name': 'Bob',
        })
        group = client.get_group(existing_group[u'key'])
        self.assertEqual(group, existing_group)

    def test_get_smart_group(self):
        client = self.make_client()
        existing_group = self.make_existing_group({
            u'name': 'Bob',
            u'query': 'test-query',
        })
        group = client.get_group(existing_group[u'key'])
        self.assertEqual(group, existing_group)

    def test_get_missing_group(self):
        client = self.make_client()
        self.assert_http_error(404, client.get_group, 'foo')

    def test_update_group(self):
        client = self.make_client()
        existing_group = self.make_existing_group({
            u'name': u'Bob',
        })

        new_group = existing_group.copy()
        new_group[u'name'] = u'Susan'

        group = client.update_group(existing_group[u'key'], {'name': 'Susan'})
        self.assertEqual(existing_group, group)
        self.assertEqual(group, new_group)

    def test_update_smart_group(self):
        client = self.make_client()
        existing_group = self.make_existing_group({
            u'name': u'Bob',
            u'query': u'test-query',
        })

        new_group = existing_group.copy()
        new_group[u'query'] = u'another-query'

        group = client.update_group(existing_group[u'key'],
                                    {'query': 'another-query'})
        self.assertEqual(existing_group, group)
        self.assertEqual(group, new_group)

    def test_update_missing_group(self):
        client = self.make_client()
        self.assert_http_error(404, client.update_group, 'foo', {})

    def test_delete_group(self):
        client = self.make_client()
        existing_group = self.make_existing_group({u'name': u'Bob'})

        self.assert_group_status(existing_group[u'key'], exists=True)
        group = client.delete_group(existing_group[u'key'])
        self.assertEqual(existing_group, group)
        self.assert_group_status(group[u'key'], exists=False)

    def test_delete_missing_group(self):
        client = self.make_client()
        self.assert_http_error(404, client.delete_group, 'foo')

    def test_group_contacts_multiple_pages_with_cursor(self):
        self.make_existing_group({
            u'name': 'key',
        })
        expected_contacts = self.make_n_contacts(self.MAX_CONTACTS_PER_PAGE +
                                                 1,
                                                 groups=["key"])

        client = self.make_client()
        first_page = client._api_request("GET", "groups/key", "contacts")
        cursor = first_page['cursor']
        contacts = list(
            client.group_contacts(group_key="key", start_cursor=cursor))
        contacts.extend(first_page['data'])
        contacts.sort(key=lambda d: d['msisdn'])
        expected_contacts.sort(key=lambda d: d['msisdn'])
        self.assertEqual(contacts, expected_contacts)

    def test_group_contacts_multiple_pages(self):
        self.make_existing_group({
            u'name': 'key',
        })
        self.make_existing_group({
            u'name': 'diffkey',
        })
        expected_contacts = self.make_n_contacts(self.MAX_CONTACTS_PER_PAGE +
                                                 1,
                                                 groups=["key"])
        self.make_existing_contact({
            u"msisdn": u"+1234567",
            u"name": u"Nancy",
            u"surname": u"of Camelot",
            u"groups": ["diffkey"],
        })

        client = self.make_client()
        contacts = list(client.group_contacts("key"))
        self.assert_contacts_equal(contacts, expected_contacts)

    def test_group_contacts_multiple_pages_with_failure(self):
        self.make_existing_group({
            u'name': 'key',
        })
        self.make_existing_group({
            u'name': 'diffkey',
        })
        expected_contacts = self.make_n_contacts(self.MAX_CONTACTS_PER_PAGE +
                                                 1,
                                                 groups=["key"])
        self.make_existing_contact({
            u"msisdn": u"+1234567",
            u"name": u"Nancy",
            u"surname": u"of Camelot",
            u"groups": ["diffkey"],
        })

        contacts_api = self.make_client()
        it = contacts_api.group_contacts("key")
        contacts = [it.next() for _ in range(self.MAX_CONTACTS_PER_PAGE)]
        self.simulate_api_down()
        err = self.assert_paged_exception(it.next)

        self.simulate_api_up()
        [last_contact
         ] = list(contacts_api.group_contacts("key", start_cursor=err.cursor))

        self.assert_contacts_equal(contacts + [last_contact],
                                   expected_contacts)

    def test_group_contacts_none_found(self):
        self.make_existing_group({
            u'name': 'key',
        })
        self.make_existing_group({
            u'name': 'diffkey',
        })
        self.make_n_contacts(self.MAX_CONTACTS_PER_PAGE + 1,
                             groups=["diffkey"])

        client = self.make_client()
        contacts = list(client.group_contacts("key"))
        self.assert_contacts_equal(contacts, [])
Exemplo n.º 6
0
class TestContentStoreApiClient(TestCase):
    API_URL = "http://example.com/contentstore"
    AUTH_TOKEN = "auth_token"

    def setUp(self):
        self.messageset_data = {}
        self.schedule_data = {}
        self.message_data = {}
        self.binary_content_data = {}
        self.contentstore_backend = FakeContentStoreApi(
            "contentstore/",
            self.AUTH_TOKEN,
            messageset_data=self.messageset_data,
            schedule_data=self.schedule_data,
            message_data=self.message_data,
            binary_content_data=self.binary_content_data)
        self.session = TestSession()
        adapter = FakeContentStoreApiAdapter(self.contentstore_backend)
        self.session.mount(self.API_URL, adapter)
        self.client = self.make_client()

    def make_client(self, auth_token=AUTH_TOKEN):
        return ContentStoreApiClient(auth_token,
                                     api_url=self.API_URL,
                                     session=self.session)

    def make_existing_messageset(self, messageset_data):
        existing_messageset = make_messageset_dict(messageset_data)
        self.messageset_data[existing_messageset[u"id"]] = existing_messageset
        return existing_messageset

    def make_existing_message(self, message_data):
        existing_message = make_message_dict(message_data)
        self.message_data[existing_message[u"id"]] = existing_message
        return existing_message

    def make_existing_schedule(self, schedule_data):
        existing_schedule = make_schedule_dict(schedule_data)
        self.schedule_data[existing_schedule[u"id"]] = existing_schedule
        return existing_schedule

    def assert_messageset_status(self, messageset_id, exists=True):
        exists_status = (messageset_id in self.messageset_data)
        self.assertEqual(exists_status, exists)

    def assert_http_error(self, expected_status, func, *args, **kw):
        try:
            func(*args, **kw)
        except HTTPError as err:
            self.assertEqual(err.response.status_code, expected_status)
        else:
            self.fail("Expected HTTPError with status %s." %
                      (expected_status, ))

    def test_assert_http_error(self):
        self.session.mount("http://bad.example.com/", TestAdapter("", 500))

        def bad_req():
            r = self.session.get("http://bad.example.com/")
            r.raise_for_status()

        # Fails when no exception is raised.
        self.assertRaises(self.failureException, self.assert_http_error, 404,
                          lambda: None)

        # Fails when an HTTPError with the wrong status code is raised.
        self.assertRaises(self.failureException, self.assert_http_error, 404,
                          bad_req)

        # Passes when an HTTPError with the expected status code is raised.
        self.assert_http_error(500, bad_req)

        # Non-HTTPError exceptions aren't caught.
        def raise_error():
            raise ValueError()

        self.assertRaises(ValueError, self.assert_http_error, 404, raise_error)

    def test_default_session(self):
        import requests
        contentstore = ContentStoreApiClient(self.AUTH_TOKEN)
        self.assertTrue(isinstance(contentstore.session, requests.Session))

    def test_default_api_url(self):
        contentstore = ContentStoreApiClient(self.AUTH_TOKEN)
        self.assertEqual(contentstore.api_url,
                         "http://testserver/contentstore")

    def test_auth_failure(self):
        contentstore = self.make_client(auth_token="bogus_token")
        self.assert_http_error(403, contentstore.get_messagesets)

    def test_get_messageset(self):
        expected_messageset = self.make_existing_messageset({
            u"short_name":
            u"Full Set",
            u"notes":
            u"A full set of messages.",
            u"default_schedule":
            1
        })
        [messageset] = list(self.client.get_messagesets())
        self.assertEqual(messageset, expected_messageset)

    def test_create_messageset(self):
        new_messageset = self.client.create_messageset({
            u"short_name": u"Full Set1",
            u"notes": u"A full and new set of messages.",
            u"default_schedule": 1
        })
        [messageset] = list(self.client.get_messagesets())
        self.assertEqual(messageset["short_name"],
                         new_messageset["short_name"])
        self.assertEqual(messageset["notes"], new_messageset["notes"])
        self.assertEqual(messageset["default_schedule"],
                         new_messageset["default_schedule"])

    def test_delete_messageset(self):
        new_messageset = self.make_existing_messageset({
            u"short_name": u"Full Set",
            u"notes": u"A full set of messages that will go.",
            u"default_schedule": 1
        })
        [messageset] = list(self.client.get_messagesets())
        self.assertEqual(messageset, new_messageset)
        self.client.delete_messageset(new_messageset["id"])
        messageset = list(self.client.get_messagesets())
        self.assertEqual(messageset, [])

    def test_get_message(self):
        expected_message = self.make_existing_message({
            "messageset":
            1,
            "sequence_number":
            2,
            "lang":
            "afr_ZA",
            "text_content":
            "Message two"
        })
        [message] = list(self.client.get_messages())
        self.assertEqual(message, expected_message)

    def test_get_message_content(self):
        expected_message = self.make_existing_message({
            "messageset":
            1,
            "sequence_number":
            2,
            "lang":
            "afr_ZA",
            "text_content":
            "Message two"
        })
        message = self.client.get_message_content(expected_message[u"id"])
        self.assertEqual(message, expected_message)

    def test_get_messageset_messages(self):
        new_messageset = self.client.create_messageset({
            u"short_name": u"Full Set1",
            u"notes": u"A full and new set of messages.",
            u"default_schedule": 1
        })
        messageset_id = new_messageset["id"]
        expected_message = self.make_existing_message({
            "messageset":
            messageset_id,
            "sequence_number":
            2,
            "lang":
            "afr_ZA",
            "text_content":
            "Message two"
        })
        expected_message2 = self.make_existing_message({
            "messageset":
            messageset_id,
            "sequence_number":
            1,
            "lang":
            "afr_ZA",
            "text_content":
            "Message one"
        })
        messageset_messages = self.client.get_messageset_messages(
            messageset_id)
        self.assertEqual(len(messageset_messages["messages"]), 2)
        # should be sorted by sequence_number
        self.assertEqual(messageset_messages["messages"][0]["id"],
                         expected_message2["id"])
        self.assertEqual(messageset_messages["messages"][1]["id"],
                         expected_message["id"])

    def test_create_message(self):
        new_message = self.client.create_message({
            "messageset": 1,
            "sequence_number": 2,
            "lang": "afr_ZA",
            "text_content": "Message two"
        })
        [message] = list(self.client.get_messages())
        self.assertEqual(message["text_content"], new_message["text_content"])
        self.assertEqual(message["sequence_number"],
                         new_message["sequence_number"])
        self.assertEqual(message["messageset"], new_message["messageset"])
        self.assertEqual(message["lang"], new_message["lang"])

    def test_get_schedule(self):
        expected_schedule = self.make_existing_schedule({
            "minute": "1",
            "hour": "2",
            "day_of_week": "3",
            "day_of_month": "4",
            "month_of_year": "5",
        })
        [schedule] = list(self.client.get_schedules())
        self.assertEqual(schedule, expected_schedule)

    def test_create_schedule(self):
        new_schedule = self.client.create_schedule({
            "minute": "1",
            "hour": "2",
            "day_of_week": "3",
            "day_of_month": "4",
            "month_of_year": "5",
        })
        [schedule] = list(self.client.get_schedules())
        self.assertEqual(schedule["minute"], new_schedule["minute"])
        self.assertEqual(schedule["hour"], new_schedule["hour"])
        self.assertEqual(schedule["day_of_week"], new_schedule["day_of_week"])
        self.assertEqual(schedule["day_of_month"],
                         new_schedule["day_of_month"])
        self.assertEqual(schedule["month_of_year"],
                         new_schedule["month_of_year"])