Ejemplo n.º 1
0
class ConsumerTest(TestCase):
    fixtures = ['models.json']

    def setUp(self):
        self.consumer = Consumer()
        self.consumer.name = "Piston Test Consumer"
        self.consumer.description = "A test consumer for Piston."
        self.consumer.user = User.objects.get(pk=3)
        self.consumer.generate_random_codes()

    def _pre_test_email(self):
        template = "piston/mails/consumer_%s.txt" % self.consumer.status
        try:
            loader.render_to_string(template, {
                'consumer': self.consumer,
                'user': self.consumer.user
            })
            return True
        except TemplateDoesNotExist:
            """
            They haven't set up the templates, which means they might not want
            these emails sent.
            """
            return False

    def test_create_pending(self):
        """ Ensure creating a pending Consumer sends proper emails """
        # Verify if the emails can be sent
        if not self._pre_test_email():
            return

        # If it's pending we should have two messages in the outbox; one
        # to the consumer and one to the site admins.
        if len(settings.ADMINS):
            self.assertEquals(len(mail.outbox), 2)
        else:
            self.assertEquals(len(mail.outbox), 1)

        expected = "Your API Consumer for example.com is awaiting approval."
        self.assertEquals(mail.outbox[0].subject, expected)

    def test_delete_consumer(self):
        """ Ensure deleting a Consumer sends a cancel email """

        # Clear out the outbox before we test for the cancel email.
        mail.outbox = []

        # Delete the consumer, which should fire off the cancel email.
        self.consumer.delete()

        # Verify if the emails can be sent
        if not self._pre_test_email():
            return

        self.assertEquals(len(mail.outbox), 1)
        expected = "Your API Consumer for example.com has been canceled."
        self.assertEquals(mail.outbox[0].subject, expected)
Ejemplo n.º 2
0
class ConsumerTest(TestCase):
    fixtures = ['models.json']

    def setUp(self):
        self.consumer = Consumer()
        self.consumer.name = "Piston Test Consumer"
        self.consumer.description = "A test consumer for Piston."
        self.consumer.user = User.objects.get(pk=3)
        self.consumer.generate_random_codes()

    def _pre_test_email(self):
        template = "piston/mails/consumer_%s.txt" % self.consumer.status
        try:
            loader.render_to_string(template, {
                'consumer': self.consumer,
                'user': self.consumer.user
            })
            return True
        except TemplateDoesNotExist:
            """
            They haven't set up the templates, which means they might not want
            these emails sent.
            """
            return False

    def test_create_pending(self):
        """ Ensure creating a pending Consumer sends proper emails """
        # Verify if the emails can be sent
        if not self._pre_test_email():
            return

        # If it's pending we should have two messages in the outbox; one
        # to the consumer and one to the site admins.
        if len(settings.ADMINS):
            self.assertEquals(len(mail.outbox), 2)
        else:
            self.assertEquals(len(mail.outbox), 1)

        expected = "Your API Consumer for example.com is awaiting approval."
        self.assertEquals(mail.outbox[0].subject, expected)

    def test_delete_consumer(self):
        """ Ensure deleting a Consumer sends a cancel email """

        # Clear out the outbox before we test for the cancel email.
        mail.outbox = []

        # Delete the consumer, which should fire off the cancel email.
        self.consumer.delete()

        # Verify if the emails can be sent
        if not self._pre_test_email():
            return

        self.assertEquals(len(mail.outbox), 1)
        expected = "Your API Consumer for example.com has been canceled."
        self.assertEquals(mail.outbox[0].subject, expected)
Ejemplo n.º 3
0
class OAuthTests(APIMainTest):
    """ 
    OAuthTest Does oauth handshake test and gives derived test classes tests the possibility
    to do OAuth resource requests. 
    """
    signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1()

    def setUp(self):
        super(OAuthTests, self).setUp()

        self.consumer = Consumer(name='Test Consumer',
                                 description='Test',
                                 status='accepted')
        self.consumer.generate_random_codes()
        self.consumer.save()
        self.oa_atoken = None
        self.test_handshake()

    def tearDown(self):
        super(OAuthTests, self).tearDown()
        self.consumer.delete()

    def do_oauth_request(self, url, parameters={}, http_method='POST'):

        oaconsumer = oauth.OAuthConsumer(self.consumer.key,
                                         self.consumer.secret)

        request = oauth.OAuthRequest.from_consumer_and_token(
            oaconsumer,
            http_method=http_method,
            token=self.oa_atoken,
            http_url='http://testserver%s' % url)

        request.parameters.update(parameters)
        request.sign_request(self.signature_method, oaconsumer, self.oa_atoken)

        if http_method == 'POST':
            response = self.client.post(url, request.parameters)
        else:
            response = self.client.get(url, request.parameters)

        return response

    def test_handshake(self):
        '''Test the OAuth handshake procedure
        '''
        oaconsumer = oauth.OAuthConsumer(self.consumer.key,
                                         self.consumer.secret)

        # Get a request key...
        request = oauth.OAuthRequest.from_consumer_and_token(
            oaconsumer, http_url='http://testserver/oauth/request_token/')
        request.sign_request(self.signature_method, oaconsumer, None)
        response = self.client.get('/oauth/request_token/', request.parameters)
        oatoken = oauth.OAuthToken.from_string(response.content)

        token = Token.objects.get(key=oatoken.key, token_type=Token.REQUEST)
        self.assertEqual(token.secret, oatoken.secret)

        # Simulate user authentication...
        self.failUnless(self.client.login(username='******', password='******'))
        request = oauth.OAuthRequest.from_token_and_callback(
            token=oatoken,
            callback='http://printer.example.com/request_token_ready',
            http_url='http://testserver/oauth/authorize/')
        request.sign_request(self.signature_method, oaconsumer, oatoken)

        # Request the login page
        # TODO: Parse the response to make sure all the fields exist
        #        response = self.client.get('/api/oauth/authorize', {
        #            'oauth_token': oatoken.key,
        #            'oauth_callback': 'http://printer.example.com/request_token_ready',
        #            })

        response = self.client.post(
            '/oauth/authorize/', {
                'oauth_token':
                oatoken.key,
                'oauth_callback':
                'http://printer.example.com/request_token_ready',
                'csrf_signature':
                OAuthAuthenticationForm.get_csrf_signature(
                    settings.SECRET_KEY, oatoken.key),
                'authorize_access':
                1,
            })

        # Response should be a redirect...
        self.assertEqual(302, response.status_code)
        self.assertEqual(
            'http://printer.example.com/request_token_ready?oauth_token=' +
            oatoken.key, response['Location'])

        # Obtain access token...
        request = oauth.OAuthRequest.from_consumer_and_token(
            oaconsumer,
            token=oatoken,
            http_url='http://testserver/oauth/access_token/')
        request.sign_request(self.signature_method, oaconsumer, oatoken)
        response = self.client.get('/oauth/access_token/', request.parameters)

        oa_atoken = oauth.OAuthToken.from_string(response.content)
        atoken = Token.objects.get(key=oa_atoken.key, token_type=Token.ACCESS)
        self.assertEqual(atoken.secret, oa_atoken.secret)
        # save the acces token so we can do oauth requests
        self.oa_atoken = oa_atoken
Ejemplo n.º 4
0
class OAuthTests(MainTests):
    signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1()

    def setUp(self):
        super(OAuthTests, self).setUp()

        self.consumer = Consumer(name='Test Consumer',
                                 description='Test',
                                 status='accepted')
        self.consumer.generate_random_codes()
        self.consumer.save()

    def tearDown(self):
        super(OAuthTests, self).tearDown()
        self.consumer.delete()

    def test_handshake(self):
        '''Test the OAuth handshake procedure
        '''
        oaconsumer = oauth.OAuthConsumer(self.consumer.key,
                                         self.consumer.secret)

        # Get a request key...
        request = oauth.OAuthRequest.from_consumer_and_token(
            oaconsumer, http_url='http://testserver/api/oauth/request_token')
        request.sign_request(self.signature_method, oaconsumer, None)

        response = self.client.get('/api/oauth/request_token',
                                   request.parameters)
        oatoken = oauth.OAuthToken.from_string(response.content)

        token = Token.objects.get(key=oatoken.key, token_type=Token.REQUEST)
        self.assertEqual(token.secret, oatoken.secret)

        # Simulate user authentication...
        self.failUnless(self.client.login(username='******', password='******'))
        request = oauth.OAuthRequest.from_token_and_callback(
            token=oatoken,
            callback='http://printer.example.com/request_token_ready',
            http_url='http://testserver/api/oauth/authorize')
        request.sign_request(self.signature_method, oaconsumer, oatoken)

        # Request the login page
        # TODO: Parse the response to make sure all the fields exist
        #        response = self.client.get('/api/oauth/authorize', {
        #            'oauth_token': oatoken.key,
        #            'oauth_callback': 'http://printer.example.com/request_token_ready',
        #            })

        response = self.client.post(
            '/api/oauth/authorize', {
                'oauth_token':
                oatoken.key,
                'oauth_callback':
                'http://printer.example.com/request_token_ready',
                'csrf_signature':
                OAuthAuthenticationForm.get_csrf_signature(
                    settings.SECRET_KEY, oatoken.key),
                'authorize_access':
                1,
            })

        # Response should be a redirect...
        self.assertEqual(302, response.status_code)
        self.assertEqual(
            'http://printer.example.com/request_token_ready?oauth_token=' +
            oatoken.key, response['Location'])

        # Obtain access token...
        request = oauth.OAuthRequest.from_consumer_and_token(
            oaconsumer,
            token=oatoken,
            http_url='http://testserver/api/oauth/access_token')
        request.sign_request(self.signature_method, oaconsumer, oatoken)
        response = self.client.get('/api/oauth/access_token',
                                   request.parameters)

        oa_atoken = oauth.OAuthToken.from_string(response.content)
        atoken = Token.objects.get(key=oa_atoken.key, token_type=Token.ACCESS)
        self.assertEqual(atoken.secret, oa_atoken.secret)
Ejemplo n.º 5
0
class OAuthTests(MainTests):
    signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1()

    def setUp(self):
        super(OAuthTests, self).setUp()

        self.consumer = Consumer(name="Test Consumer", description="Test", status="accepted")
        self.consumer.generate_random_codes()
        self.consumer.save()

    def tearDown(self):
        super(OAuthTests, self).tearDown()
        self.consumer.delete()

    def test_handshake(self):
        """Test the OAuth handshake procedure
        """
        oaconsumer = oauth.OAuthConsumer(self.consumer.key, self.consumer.secret)

        # Get a request key...
        request = oauth.OAuthRequest.from_consumer_and_token(
            oaconsumer, http_url="http://testserver/api/oauth/request_token"
        )
        request.sign_request(self.signature_method, oaconsumer, None)

        response = self.client.get("/api/oauth/request_token", request.parameters)
        oatoken = oauth.OAuthToken.from_string(response.content)

        token = Token.objects.get(key=oatoken.key, token_type=Token.REQUEST)
        self.assertEqual(token.secret, oatoken.secret)

        # Simulate user authentication...
        self.failUnless(self.client.login(username="******", password="******"))
        request = oauth.OAuthRequest.from_token_and_callback(
            token=oatoken,
            callback="http://printer.example.com/request_token_ready",
            http_url="http://testserver/api/oauth/authorize",
        )
        request.sign_request(self.signature_method, oaconsumer, oatoken)

        # Request the login page
        # TODO: Parse the response to make sure all the fields exist
        #        response = self.client.get('/api/oauth/authorize', {
        #            'oauth_token': oatoken.key,
        #            'oauth_callback': 'http://printer.example.com/request_token_ready',
        #            })

        response = self.client.post(
            "/api/oauth/authorize",
            {
                "oauth_token": oatoken.key,
                "oauth_callback": "http://printer.example.com/request_token_ready",
                "csrf_signature": OAuthAuthenticationForm.get_csrf_signature(settings.SECRET_KEY, oatoken.key),
                "authorize_access": 1,
            },
        )

        # Response should be a redirect...
        self.assertEqual(302, response.status_code)
        self.assertEqual(
            "http://printer.example.com/request_token_ready?oauth_token=" + oatoken.key, response["Location"]
        )

        # Obtain access token...
        request = oauth.OAuthRequest.from_consumer_and_token(
            oaconsumer, token=oatoken, http_url="http://testserver/api/oauth/access_token"
        )
        request.sign_request(self.signature_method, oaconsumer, oatoken)
        response = self.client.get("/api/oauth/access_token", request.parameters)

        oa_atoken = oauth.OAuthToken.from_string(response.content)
        atoken = Token.objects.get(key=oa_atoken.key, token_type=Token.ACCESS)
        self.assertEqual(atoken.secret, oa_atoken.secret)
Ejemplo n.º 6
0
class OAuthTests(APIMainTest):
    """ 
    OAuthTest Does oauth handshake test and gives derived test classes tests the possibility
    to do OAuth resource requests. 
    """
    signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1()

    def setUp(self):
        super(OAuthTests, self).setUp()

        self.consumer = Consumer(name='Test Consumer', description='Test', status='accepted')
        self.consumer.generate_random_codes()
        self.consumer.save()
        self.oa_atoken = None 
        self.test_handshake()

    def tearDown(self):
        super(OAuthTests, self).tearDown()
        self.consumer.delete()

    def do_oauth_request(self, url , parameters = {} , http_method = 'POST' ):
        
        oaconsumer = oauth.OAuthConsumer(self.consumer.key, self.consumer.secret)

        request = oauth.OAuthRequest.from_consumer_and_token(
                oaconsumer, 
                http_method=http_method, 
                token=self.oa_atoken,
                http_url='http://testserver%s' % url )
        
        request.parameters.update( parameters )
        request.sign_request(self.signature_method, oaconsumer, self.oa_atoken )
        
        if http_method == 'POST':
            response = self.client.post( url, request.parameters )
        else :
            response = self.client.get( url, request.parameters )

        return response

    def test_handshake(self):
        '''Test the OAuth handshake procedure
        '''
        oaconsumer = oauth.OAuthConsumer(self.consumer.key, self.consumer.secret)

        # Get a request key...
        request = oauth.OAuthRequest.from_consumer_and_token(oaconsumer,
                http_url='http://testserver/oauth/request_token/'
                )
        request.sign_request(self.signature_method, oaconsumer, None)
        response = self.client.get('/oauth/request_token/', request.parameters)
        oatoken = oauth.OAuthToken.from_string(response.content)

        token = Token.objects.get(key=oatoken.key, token_type=Token.REQUEST)
        self.assertEqual(token.secret, oatoken.secret)

        # Simulate user authentication...
        self.failUnless(self.client.login(username='******', password='******'))
        request = oauth.OAuthRequest.from_token_and_callback(token=oatoken,
                callback='http://printer.example.com/request_token_ready',
                http_url='http://testserver/oauth/authorize/')
        request.sign_request(self.signature_method, oaconsumer, oatoken)

        # Request the login page
# TODO: Parse the response to make sure all the fields exist
#        response = self.client.get('/api/oauth/authorize', {
#            'oauth_token': oatoken.key,
#            'oauth_callback': 'http://printer.example.com/request_token_ready',
#            })

        response = self.client.post('/oauth/authorize/', {
            'oauth_token': oatoken.key,
            'oauth_callback': 'http://printer.example.com/request_token_ready',
            'csrf_signature': OAuthAuthenticationForm.get_csrf_signature(settings.SECRET_KEY, oatoken.key),
            'authorize_access': 1,
            })

        # Response should be a redirect...
        self.assertEqual(302, response.status_code)
        self.assertEqual('http://printer.example.com/request_token_ready?oauth_token='+oatoken.key, response['Location'])

        # Obtain access token...
        request = oauth.OAuthRequest.from_consumer_and_token(oaconsumer, token=oatoken,
                http_url='http://testserver/oauth/access_token/')
        request.sign_request(self.signature_method, oaconsumer, oatoken)
        response = self.client.get('/oauth/access_token/', request.parameters)

        oa_atoken = oauth.OAuthToken.from_string(response.content)
        atoken = Token.objects.get(key=oa_atoken.key, token_type=Token.ACCESS)
        self.assertEqual(atoken.secret, oa_atoken.secret)
        # save the acces token so we can do oauth requests
        self.oa_atoken = oa_atoken
Ejemplo n.º 7
0
class ApiTestCase(TestCase):
    fixtures = ['basic.json']

    def setUp(self):
        # Although client.put now exists in Django 1.1, it is unusable for us:
        # http://code.djangoproject.com/ticket/11371
        # So, we override it with our own working version:
        self.client.put = curry(self.client.post, REQUEST_METHOD='PUT')
        # TODO: Use standard consumer?
        self.consumer = Consumer(name='Test Consumer',
                                 description='Test',
                                 status='accepted')
        self.consumer.key = "123"
        self.consumer.secret = "123"
        self.consumer.save()
        self.admin_requester = OAuthRequester(self, 'admin', 'admin',
                                              self.consumer)
        self.test1_requester = OAuthRequester(self, 'test1', 'test1',
                                              self.consumer)

    def tearDown(self):
        self.consumer.delete()

    def testUser(self):
        # Test a user with missing fields
        response = self.client.get('/api/1.0/admin/')
        self.assertEqual(response.status_code, 200)
        # TODO: Genericize URL stuff
        self.assertEqual(
            json.loads(response.content), {
                'user-name': 'admin',
                'last-name': '',
                'notes-ref': {
                    'href': 'http://example.com/admin/notes/',
                    'api-ref': 'http://example.com/api/1.0/admin/notes/'
                },
                'current-sync-guid': '5ec1f08a-19f1-416a-b086-ff22f6f7c9e8',
                'first-name': '',
                'latest-sync-revision': -1
            })

        # Test a user with all fields, with and without auth
        for client in self.client, self.test1_requester:
            response = client.get('/api/1.0/test1/')
            self.assertEqual(response.status_code, 200)
            self.assertEqual(
                json.loads(response.content), {
                    'user-name': 'test1',
                    'last-name': 'Doe',
                    'notes-ref': {
                        'href': 'http://example.com/test1/notes/',
                        'api-ref': 'http://example.com/api/1.0/test1/notes/'
                    },
                    'current-sync-guid':
                    '1886ae92-6c46-43e8-86c0-bb74df89f66c',
                    'first-name': 'John',
                    'latest-sync-revision': -1
                })

    def testUserBadMethods(self):
        # PUT/POST/DELETE are not allowed
        # POST and PUT need some dummy data, otherwise piston replies "Bad Request"
        response = self.admin_requester.put('/api/1.0/admin/',
                                            '{ "test" : "test" }')
        self.assertEqual(response.status_code, 405)
        self.assertEqual(response['Allow'], 'GET')
        response = self.admin_requester.post('/api/1.0/admin/',
                                             '{ "test" : "test" }')
        self.assertEqual(response.status_code, 405)
        self.assertEqual(response['Allow'], 'GET')
        response = self.admin_requester.delete('/api/1.0/admin/')
        self.assertEqual(response.status_code, 405)
        self.assertEqual(response['Allow'], 'GET')

    def testRootNoAuth(self):
        # Test w/out auth
        response = self.client.get('/api/1.0/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(
            json.loads(response.content), {
                'api-version':
                '1.0',
                'oauth_access_token_url':
                'http://example.com/oauth/access_token/',
                'oauth_authorize_url':
                'http://example.com/oauth/authenticate/',
                'oauth_request_token_url':
                'http://example.com/oauth/request_token/'
            })

    def testRootWithAuth(self):
        # Test w/ auth (admin user)
        response = self.admin_requester.get('/api/1.0/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(
            json.loads(response.content), {
                'api-version':
                '1.0',
                'user-ref': {
                    'href': 'http://example.com/admin/',
                    'api-ref': 'http://example.com/api/1.0/admin/'
                },
                'oauth_access_token_url':
                'http://example.com/oauth/access_token/',
                'oauth_authorize_url':
                'http://example.com/oauth/authenticate/',
                'oauth_request_token_url':
                'http://example.com/oauth/request_token/'
            })

        # Test w/ auth (test1 user)
        response = self.test1_requester.get('/api/1.0/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(
            json.loads(response.content), {
                'api-version':
                '1.0',
                'user-ref': {
                    'href': 'http://example.com/test1/',
                    'api-ref': 'http://example.com/api/1.0/test1/'
                },
                'oauth_access_token_url':
                'http://example.com/oauth/access_token/',
                'oauth_authorize_url':
                'http://example.com/oauth/authenticate/',
                'oauth_request_token_url':
                'http://example.com/oauth/request_token/'
            })

    def testRootBadMethods(self):
        # PUT/POST/DELETE are not allowed
        # POST and PUT need some dummy data, otherwise piston replies "Bad Request"
        response = self.admin_requester.put('/api/1.0/', '{ "test" : "test" }')
        self.assertEqual(response.status_code, 405)
        self.assertEqual(response['Allow'], 'GET')
        response = self.admin_requester.post('/api/1.0/',
                                             '{ "test" : "test" }')
        self.assertEqual(response.status_code, 405)
        self.assertEqual(response['Allow'], 'GET')
        response = self.admin_requester.delete('/api/1.0/')
        self.assertEqual(response.status_code, 405)
        self.assertEqual(response['Allow'], 'GET')

    def testNotes(self):
        noteJson = '{"guid": "002e91a2-2e34-4e2d-bf88-21def49a7705",' + \
                   '"title" :"New Note 6",' + \
                   '"note-content" :"New Note 6\\nDescribe youre note <b>here</b>.",' + \
                   '"note-content-version" : 0.2,' + \
                   '"last-change-date" : "2009-04-19T21:29:23.2197340-07:00",' + \
                   '"last-metadata-change-date" : "2009-04-19T21:29:23.2197340-07:00",' + \
                   '"create-date" : "2008-03-06T13:44:46.4342680-08:00",' + \
                   '"last-sync-revision" : 0,' + \
                   '"open-on-startup" : false,' + \
                   '"tags" : ["tag1","tag2"]' + \
                   '}'
        notesJson = '{"latest-sync-revision" : 0,' + \
                    '"note-changes" : [' + noteJson + ']}'

        full_notes = {
            "notes": [{
                "guid": "002e91a2-2e34-4e2d-bf88-21def49a7705",
                "ref": {
                    "href": "http://example.com/admin/notes/1/",
                    "api-ref": "http://example.com/api/1.0/admin/notes/1/"
                },
                "title": "New Note 6"
            }],
            "latest-sync-revision":
            0
        }
        public_notes = {"notes": [], "latest-sync-revision": 0}

        response = self.admin_requester.put('/api/1.0/admin/notes/', notesJson)
        self.assertEqual(json.loads(response.content), full_notes)

        response = self.client.get('/api/1.0/admin/notes/')
        self.assertEqual(response.status_code, 401)

        response = self.admin_requester.get('/api/1.0/admin/notes/')
        self.assertEqual(json.loads(response.content), full_notes)

        response = self.test1_requester.get('/api/1.0/admin/notes/')
        self.assertEqual(json.loads(response.content), public_notes)

        # Make a note public
        # TODO: Test collections with a mix of public and private notes
        admin = User.objects.get(username='******')
        note = Note.objects.get(author=admin,
                                guid="002e91a2-2e34-4e2d-bf88-21def49a7705")
        note.permissions = 1
        note.save()

        response = self.test1_requester.get('/api/1.0/admin/notes/')
        self.assertEqual(json.loads(response.content), full_notes)

    def testNotesBadMethods(self):
        # POST/DELETE are not allowed
        # POST and PUT need some dummy data, otherwise piston replies "Bad Request"
        response = self.admin_requester.post('/api/1.0/admin/notes/',
                                             '{ "test" : "test" }')
        self.assertEqual(response.status_code, 405)
        self.assertEqual(response['Allow'], 'GET, PUT')
        response = self.admin_requester.delete('/api/1.0/admin/notes/')
        self.assertEqual(response.status_code, 405)
        self.assertEqual(response['Allow'], 'GET, PUT')

    def testNote(self):
        note = {
            "note-content": "New Note 6\\nDescribe youre note <b>here</b>.",
            "open-on-startup": False,
            "last-metadata-change-date": "2010-01-28T18:30:45Z",
            "tags": ["tag1", "tag2"],
            "title": "New Note 6",
            "create-date": "2009-08-28T18:30:45Z",
            "pinned": False,
            "last-sync-revision": 0,
            "last-change-date": "2010-01-28T18:30:45Z",
            "guid": "002e91a2-2e34-4e2d-bf88-21def49a7705"
        }

        # Put testing data into the database
        notesJson = '{"latest-sync-revision" : 0,' + \
                    '"note-changes" : [' + json.dumps(note) + ']}'
        response = self.admin_requester.put('/api/1.0/admin/notes/', notesJson)

        # Strip the domain from the api-ref
        noteAPIRef = json.loads(response.content)['notes'][0]['ref']['api-ref']
        noteAPIRef = noteAPIRef.partition('/api/')[1] + noteAPIRef.partition(
            '/api/')[2]
        response = self.admin_requester.get(noteAPIRef)
        responseNote = json.loads(response.content)['note'][0]

        self.assertEqual(response.status_code, 200)
        self.assertEqual(responseNote, note)

    def testNoteBadMethods(self):
        # PUT/POST/DELETE are not allowed
        # POST and PUT need some dummy data, otherwise piston replies "Bad Request"
        response = self.admin_requester.put('/api/1.0/admin/notes/1/',
                                            '{ "test" : "test" }')
        self.assertEqual(response.status_code, 405)
        self.assertEqual(response['Allow'], 'GET')
        response = self.admin_requester.post('/api/1.0/admin/notes/1/',
                                             '{ "test" : "test" }')
        self.assertEqual(response.status_code, 405)
        self.assertEqual(response['Allow'], 'GET')
        response = self.admin_requester.delete('/api/1.0/admin/notes/1/')
        self.assertEqual(response.status_code, 405)
        self.assertEqual(response['Allow'], 'GET')