Example #1
0
    def test_singular_resource(self, *a):
        View = get_test_view_class()
        config = _create_config()
        root = config.get_root_resource()
        root.add('thing', view=View)
        grandpa = root.add('grandpa', 'grandpas', view=View)
        wife = grandpa.add('wife', view=View, renderer='string')
        wife.add('child', 'children', view=View)

        config.begin()
        app = TestApp(config.make_wsgi_app())

        self.assertEqual(
            '/grandpas/1/wife',
            route_path('grandpa:wife', testing.DummyRequest(), grandpa_id=1)
        )

        self.assertEqual(
            '/grandpas/1',
            route_path('grandpa', testing.DummyRequest(), id=1)
        )

        self.assertEqual(
            '/grandpas/1/wife/children/2',
            route_path('grandpa_wife:child', testing.DummyRequest(),
                       grandpa_id=1, id=2)
        )

        self.assertEqual(app.put('/grandpas').body, six.b('update_many'))
        self.assertEqual(app.head('/grandpas').body, six.b(''))
        self.assertEqual(app.options('/grandpas').body, six.b(''))

        self.assertEqual(app.delete('/grandpas/1').body, six.b('delete'))
        self.assertEqual(app.head('/grandpas/1').body, six.b(''))
        self.assertEqual(app.options('/grandpas/1').body, six.b(''))

        self.assertEqual(app.put('/thing').body, six.b('replace'))
        self.assertEqual(app.patch('/thing').body, six.b('update'))
        self.assertEqual(app.delete('/thing').body, six.b('delete'))
        self.assertEqual(app.head('/thing').body, six.b(''))
        self.assertEqual(app.options('/thing').body, six.b(''))

        self.assertEqual(app.put('/grandpas/1/wife').body, six.b('replace'))
        self.assertEqual(app.patch('/grandpas/1/wife').body, six.b('update'))
        self.assertEqual(app.delete('/grandpas/1/wife').body, six.b('delete'))
        self.assertEqual(app.head('/grandpas/1/wife').body, six.b(''))
        self.assertEqual(app.options('/grandpas/1/wife').body, six.b(''))

        self.assertEqual(six.b('show'), app.get('/grandpas/1').body)
        self.assertEqual(six.b('show'), app.get('/grandpas/1/wife').body)
        self.assertEqual(
            six.b('show'), app.get('/grandpas/1/wife/children/1').body)
Example #2
0
    def test_singular_resource(self, *a):
        View = get_test_view_class()
        config = _create_config()
        root = config.get_root_resource()
        root.add('thing', view=View)
        grandpa = root.add('grandpa', 'grandpas', view=View)
        wife = grandpa.add('wife', view=View, renderer='string')
        wife.add('child', 'children', view=View)

        config.begin()
        app = TestApp(config.make_wsgi_app())

        self.assertEqual(
            '/grandpas/1/wife',
            route_path('grandpa:wife', testing.DummyRequest(), grandpa_id=1)
        )

        self.assertEqual(
            '/grandpas/1',
            route_path('grandpa', testing.DummyRequest(), id=1)
        )

        self.assertEqual(
            '/grandpas/1/wife/children/2',
            route_path('grandpa_wife:child', testing.DummyRequest(),
                       grandpa_id=1, id=2)
        )

        self.assertEqual(app.put('/grandpas').body, six.b('update_many'))
        self.assertEqual(app.head('/grandpas').body, six.b(''))
        self.assertEqual(app.options('/grandpas').body, six.b(''))

        self.assertEqual(app.delete('/grandpas/1').body, six.b('delete'))
        self.assertEqual(app.head('/grandpas/1').body, six.b(''))
        self.assertEqual(app.options('/grandpas/1').body, six.b(''))

        self.assertEqual(app.put('/thing').body, six.b('replace'))
        self.assertEqual(app.patch('/thing').body, six.b('update'))
        self.assertEqual(app.delete('/thing').body, six.b('delete'))
        self.assertEqual(app.head('/thing').body, six.b(''))
        self.assertEqual(app.options('/thing').body, six.b(''))

        self.assertEqual(app.put('/grandpas/1/wife').body, six.b('replace'))
        self.assertEqual(app.patch('/grandpas/1/wife').body, six.b('update'))
        self.assertEqual(app.delete('/grandpas/1/wife').body, six.b('delete'))
        self.assertEqual(app.head('/grandpas/1/wife').body, six.b(''))
        self.assertEqual(app.options('/grandpas/1/wife').body, six.b(''))

        self.assertEqual(six.b('show'), app.get('/grandpas/1').body)
        self.assertEqual(six.b('show'), app.get('/grandpas/1/wife').body)
        self.assertEqual(
            six.b('show'), app.get('/grandpas/1/wife/children/1').body)
Example #3
0
def test_web_basic():
    """The web basic test
    """
    class TestService(Service):
        """The test service
        """
        @get('/test/get')
        @post('/test/post')
        @put('/test/put')
        @delete('/test/delete')
        @head('/test/head')
        @patch('/test/patch')
        @options('/test/options')
        @endpoint()
        def test(self):
            """Test
            """
            return 'OK'

        @get('/test2')
        @endpoint()
        def test2(self, param):
            """Test 2
            """
            return 'OK'

    adapter = WebAdapter()
    server = Server([ TestService() ], [ adapter ])
    server.start()
    # Test
    app = TestApp(adapter)
    rsp = app.get('/test', expect_errors = True)
    assert rsp.status_int == 404
    rsp = app.get('/test/get')
    assert rsp.status_int == 200 and rsp.content_type == 'text/plain' and rsp.text == 'OK'
    rsp = app.post('/test/post')
    assert rsp.status_int == 200 and rsp.content_type == 'text/plain' and rsp.text == 'OK'
    rsp = app.put('/test/put')
    assert rsp.status_int == 200 and rsp.content_type == 'text/plain' and rsp.text == 'OK'
    rsp = app.delete('/test/delete')
    assert rsp.status_int == 200 and rsp.content_type == 'text/plain' and rsp.text == 'OK'
    rsp = app.head('/test/head')
    assert rsp.status_int == 200 and rsp.content_type == 'text/plain'
    rsp = app.patch('/test/patch')
    assert rsp.status_int == 200 and rsp.content_type == 'text/plain' and rsp.text == 'OK'
    rsp = app.options('/test/options')
    assert rsp.status_int == 200 and rsp.content_type == 'text/plain' and rsp.text == 'OK'
    # Too many parameters
    rsp = app.get('/test/get?a=1', expect_errors = True)
    assert rsp.status_int == 400
    # Lack of parameters
    rsp = app.get('/test2', expect_errors = True)
    assert rsp.status_int == 400
    rsp = app.get('/test2?param=1')
    assert rsp.status_int == 200 and rsp.text == 'OK'
Example #4
0
class TestIntegration(unittest.TestCase):

    def setUp(self):
        app = Application('tangled.web.tests:test.ini')
        app.mount_resource('user', UserResource, '/users/<id>')
        self.app = TestApp(app)
        self._original_data = copy.deepcopy(Users.data)

    def tearDown(self):
        Users.data = self._original_data

    def test_get(self):
        self.assertEqual(Users.get(1)['name'], 'Alice')
        response = self.app.get('/users/1')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json['name'], 'Alice')
        self.assertEqual(Users.get(1)['name'], 'Alice')

    def test_put(self):
        self.assertEqual(Users.get(2)['name'], 'Bob')
        response = self.app.put('/users/2', params={'name': 'Bobby'})
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json['name'], 'Bobby')
        self.assertEqual(Users.get(2)['name'], 'Bobby')

    def test_patch(self):
        self.assertEqual(Users.get(2)['name'], 'Bob')
        response = self.app.patch('/users/2', params={'name': 'Bobby'})
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json['name'], 'Bobby')
        self.assertEqual(Users.get(2)['name'], 'Bobby')

    def test_patch_json(self):
        self.assertEqual(Users.get(2)['name'], 'Bob')
        response = self.app.patch_json('/users/2', params={'name': 'Bobby'})
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json['name'], 'Bobby')
        self.assertEqual(Users.get(2)['name'], 'Bobby')
Example #5
0
class KuleTests(unittest.TestCase):
    """
    Functionality tests for kule.
    """
    def setUp(self):
        self.kule = Kule(database="kule_test",
                         collections=["documents"])
        self.app = TestApp(self.kule.get_bottle_app())
        self.collection = self.kule.get_collection("documents")

    def tearDown(self):
        self.collection.remove()

    def test_empty_response(self):
        response = self.app.get("/documents")
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json,
                         {'meta': {
                             'total_count': 0,
                             'limit': 20,
                             'offset': 0},
                          'objects': []})

    def test_get_list(self):
        self.collection.insert({"foo": "bar"})
        response = self.app.get("/documents")
        self.assertEqual(response.status_code, 200)
        objects = response.json.get("objects")
        meta = response.json.get("meta")
        self.assertEqual(1, len(objects))
        self.assertEqual(1, meta.get("total_count"))
        record = first(objects)
        self.assertEqual(record.get("foo"), "bar")

    def test_post_list(self):
        response = self.app.post("/documents", json.dumps({"foo": "bar"}),
                                 content_type="application/json")
        self.assertEqual(201, response.status_code)
        object_id = response.json.get("_id")
        query = {"_id": bson.ObjectId(object_id)}
        self.assertEqual(1, self.collection.find(query).count())
        record = self.collection.find_one(query)
        self.assertEqual(record.get("foo"), "bar")

    def test_get_detail(self):
        object_id = str(self.collection.insert({"foo": "bar"}))
        response = self.app.get("/documents/%s" % object_id)
        self.assertEqual(200, response.status_code)
        self.assertEqual(response.json, {'_id': object_id,
                                         'foo': 'bar'})

    def test_put_detail(self):
        object_id = self.collection.insert({"foo": "bar"})
        response = self.app.put("/documents/%s" % object_id,
                                json.dumps({"bar": "foo"}),
                                content_type="application/json")
        self.assertEqual(response.status_code, 202)
        record = self.collection.find_one({"_id": object_id})
        self.assertEqual(record, {'_id': object_id,
                                  'bar': 'foo'})

    def test_patch_detail(self):
        object_id = self.collection.insert({"foo": "bar"})
        response = self.app.patch("/documents/%s" % object_id,
                                  json.dumps({"bar": "foo"}),
                                  content_type="application/json")
        self.assertEqual(response.status_code, 202)
        record = self.collection.find_one({"_id": object_id})
        self.assertEqual(record, {'_id': object_id,
                                  'foo': 'bar',
                                  'bar': 'foo'})

    def test_delete_detail(self):
        object_id = self.collection.insert({"foo": "bar"})
        response = self.app.delete("/documents/%s" % object_id)
        self.assertEqual(response.status_code, 204)
        self.assertEqual(0, self.collection.find(
            {"_id": object_id}).count())

    def test_magical_methods(self):
        class MyKule(Kule):
            def get_documents_list(self):
                return {"foo": "bar"}
        kule = MyKule(database="kule_test", collections=["documents"])
        app = TestApp(kule.get_bottle_app())
        self.assertEqual(app.get("/documents").json, {"foo": "bar"})

    def test_bundler(self):
        class MyKule(Kule):
            def build_documents_bundle(self, document):
                return {"_title": document.get("title")}
        kule = MyKule(database="kule_test", collections=["documents"])
        app = TestApp(kule.get_bottle_app())
        object_id = kule.get_collection("documents").insert({"title": "bar"})
        result = app.get("/documents/%s" % object_id).json
        self.assertEqual(result ,{"_title": "bar"})
Example #6
0
class TestResourceRecognition(Test):
    def setUp(self):
        from nefertari.resource import add_resource_routes
        self.config = _create_config()
        add_resource_routes(
            self.config,
            DummyCrudRenderedView,
            'message',
            'messages',
            renderer='string'
        )
        self.config.begin()
        self.app = TestApp(self.config.make_wsgi_app())
        self.collection_path = '/messages'
        self.collection_name = 'messages'
        self.member_path = '/messages/{id}'
        self.member_name = 'message'

    def test_get_collection(self):
        self.assertEqual(self.app.get('/messages').body, six.b('index'))

    @mock.patch('nefertari.renderers.JsonRendererFactory._trigger_events')
    def test_get_collection_json(self, mock_trigger):
        from nefertari.resource import add_resource_routes
        mock_trigger.side_effect = lambda x, y: x
        add_resource_routes(
            self.config,
            DummyCrudRenderedView,
            'message',
            'messages',
            renderer='json'
        )
        self.assertEqual(self.app.get('/messages').body, six.b('"index"'))

    @mock.patch('nefertari.renderers.JsonRendererFactory._trigger_events')
    def test_get_collection_nefertari_json(self, mock_trigger):
        from nefertari.resource import add_resource_routes
        mock_trigger.side_effect = lambda x, y: x
        add_resource_routes(
            self.config,
            DummyCrudRenderedView,
            'message',
            'messages',
            renderer='nefertari_json'
        )
        self.assertEqual(self.app.get('/messages').body, six.b('"index"'))

    def test_get_collection_no_renderer(self):
        from nefertari.resource import add_resource_routes
        add_resource_routes(
            self.config, DummyCrudRenderedView, 'message', 'messages')
        self.assertRaises(ValueError, self.app.get, '/messages')

    def test_post_collection(self):
        result = self.app.post('/messages').body
        self.assertEqual(result, six.b('create'))

    def test_head_collection(self):
        response = self.app.head('/messages')
        self.assertEqual(response.body, six.b(''))
        self.assertEqual(response.status_code, 200)
        self.assertTrue(response.headers)

    def test_get_member(self):
        result = self.app.get('/messages/1').body
        self.assertEqual(result, six.b('show'))

    def test_head_member(self):
        response = self.app.head('/messages/1')
        self.assertEqual(response.body, six.b(''))
        self.assertEqual(response.status_code, 200)
        self.assertTrue(response.headers)

    def test_put_member(self):
        result = self.app.put('/messages/1').body
        self.assertEqual(result, six.b('replace'))

    def test_patch_member(self):
        result = self.app.patch('/messages/1').body
        self.assertEqual(result, six.b('update'))

    def test_delete_member(self):
        result = self.app.delete('/messages/1').body
        self.assertEqual(result, six.b('delete'))
Example #7
0
class TestCustomPredicates(TestCase):
    def setUp(self):
        from pyramid.renderers import JSONP
        self.config = testing.setUp()
        self.config.add_renderer('jsonp', JSONP(param_name='callback'))
        self.config.include("cornice")
        self.authz_policy = ACLAuthorizationPolicy()
        self.config.set_authorization_policy(self.authz_policy)

        self.authn_policy = AuthTktAuthenticationPolicy('$3kr1t')
        self.config.set_authentication_policy(self.authn_policy)
        self.config.add_route_predicate('position', employeeType)
        self.config.scan("tests.test_resource_custom_predicates")
        self.app = TestApp(CatchErrors(self.config.make_wsgi_app()))

    def tearDown(self):
        testing.tearDown()

    def test_get_resource_predicates(self):
        # Tests for resource with name 'Supervisors'
        res = self.app.get('/company/employees?position=supervisor').json
        self.assertEqual(res[0], 'Supervisors list get')
        res = self.app.get('/company/employees/2?position=supervisor').json
        self.assertEqual(res['get'], 'Supervisors')

        # Tests for resource with name 'Topmanagers'
        res = self.app.get('/company/employees?position=topmanager').json
        self.assertEqual(res[0], 'Topmanagers list get')
        res = self.app.get('/company/employees/1?position=topmanager').json
        self.assertEqual(res['get'], 'Topmanagers')

    def test_post_resource_predicates(self):
        # Tests for resource with name 'Supervisors'
        supervisor_data = {
            'name': 'Jimmy Arrow',
            'position': 'supervisor',
            'salary': 50000
        }
        res = self.app.post('/company/employees', supervisor_data).json
        self.assertEqual(res[0], 'Supervisors list post')

        # Tests for resource with name 'Topmanagers'
        topmanager_data = {
            'name': 'Jimmy Arrow',
            'position': 'topmanager',
            'salary': 30000
        }
        res = self.app.post('/company/employees', topmanager_data).json
        self.assertEqual(res[0], 'Topmanagers list post')

    def test_patch_resource_predicates(self):
        # Tests for resource with name 'Supervisors'
        res = self.app.patch('/company/employees/2?position=supervisor', {
            'salary': 1001
        }).json
        self.assertEqual(res['patch'], 'Supervisors')

        # Tests for resource with name 'Topmanagers'
        res = self.app.patch('/company/employees/1?position=topmanager', {
            'salary': 2002
        }).json
        self.assertEqual(res['patch'], 'Topmanagers')

    def test_put_resource_predicates(self):
        # Tests for resource with name 'Supervisors'
        supervisor_data = {'position': 'supervisor', 'salary': 53000}
        res = self.app.put('/company/employees/2', supervisor_data).json
        self.assertEqual(res['put'], 'Supervisors')

        # Tests for resource with name 'Topmanagers'
        topmanager_data = {'position': 'topmanager', 'salary': 33000}
        res = self.app.put('/company/employees/1', topmanager_data).json
        self.assertEqual(res['put'], 'Topmanagers')
class TestCustomPredicates(TestCase):

    def setUp(self):
        from pyramid.renderers import JSONP
        self.config = testing.setUp()
        self.config.add_renderer('jsonp', JSONP(param_name='callback'))
        self.config.include("cornice")
        self.authz_policy = ACLAuthorizationPolicy()
        self.config.set_authorization_policy(self.authz_policy)

        self.authn_policy = AuthTktAuthenticationPolicy('$3kr1t')
        self.config.set_authentication_policy(self.authn_policy)
        self.config.add_route_predicate('position', employeeType)
        self.config.scan("tests.test_resource_custom_predicates")
        self.app = TestApp(CatchErrors(self.config.make_wsgi_app()))

    def tearDown(self):
        testing.tearDown()

    def test_get_resource_predicates(self):
        # Tests for resource with name 'Supervisors'
        res = self.app.get('/company/employees?position=supervisor').json
        self.assertEqual(res[0], 'Supervisors list get')
        res = self.app.get('/company/employees/2?position=supervisor').json
        self.assertEqual(res['get'], 'Supervisors')

        # Tests for resource with name 'Topmanagers'
        res = self.app.get('/company/employees?position=topmanager').json
        self.assertEqual(res[0], 'Topmanagers list get')
        res = self.app.get('/company/employees/1?position=topmanager').json
        self.assertEqual(res['get'], 'Topmanagers')

    def test_post_resource_predicates(self):
        # Tests for resource with name 'Supervisors'
        supervisor_data = {
            'name': 'Jimmy Arrow',
            'position': 'supervisor',
            'salary': 50000
        }
        res = self.app.post('/company/employees', supervisor_data).json
        self.assertEqual(res[0], 'Supervisors list post')

        # Tests for resource with name 'Topmanagers'
        topmanager_data = {
            'name': 'Jimmy Arrow',
            'position': 'topmanager',
            'salary': 30000
        }
        res = self.app.post('/company/employees', topmanager_data).json
        self.assertEqual(res[0], 'Topmanagers list post')

    def test_patch_resource_predicates(self):
        # Tests for resource with name 'Supervisors'
        res = self.app.patch(
            '/company/employees/2?position=supervisor',
            {'salary': 1001}
        ).json
        self.assertEqual(res['patch'], 'Supervisors')

        # Tests for resource with name 'Topmanagers'
        res = self.app.patch(
            '/company/employees/1?position=topmanager',
            {'salary': 2002}
        ).json
        self.assertEqual(res['patch'], 'Topmanagers')

    def test_put_resource_predicates(self):
        # Tests for resource with name 'Supervisors'
        supervisor_data = {
            'position': 'supervisor',
            'salary': 53000
        }
        res = self.app.put('/company/employees/2', supervisor_data).json
        self.assertEqual(res['put'], 'Supervisors')

        # Tests for resource with name 'Topmanagers'
        topmanager_data = {
            'position': 'topmanager',
            'salary': 33000
        }
        res = self.app.put('/company/employees/1', topmanager_data).json
        self.assertEqual(res['put'], 'Topmanagers')
Example #9
0
class TestAdminAPI(unittest.TestCase):
    """Tests API functions associated with VM actions.
       Note that all tests are in-process, we don't actually start a HTTP server,
       but we do communicate HTTP requests and responses.
       Outside of setUp, all calls to the database should be via the HTTP API.
    """
    def setUp(self):
        """Launch pserve using webtest with test settings"""
        self.appconf = get_app(test_ini)
        self.app = TestApp(self.appconf)

        #This seems to be how we suppress cookies being remembered.
        #All auth via BasicAuth - never return the session cookie.
        self.app.cookiejar.set_policy(DefaultCookiePolicy(allowed_domains=[]))

        # This sets global var "engine" - in the case of SQLite this is a fresh RAM
        # DB each time.  If we only did this on class instantiation the database would
        # be dirty and one test could influence another.
        # TODO - add a test that tests this.
        server.choose_engine("SQLite")

        # Punch in new administrator account with direct server call
        # This will implicitly generate the tables.
        user_id = server.create_user("administrators", "administrator", "administrator", "administrator")
        #server.touch_to_add_user_group("administrator", "administrators")
        server.touch_to_add_password(user_id, "adminpass")

        self.app.authorization = ('Basic', ('administrator', 'adminpass'))

    """Unauthenticated API functions."""

    def test_home_view(self):
        """ Home view should respond with 200 OK, as anyone can call it. """
        response = self.app.get('/', status=200)

    """Admin API functions.

    The admin functions in the API are primarily used by system utilities.
    Creating a user and password, and validating against the database in
    order to receive an access token, are prerequisites for using functions
    in later sections of the API. These can only be called by an
    administrator."""

    def test_create_user(self):
        """ Creating a user should respond with 200 OK.
        Retrieving the user should respond likewise. """

        newuser = { 'type': 'users',
                    'handle': '*****@*****.**',
                    'name': 'Test User',
                    'username':'******'} #Should be ignored!

        self.app.put('/users/testuser', newuser, status=200)

        newuser2 = self.app.get('/users/testuser', status=200).json

        #Fold real user name into dict and remove type
        newuser['username'] = '******'
        del(newuser['type'])

        #User id should be 1, but we'll ignore it.  Ditto credits.
        del(newuser2['id'])
        del(newuser2['credits'])

        self.assertEqual(newuser2, newuser)

        #There should be no user named 'ignored'
        self.app.get('/users/ignored', status=404)

    def test_get_my_details(self):
        """As an admin, fetching /users/<me> should produce exactly the
           same result as fetching /user
        """

        r1 = self.app.get('/users/administrator')
        r2 = self.app.get('/user')

        self.assertEqual(r1.json, r2.json)

    #!! Not implemented.
    @unittest.skip
    def test_update_user(self):
        """ Updating a user. Retrieve details. The results should reflect the
            change.
        """
        self.create_user('testuser')

        self.app.patch(           '/users/testuser',
                                  {'type': 'users',
                                  'handle': '*****@*****.**',
                                  'name': 'Test User Updated',
                                  'username':'******'})
        response = self.app.get('/users/testuser?actor_id=testuser')

        self.assertEqual(response.json['name'], 'Test User Updated')

    #!! Not implemented.
    @unittest.skip
    def test_update_self(self):
        """ Updating myself. Retrieve details. The results should reflect the
            change.
        """

        me = self.app.get('/user').json['username']

        response = self.app.patch('/users/' + me,
                                  {'type': 'users',
                                  'handle': 'testuser',
                                  'name': 'Test User Updated',
                                  'username':'******'},
                                  status=501)

        response = self.app.get('/users/' + me)

        self.assertEqual(response.json['name'], 'Test User Updated')

    #!! Not implemented.
    @unittest.skip
    def test_delete_user(self):
        """ Delete a user. Attempt to retrieve details should return 404.

        !! Not implemented - see notes about why this is tricky."""
        self.create_user('testuser')
        response = self.app.delete('/users/testuser')

        response = self.app.get('/users/testuser', status=404)

    def test_change_my_password(self):
        """ Apply a password to ourself. Check that we receive a 200 OK.
            Check that i can now log in with the new password.
            Note there is an equivalent test for a regular user setting their
            own password.
        """
        self.create_user('testuser')
        response = self.app.put('/users/administrator/password',
                                {'password': '******'})

        #Force the server to forget the old password
        self.app.authorization = ('Basic', ('xxx', 'xxx'))
        self.app.get('/users/testuser', status=401)

        #The old password must now fail.
        self.app.authorization = ('Basic', ('administrator', 'adminpass'))
        self.app.get('/users/testuser', status=401)

        #The new one should now work
        self.app.authorization = ('Basic', ('administrator', 'newpass'))
        self.app.get('/users/testuser')



    def test_set_user_password(self):  # FIX
        """ Apply a password to a user. Check that we receive a 200 OK.
            Validate against the database with the user and password above.
        """

        self.create_user('testpassuser')

        self.app.put(           '/users/testpassuser/password',
                                {'password': '******'})

        #Test login with new pass
        self.app.authorization = ('Basic', ('testpassuser', 'testpass'))
        response = self.app.get('/users/testpassuser', status=200)

    @unittest.skip
    def test_retrieve_user_touches(self):
        """ Retrieve a list of touches that the user has made to the database.
        This can only be requested by the user themselves, an agent or an
        administrator.

        !! Not implemented."""
        pass

    def test_invalid_user_credit(self):
        """ Query the credit for a non-existent user."""

        response = self.app.post('/users/notauser/credit',
                                {'credit': 1000},
                                status=404)
        response = self.app.get('/users/notauser/credit',
                                status=404)

    def test_create_retrieve_user_credit(self):
        """ Add credit to a user's account. This can only be done by an
        administrator."""

        self.create_user("testuser")

        self.app.post('/users/testuser/credit', {'credit': 1000})

        response = self.app.get('/users/testuser/credit', status=200)
        self.assertEqual(response.json['credit_balance'], 1000)
        uid = response.json['actor_id']

        # Debit 100, we should have 900 left
        response2 = self.app.post('/users/testuser/credit', {'credit': "-100"})

        self.assertEqual(response2.json, { 'actor_id' : uid,
                                           'credit_change' : -100,
                                           'credit_balance' : 900 } )


###############################################################################
# Support Functions, calling server admin views                               #
###############################################################################

    def create_user(self, name):
        response = self.app.put('/users/' + name,
                                {'type': 'users',
                                'handle': name + '@example.com',
                                'name': name + " " + name,
                                'username': name},
                                status=200,
                                expect_errors=False)
class model_tests(unittest2.TestCase):

    def setUp(self):
        print ""
        print "setUp"

        # Test application
        self.app = TestApp(
            app,
            extra_environ={'test': 'test'}
        )

        response = self.app.post_json('/login', {'username': '******', 'password': '******'})
        assert response.json['token']
        self.app.authorization = ('Basic', (response.json['token'], ''))

        print 'get / - elements'
        response = self.app.get('/')
        response.mustcontain('{"_links": {"child": [')
        self.elements = []
        for element in response.json['_links']['child']:
            self.elements.append(element['href'])
        assert self.elements
        assert len(self.elements) == 9

    def tearDown(self):
        print ""
        print "tearDown"

        response = self.app.post('/logout')
        response.mustcontain('ok')

    def dump_elements(self):
        print ''
        print 'elements'

        print 'get /element'
        for element in self.elements:
            response = self.app.get('/'+element)
            response.mustcontain('"_items":', '"_links"', '"_meta"')
            resp = response.json

            print "Element:", element
            print " - ", resp['_meta']

    def dump_session(self, session_id, status='open', nb_users=-1, nb_events=-1):
        # Get events ...
        response = self.app.get('/userservice_session/%s' % session_id)
        session = response.json
        print "Response:", session
        # {u'_updated': u'Tue, 10 May 2016 07:24:50 GMT', u'status': u'open', u'_id': u'57318cc24c988c28c55b030e', u'closing_date': u'', u'service_name': u'userservice1', u'userservice': u'57318cc24c988c28c55b030b', u'_links': {u'self': {u'href': u'userservice_session/57318cc24c988c28c55b030e', u'title': u'Userservice_session'}, u'parent': {u'href': u'/', u'title': u'home'}, u'collection': {u'href': u'userservice_session', u'title': u'userservice_session'}}, u'opening_date': u'Tue, 10 May 2016 07:24:50 GMT', u'ui': True, u'current_nb_users': 0, u'_etag': u'aa97a539afd10c8ed0724158423649e552c4a9af', u'_created': u'Tue, 10 May 2016 07:24:50 GMT'}

        # Session information
        print "Session: ", session
        print "- Id: ", session['_id']
        assert session['userservice']
        print "- Service: ", session['service_name']
        assert session['service_name']
        print "- Status: ", session['status']
        assert session['status'] == status
        print "- Opening date: ", session['opening_date']
        print "- Closing date: ", session['closing_date']
        print "- Users: ", session['current_nb_users']
        assert session['current_nb_users'] != None
        if nb_users != -1:
            assert session['current_nb_users'] == nb_users
        print "- Events: ", session['current_nb_events']
        assert session['current_nb_events'] != None
        if nb_events != -1:
            assert session['current_nb_events'] == nb_events

    def dump_events(self, session_id, nb_events):
        # Get events ...
        response = self.app.get('/event?where={"userservice_session":"%s"}' % session_id)
        resp = response.json
        assert resp['_meta']['total'] == nb_events
        for item in resp['_items']:
            assert item['date']
            assert item['user']
            assert item['type']
            assert item['message'] != None
            print "Event:", item['date'], item['type'], item['message']

    def dump_cdr(self, session_id, status='open', nb_users=-1, nb_documents=-1, video=None):
        # Get session cdr ...
        response = self.app.get('/userservice_cdr?where={"userservice_session":"%s"}' % session_id)
        resp = response.json
        assert resp['_meta']['total']
        for item in resp['_items']:
            print "CDR:", item
            assert item['userservice']
            assert item['userservice_session']
            assert item['nb_users'] != None
            if nb_users != -1:
                assert item['nb_users'] == nb_users
            assert item['nb_documents'] != None
            if nb_documents != -1:
                assert item['nb_documents'] == nb_documents
            assert item['status'] == status
            assert item['opening_date']
            if item['status'] == 'close':
                assert item['closing_date']
            assert item['videoconference'] != None
            if video:
                assert item['videoconference'] == video

    def dump_documents(self, session_id, nb_documents):
        # Get events ...
        response = self.app.get('/document?where={"userservice_session":"%s"}' % session_id)
        resp = response.json
        assert resp['_meta']['total'] == nb_documents
        for item in resp['_items']:
            print item
            assert item['date']
            assert item['user']
            assert item['name'] != None
            assert item['source'] != None
            assert item['document'] != None
            print "Document:", item['date'], item['name'], item['source']


    def test_1_domains(self):
        print ''
        print 'domains'

        print 'get /docs - data model'
        response = self.app.get('/docs/spec.json')
        response.mustcontain('"api_name": "API"')
        assert response.json['api_name'] == 'API'
        assert response.json['server_name'] == None
        assert response.json['base'] == 'http:///'
        assert response.json['domains']

        self.dm_domains = {}
        for domain_name in response.json['domains']:
            fields = response.json['domains'][domain_name]["/" + domain_name]['POST']['params']
            self.dm_domains.update({
                domain_name: fields
            })
        assert self.dm_domains

    def test_2_elements(self):
        print ''
        print 'elements'

        print 'get /element'
        for element in self.elements:
            response = self.app.get('/'+element)
            response.mustcontain('"_items":', '"_links"', '"_meta"')
            resp = response.json

            # Number of elements
            assert 'page' in resp['_meta']
            assert 'total' in resp['_meta']
            assert 'max_results' in resp['_meta']

            # Links
            assert 'self' in resp['_links']
            if resp['_meta']['total'] > resp['_meta']['max_results']:
                assert 'next' in resp['_links']
                assert 'last' in resp['_links']
            assert 'parent' in resp['_links']

        self.dump_elements()

    def test_3_create_users(self):

        print 'post /user'
        response = self.app.post('/user', {'username': '******'}, status=422)
        response.mustcontain("""{"_status": "ERR", "_issues": {"username": "******", "name": "required field"}, "_error": {"message": "Insertion failure: 1 document(s) contain(s) error(s)", "code": 422}}""")

        # User 1
        response = self.app.get('/user?where={"name":"user1"}')
        resp = response.json
        if resp['_meta']['total'] > 0:
            print "User user1 still exists, deleting..."
            item = resp['_items'][0]
            response = self.app.delete('/user/'+item['_id'], {}, headers=[('If-Match', str(item['_etag']))], status=204)

        print "Creating user user1..."
        # Default parameters...
        response = self.app.post('/user', {'name': 'user1'}, status=201)
        resp = response.json
        print "Created user:"******"""{"_status": "ERR", "_issues": {"name": "value 'user1' is not unique"}, "_error": {"message": "Insertion failure: 1 document(s) contain(s) error(s)", "code": 422}}""")

        # Get and control and patch
        response = self.app.get('/user?where={"name":"user1"}')
        resp = response.json
        assert resp['_meta']['total'] > 0
        item = resp['_items'][0]
        print item
        assert item['name'] == 'user1'
        assert 'friendly_name' not in item
        assert item['password']
        # Default password !

        # Login new user
        # -----------------------------
        response = self.app.post('/logout')
        response.mustcontain('ok')
        response = self.app.post_json('/login', {'username': '******', 'password': '******'})
        assert response.json['token']

        # Login admin
        # -----------------------------
        response = self.app.post_json('/login', {'username': '******', 'password': '******'})
        assert response.json['token']

        # User 2
        response = self.app.get('/user?where={"name":"user2"}')
        resp = response.json
        if resp['_meta']['total'] > 0:
            print "User user2 still exists, deleting..."
            item = resp['_items'][0]
            response = self.app.delete('/user/'+item['_id'], {}, headers=[('If-Match', str(item['_etag']))], status=204)

        print "Creating user user2..."
        # Good parameters...
        # Use post_json! Data posted must be json formatted in the HTTP request
        response = self.app.post_json('/user', {
            'name': 'user2',
            'friendly_name': 'Friendly name',
            'description': 'Description',
            'password': '******',
            'email': 'mail@',
            'lync': 'sip:',
            'is_admin': True,
            'read_only': False,
            'widgets_allowed': True
        }, status=201)
        resp = response.json
        print "Created user:"******"name":"user2"}')
        resp = response.json
        assert resp['_meta']['total'] > 0
        item = resp['_items'][0]
        print item
        assert item['name'] == 'user2'
        assert item['friendly_name'] == 'Friendly name'
        assert item['password']

        # Login new user
        # -----------------------------
        response = self.app.post('/logout')
        response.mustcontain('ok')
        response = self.app.post_json('/login', {'username': '******', 'password': '******'})
        assert response.json['token']

        # Login admin
        # -----------------------------
        response = self.app.post_json('/login', {'username': '******', 'password': '******'})
        assert response.json['token']

        response = self.app.get('/user?where={"name":"user2"}')
        resp = response.json
        assert resp['_meta']['total'] > 0
        item = resp['_items'][0]

        response = self.app.patch('/user/'+item['_id'], {'friendly_name':'Patched friendly name'}, headers=[('If-Match', str(item['_etag']))], status=200)
        resp = response.json
        assert resp['_id'] == item['_id']

        response = self.app.get('/user/'+resp['_id'])
        resp = response.json
        item = resp
        assert item['friendly_name'] == 'Patched friendly name'

        # Change password
        response = self.app.patch('/user/'+item['_id'], {'password':'******'}, headers=[('If-Match', str(item['_etag']))], status=200)
        resp = response.json
        assert resp['_id'] == item['_id']

        # Login new user
        # -----------------------------
        response = self.app.post('/logout')
        response.mustcontain('ok')
        response = self.app.post_json('/login', {'username': '******', 'password': '******'})
        assert response.json['token']

        # Login admin
        # -----------------------------
        response = self.app.post_json('/login', {'username': '******', 'password': '******'})
        assert response.json['token']

        response = self.app.get('/user?where={"name":"user2"}')
        resp = response.json
        assert resp['_meta']['total'] > 0
        item = resp['_items'][0]

    def test_4_create_userservices(self):

        print 'post /userservice'
        response = self.app.post('/userservice', {'username': '******'}, status=422)
        response.mustcontain("""{"_status": "ERR", "_issues": {"username": "******", "name": "required field"}, "_error": {"message": "Insertion failure: 1 document(s) contain(s) error(s)", "code": 422}}""")

        # userservice 1
        response = self.app.get('/userservice?where={"name":"userservice1"}')
        resp = response.json
        if resp['_meta']['total'] > 0:
            print "userservice userservice1 still exists, deleting..."
            item = resp['_items'][0]
            response = self.app.delete('/userservice/'+item['_id'], {}, headers=[('If-Match', str(item['_etag']))], status=204)

        print "Creating userservice userservice1..."
        # Default parameters...
        response = self.app.post('/userservice', {'name': 'userservice1'}, status=201)
        resp = response.json
        print "Created userservice:", resp['_id']
        # Only once...
        response = self.app.post('/userservice', {'name': 'userservice1'}, status=422)
        response.mustcontain("""{"_status": "ERR", "_issues": {"name": "value 'userservice1' is not unique"}, "_error": {"message": "Insertion failure: 1 document(s) contain(s) error(s)", "code": 422}}""")

        # userservice 2
        response = self.app.get('/userservice?where={"name":"userservice2"}')
        resp = response.json
        if resp['_meta']['total'] > 0:
            print "userservice userservice2 still exists, deleting..."
            item = resp['_items'][0]
            response = self.app.delete('/userservice/'+item['_id'], {}, headers=[('If-Match', str(item['_etag']))], status=204)

        print "Creating userservice userservice2..."
        # Good parameters...
        # Use post_json! Data posted must be json formatted in the HTTP request
        # Bad parameters: status ...
        response = self.app.post_json('/userservice', {
            'name': 'userservice2',
            'description': 'Description',
            'status': 'fake!'
        }, status=422)

        response = self.app.post_json('/userservice', {
            'name': 'userservice2',
            'description': 'Description',
            'status': 'inactive'
        }, status=201)
        resp = response.json
        print "Created userservice:", resp['_id']

        # Get and control and patch
        response = self.app.get('/userservice?where={"name":"userservice2"}')
        resp = response.json
        assert resp['_meta']['total'] > 0
        item = resp['_items'][0]
        print item
        assert item['name'] == 'userservice2'
        assert item['description'] == 'Description'

        response = self.app.patch('/userservice/'+item['_id'], {'description':'Patched description'}, headers=[('If-Match', str(item['_etag']))], status=200)
        resp = response.json
        assert resp['_id'] == item['_id']

        response = self.app.get('/userservice?where={"name":"userservice2"}')
        resp = response.json
        assert resp['_meta']['total'] > 0
        item = resp['_items'][0]
        assert item['description'] == 'Patched description'

    def test_5_create_userservice_users(self):

        print 'post /userservice_user'
        response = self.app.post('/userservice_user', {'username': '******'}, status=422)
        response.mustcontain("""{"_status": "ERR", "_issues": {"username": "******"}, "_error": {"message": "Insertion failure: 1 document(s) contain(s) error(s)", "code": 422}}""")

        response = self.app.get('/user?where={"name":"user1"}')
        resp = response.json
        assert resp['_meta']['total'] > 0
        user1 = resp['_items'][0]

        response = self.app.get('/userservice?where={"name":"userservice1"}')
        resp = response.json
        assert resp['_meta']['total'] > 0
        userservice1 = resp['_items'][0]

        # userservice_user 1
        response = self.app.get('/userservice_user?where={"user":"******","userservice":"%s"}' % (user1['_id'], userservice1['_id']))
        resp = response.json
        if resp['_meta']['total'] > 0:
            print "userservice_user for userservice1 still exists, deleting..."
            item = resp['_items'][0]
            response = self.app.delete('/userservice_user/'+item['_id'], {}, headers=[('If-Match', str(item['_etag']))], status=204)

        print "Creating userservice_user for userservice1..."
        # Default parameters...
        response = self.app.post('/userservice_user', {'userservice': userservice1['_id'], 'user': user1['_id']}, status=201)
        resp = response.json
        print "Created userservice_user:"******"A relation', 'still exists')
        # Bad service id!
        response = self.app.post('/userservice_user', {'userservice': user1['_id'], 'user': user1['_id']}, status=422)
        response.mustcontain(""" must exist in resource 'userservice', field '_id'""")

        # Get and control and patch
        response = self.app.get('/userservice_user?where={"user":"******","userservice":"%s"}' % (user1['_id'], userservice1['_id']))
        resp = response.json
        assert resp['_meta']['total'] > 0
        item = resp['_items'][0]
        print item
        assert item['status'] == 'active'

        response = self.app.patch('/userservice_user/'+item['_id'], {'status':'inactive'}, headers=[('If-Match', str(item['_etag']))], status=200)
        resp = response.json
        assert resp['_id'] == item['_id']

        response = self.app.get('/userservice_user/'+item['_id'])
        resp = response.json
        assert resp['_id'] == item['_id']
        assert resp['status'] == 'inactive'

    def test_6_create_userservice_session(self):

        print 'post /userservice_session'
        response = self.app.post('/userservice_session', {
            'username': '******'
        }, status=422)
        response.mustcontain("""{"_status": "ERR", "_issues": {"username": "******", "service_name": "required field"}, "_error": {"message": "Insertion failure: 1 document(s) contain(s) error(s)", "code": 422}}""")

        response = self.app.post('/userservice_session', {
            'service_name': 'unknown_service'
        }, status=412)
        response.mustcontain("""{"content": "Provided service name 'unknown_service' does not exist.", "_status": "KO"}""")

        # userservice_session 1
        response = self.app.get('/userservice_session?where={"service_name":"userservice1"}')
        resp = response.json
        if resp['_meta']['total'] > 0:
            print "userservice_session userservice1 still exists, deleting..."
            item = resp['_items'][0]
            response = self.app.delete('/userservice_session/'+item['_id'], {}, headers=[('If-Match', str(item['_etag']))], status=204)

        print "Creating userservice_session for userservice1..."
        # Create session 1
        # Default parameters...
        # --------------------------
        response = self.app.post('/userservice_session', {'service_name': 'userservice1'}, status=201)
        resp = response.json
        print "Created userservice_session:", resp['_id']
        session1 = resp

        # Get direct object
        response = self.app.get('/userservice_session/%s' % session1['_id'])
        item = response.json
        print item
        assert item['service_name'] == 'userservice1'
        assert item['current_nb_users'] == 0
        assert item['current_nb_events'] == 1
        assert item['closing_date'] == ''
        assert not item['opening_date'] == ''
        assert item['status'] == 'open'

        # Dump session
        self.dump_session(session1['_id'], status='open', nb_users=0, nb_events=1)

        # Dump session CDR
        self.dump_cdr(session1['_id'], nb_users=0, status='open')

        # Only once... because still exists!
        response = self.app.post('/userservice_session', {'service_name': 'userservice1'}, status=412)
        response.mustcontain("""{"content": "A session for the service 'userservice1' still exists. You cannot create a new session for this service.""")

        # userservice_session 2
        response = self.app.get('/userservice_session?where={"service_name":"userservice2"}')
        resp = response.json
        if resp['_meta']['total'] > 0:
            print "userservice_session for userservice2 still exists, deleting..."
            item = resp['_items'][0]
            response = self.app.delete('/userservice_session/'+item['_id'], {}, headers=[('If-Match', str(item['_etag']))], status=204)

        print "Creating userservice_session for userservice2..."
        # Good parameters...
        # Use post_json! Data posted must be json formatted in the HTTP request
        # Bad parameters: status ...
        response = self.app.post_json('/userservice_session', {
            'service_name': 'userservice2',
            'description': 'Description',
            'status': 'fake!'
        }, status=422)

        # Create a session 2
        # --------------------------
        response = self.app.post_json('/userservice_session', {
            'service_name': 'userservice2',
            'status': 'open'
        }, status=201)
        resp = response.json
        print "Created userservice_session:", resp['_id']
        session2 = resp

        # Dump session CDR
        self.dump_cdr(resp['_id'], nb_users=0, status='open')

        # Get and control and patch
        # Get direct object
        response = self.app.get('/userservice_session/%s' % session2['_id'])
        item = response.json
        print item
        assert item['service_name'] == 'userservice2'
        assert item['current_nb_users'] == 0
        assert item['closing_date'] == ''
        assert not item['opening_date'] == ''
        assert item['status'] == 'open'

        # Get with search object
        response = self.app.get('/userservice_session?where={"service_name":"userservice2"}')
        resp = response.json
        assert resp['_meta']['total'] > 0
        item = resp['_items'][0]
        print item
        assert item
        assert item['service_name'] == 'userservice2'
        assert item['current_nb_users'] == 0
        assert item['closing_date'] == ''
        assert not item['opening_date'] == ''
        assert item['status'] == 'open'

        # Close session 2 (patch status=close)
        # --------------------------
        response = self.app.patch('/userservice_session/'+item['_id'], {'status':'close'}, headers=[('If-Match', str(item['_etag']))], status=200)
        resp = response.json
        assert resp['_id'] == item['_id']

        response = self.app.get('/userservice_session?where={"service_name":"userservice2"}')
        resp = response.json
        assert resp['_meta']['total'] > 0
        item = resp['_items'][0]
        assert item['status'] == 'close'
        assert not item['closing_date'] == ''

        response = self.app.get('/userservice_session?where={"service_name":"userservice2", "status":"close"}')
        resp = response.json
        assert resp['_meta']['total'] > 0
        item = resp['_items'][0]
        assert item['status'] == 'close'
        assert not item['closing_date'] == ''

        # Dump session CDR
        self.dump_cdr(item['_id'], nb_users=0, status='close')


        # Users join the session 1
        # --------------------------
        response = self.app.get('/user?where={"name":"user1"}')
        resp = response.json
        user1 = resp['_items'][0]
        response = self.app.get('/user?where={"name":"user2"}')
        resp = response.json
        user2 = resp['_items'][0]

        print "Creating relation between user and session..."
        # Unknown user...
        response = self.app.post('/userservice_session_user', {
            'service_name': 'userservice1',
            'username': '******'
        }, status=412)
        response.mustcontain("""{"content": "No user found with name: unknown_user.", "_status": "KO"}""")
        # Bad status...
        response = self.app.post('/userservice_session_user', {
            'service_name': 'userservice1',
            'username': '******',
            'status': 'close'
        }, status=412)
        response.mustcontain("""{"content": "You can only join the current session by setting status='open' for this element.", "_status": "KO"}""")

        # Default parameters...
        response = self.app.post('/userservice_session_user', {
            'service_name': 'userservice1',
            'username': user1['name']
        }, status=201)
        resp = response.json
        print "Created userservice_session_user:"******"""already joined this session.", "_status": "KO", "_id": """)

        # Default parameters...
        response = self.app.post('/userservice_session_user', {
            'service_name': 'userservice1',
            'user': user2['_id']
        }, status=201)
        resp = response.json
        print "Created userservice_session_user:"******"""already joined this session.", "_status": "KO", "_id": """)

        # Dump session CDR
        self.dump_cdr(session1['_id'], nb_users=2, status='open')




        # Users leave the session
        # --------------------------
        response = self.app.get('/userservice_session_user/'+relation1, {}, status=200)
        item = response.json

        # Current user has not joined!
        response = self.app.patch('/userservice_session_user/'+item['_id'], {
            'status':'close'
        }, headers=[('If-Match', str(item['_etag']))], status=412)
        response.mustcontain("""{"content": "You have not joined this session.", "_status": "KO"}""")

        # Control session current_nb_users
        response = self.app.get('/userservice_session/'+session1['_id'])
        item = response.json
        assert item
        assert item['current_nb_users'] == 2

        # Dump session CDR
        self.dump_cdr(session1['_id'], nb_users=2, status='open')

        # User1 has joined and leaves!
        response = self.app.get('/userservice_session_user/'+relation1, {}, status=200)
        item = response.json
        response = self.app.patch('/userservice_session_user/'+relation1, {
            'username': '******',
            'status':'close'
        }, headers=[('If-Match', str(item['_etag']))], status=200)

        # Control session current_nb_users
        response = self.app.get('/userservice_session/'+session1['_id'])
        item = response.json
        assert item
        assert item['current_nb_users'] == 1

        # Dump session CDR
        # nb_users remains 2 even when someone leaves ...
        self.dump_cdr(session1['_id'], nb_users=2, status='open')

        response = self.app.get('/userservice_session_user/'+relation2, {}, status=200)
        item = response.json
        response = self.app.patch('/userservice_session_user/'+item['_id'], {
            'user': user2['_id'],
            'status':'close'
        }, headers=[('If-Match', str(item['_etag']))])
        resp = response.json
        assert resp['_id'] == item['_id']

        # Control session current_nb_users
        response = self.app.get('/userservice_session/'+session1['_id'])
        item = response.json
        assert item
        assert item['current_nb_users'] == 0

        # Dump session CDR
        self.dump_cdr(session1['_id'], nb_users=2, status='close')


        # Get session 1 (opened state)
        response = self.app.get('/userservice_session?where={"service_name":"userservice1", "status":"open"}')
        resp = response.json
        assert resp['_meta']['total'] == 0

        # Get session 1 (closed state)
        response = self.app.get('/userservice_session?where={"service_name":"userservice1", "status":"close"}')
        resp = response.json
        assert resp['_meta']['total'] == 1

        # Close the session
        response = self.app.patch('/userservice_session/'+item['_id'], {'status':'close'}, headers=[('If-Match', str(item['_etag']))], status=200)
        resp = response.json
        assert resp['_id'] == item['_id']

        response = self.app.get('/userservice_session?where={"service_name":"userservice2"}')
        resp = response.json
        assert resp['_meta']['total'] > 0
        item = resp['_items'][0]
        assert item['status'] == 'close'
        assert not item['closing_date'] == ''

    def test_7_create_events(self):

        print 'create userservice_session'
        # userservice_session 1
        response = self.app.get('/userservice_session?where={"service_name":"userservice1"}')
        resp = response.json
        if resp['_meta']['total'] > 0:
            print "userservice_session userservice1 still exists, deleting..."
            item = resp['_items'][0]
            response = self.app.delete('/userservice_session/'+item['_id'], {}, headers=[('If-Match', str(item['_etag']))], status=204)

        print "Creating userservice_session for userservice1..."
        # Create session 1
        # Default parameters...
        # --------------------------
        response = self.app.post('/userservice_session', {'service_name': 'userservice1'}, status=201)
        resp = response.json
        print "Created userservice_session:", resp['_id']
        session = resp


        # Control session current_nb_users
        response = self.app.get('/userservice_session/'+session['_id'])
        item = response.json
        assert item
        assert item['current_nb_users'] == 0

        # Dump session CDR
        self.dump_cdr(session['_id'], nb_users=0, status='open')
        self.dump_events(session['_id'], 1)

        # Users join the session 1
        # --------------------------
        response = self.app.get('/user?where={"name":"admin"}')
        resp = response.json
        admin = resp['_items'][0]
        response = self.app.get('/user?where={"name":"user1"}')
        resp = response.json
        user1 = resp['_items'][0]
        response = self.app.get('/user?where={"name":"user2"}')
        resp = response.json
        user2 = resp['_items'][0]

        print "Creating relation between user and session..."
        # Default parameters...
        response = self.app.post('/userservice_session_user', {
            'service_name': 'userservice1',
            'username': user1['name']
        }, status=201)
        resp = response.json
        print "Created userservice_session_user:"******"Created userservice_session_user:"******"Created userservice_session_user:"******"""{"_status": "ERR", "_issues": {"type": "required field"}, "_error": {"message": "Insertion failure: 1 document(s) contain(s) error(s)", "code": 422}}""")

        # Default data, unallowed type
        response = self.app.post('/event', {
            'userservice_session': session['_id'],
            'user': user1['_id'],
            'type': 'fake'
        }, status=422)
        response.mustcontain("""{"_status": "ERR", "_issues": {"type": "unallowed value fake"}, "_error": {"message": "Insertion failure: 1 document(s) contain(s) error(s)", "code": 422}}""")

        # Default data
        response = self.app.post('/event', {
            'userservice_session': session['_id'],
            'user': user1['_id'],
            'type': 'info.webui'
        }, status=201)
        resp = response.json
        print "Created event:", resp['_id']
        response = self.app.post('/event', {
            'userservice_session': session['_id'],
            # Default user
            # 'user': user1['_id'],
            'type': 'info.chat'
        }, status=201)
        resp = response.json
        print "Created event:", resp['_id']

        self.dump_events(session['_id'], 6)


        # Post events ... videoconferencing!
        response = self.app.post('/event', {
            'userservice_session': session['_id'],
            'type': 'video.launched'
        }, status=201)
        self.dump_cdr(session['_id'], video='video.launched')
        response = self.app.post('/event', {
            'userservice_session': session['_id'],
            'type': 'video.notified'
        }, status=201)
        self.dump_cdr(session['_id'], video='video.notified')
        response = self.app.post('/event', {
            'userservice_session': session['_id'],
            'type': 'video.rejected'
        }, status=201)
        self.dump_cdr(session['_id'], video='video.rejected')
        response = self.app.post('/event', {
            'userservice_session': session['_id'],
            'type': 'video.connected'
        }, status=201)
        self.dump_cdr(session['_id'], video='video.connected')
        response = self.app.post('/event', {
            'userservice_session': session['_id'],
            'type': 'video.disconnected'
        }, status=201)
        self.dump_cdr(session['_id'], video='video.disconnected')

        self.dump_events(session['_id'], 11)

        # Post counters ...
        # Default data, missing type
        response = self.app.post('/counter', {
            'userservice_session': session['_id'],
            'user': user1['_id']
        }, status=422)
        response.mustcontain("""{"_status": "ERR", "_issues": {"name": "required field", "value": "required field"}, "_error": {"message": "Insertion failure: 1 document(s) contain(s) error(s)", "code": 422}}""")

        # Default data, name/value
        response = self.app.post('/counter', {
            'userservice_session': session['_id'], 'user': user1['_id'],
            'name': 'test', 'value': 0
        }, status=201)
        resp = response.json
        print "Created counter:", resp['_id']

        self.dump_events(session['_id'], 12)

        response = self.app.post('/counter', {
            'userservice_session': session['_id'],
            # Default user
            # 'user': user1['_id'],
            'name': 'test', 'value': 0
        }, status=201)
        resp = response.json
        print "Created counter:", resp['_id']

        self.dump_events(session['_id'], 13)



        # Post documents ...
        # Default data, missing type
        response = self.app.post('/document', {
            'userservice_session': session['_id'],
            'user': user1['_id']
        }, status=422)
        response.mustcontain("""{"_status": "ERR", "_issues": {"source": "required field", "document": "required field", "name": "required field"}, "_error": {"message": "Insertion failure: 1 document(s) contain(s) error(s)", "code": 422}}""")

        # Default data, name/source
        response = self.app.post('/document', {
            'userservice_session': session['_id'], 'user': user1['_id'],
            'name': 'test', 'source': 'test'
        }, upload_files=[
            ('document', os.path.abspath(os.path.join(os.path.dirname(__file__), 'requirements.txt')))
        ],
        status=201)
        resp = response.json
        print "Created document:", resp['_id']
        assert resp['_id']

        # Get posted document
        response = self.app.get('/document/'+resp['_id'])
        item = response.json
        assert item
        print "Got document:", item
        assert item['document']
        if 'EXTENDED_MEDIA_INFO' in app_settings and app_settings['EXTENDED_MEDIA_INFO']:
            assert isinstance(item['document'], dict)
            assert item['document']['file']
            assert item['document']['length']
            assert item['document']['content_type']
            assert item['document']['name']
            if 'RETURN_MEDIA_AS_URL' in app_settings and app_settings['RETURN_MEDIA_AS_URL']:
                assert '/media' in item['document']['file']
            else:
                assert '/media' not in item['document']['file']
        else:
            assert isinstance(item['document'], basestring)
            if 'RETURN_MEDIA_AS_URL' in app_settings and app_settings['RETURN_MEDIA_AS_URL']:
                assert '/media' in item['document']
            else:
                assert '/media' not in item['document']

        self.dump_cdr(session['_id'], nb_documents=1)
        self.dump_events(session['_id'], 14)
        self.dump_documents(session['_id'], 1)

        response = self.app.post('/document', {
            'userservice_session': session['_id'],
            # Default user
            # 'user': user1['_id'],
            'name': 'test', 'source': 'test'
        }, upload_files=[
            ('document', os.path.abspath(os.path.join(os.path.dirname(__file__), 'requirements.txt')))
        ],
        status=201)
        resp = response.json
        print "Created document:", resp['_id']
        assert resp['_id']

        self.dump_cdr(session['_id'], nb_documents=2)
        self.dump_events(session['_id'], 15)
        self.dump_documents(session['_id'], 2)



        # Close the session
        response = self.app.get('/userservice_session/'+session['_id'])
        session = response.json

        response = self.app.patch('/userservice_session/'+session['_id'], {'status':'close'}, headers=[('If-Match', str(session['_etag']))], status=200)
        resp = response.json
        assert resp['_id'] == session['_id']
Example #11
0
class ViewTest(unittest.TestCase):

    def setUp(self):
        boot = bootstrap('testing.ini')
        result = boot['root'].load_fixtures('fixtures.json')
        transaction.commit()
        self.testapp = TestApp(boot['app'])
        self.report = result['reports'][0]
        self.report_key = self.report.key

    def test_root(self):
        res = self.testapp.get('/', status=200)
        self.assertIn(u'<a href="/categories/milk">молоко</a>',
                      res.body.decode('utf-8'))
        self.assertIn(u'Москва', res.body.decode('utf-8'))
        self.assertIn(u'молочная продукция и яйцо', res.body.decode('utf-8'))

    def test_category(self):
        res = self.testapp.get('/categories/milk', status=200)
        self.assertIn(u'молоко', res.body.decode('utf-8'))
        self.assertIn(u'молочная продукция и яйцо', res.body.decode('utf-8'))

    def test_product(self):
        res = self.testapp.get(
            u'/products/Молоко Красная Цена у-паст. 3.2% 1л'.encode('utf-8'),
            status=200)
        self.assertIn(u'Молоко Красная Цена у/паст. 3.2% 1л',
                      res.body.decode('utf-8'))
        self.assertIn(u'молочная продукция и яйцо',
                      res.body.decode('utf-8'))

    def test_report_get(self):
        res = self.testapp.get('/reports/{}'.format(self.report_key),
                               status=200)
        self.assertIn(self.report_key, res.body)

    def test_404(self):
        res = self.testapp.get('/rubbishness', status=404)
        self.assertIn(u'Страница не найдена', res.body.decode('utf-8'))
        res = self.testapp.get('/products/rubbishness', status=404)
        self.assertIn(u'Страница не найдена', res.body.decode('utf-8'))

    def test_report_post_bad_request(self):
        bad_data = [('rubbish_field', 'say wha?')]
        res = self.testapp.post('/reports', bad_data, status=400)
        self.assertIn('400', res.body)

    def test_report_post_bad_category(self):
        data = [
            ('price_value', 55.6),
            ('url', 'http://howies.com/products/milk/4'),
            ('product_title', u'Элексир Веселый молочник 950г'.encode('utf-8')),
            ('merchant_title', "Howie's grocery"),
            ('reporter_name', 'Jack')
        ]
        res = self.testapp.post('/reports', data, status=400)
        self.assertIn(u'Category lookup failed for product '
                      u'"Элексир Веселый молочник 950г"',
                      res.body.decode('utf-8'))

    def test_report_post_bad_package(self):
        data = [
            ('price_value', 55.6),
            ('url', 'http://howies.com/products/milk/4'),
            ('product_title',
             u'Молоко Веселый молочник 3950г'.encode('utf-8')),
            ('merchant_title', "Howie's grocery"),
            ('reporter_name', 'Jack')
        ]
        res = self.testapp.post('/reports', data, status=400)
        self.assertIn(u'Package lookup failed for product '
                      u'"Молоко Веселый молочник 3950г"',
                      res.body.decode('utf-8'))

    def test_report_post_existent_product(self):
        data = [
            ('price_value', 55.6),
            ('url', 'http://howies.com/products/milk/4'),
            ('product_title',
             u'Молоко Красная Цена у/паст. 3.2% 1л'.encode('utf-8')),
            ('merchant_title', "Howie's grocery"),
            ('reporter_name', 'Jack')
        ]
        res = self.testapp.post('/reports', data, status=200)
        self.assertEqual(0, res.json_body['counts']['product'])
        new_report_key = res.json_body['new_report_keys'][0]
        self.testapp.get('/reports/{}'.format(new_report_key), status=200)

    def test_post_multiple_reports(self):

        data = [
            ('price_value', 55.6),
            ('url', 'http://howies.com/products/milk/4'),
            ('product_title',
             u'Молоко Красная Цена у/паст. 3.2% 1л'.encode('utf-8')),
            ('sku', 'ART97665'),
            ('merchant_title', u"Московский магазин"),
            ('reporter_name', 'Jack'),

            ('price_value', 45.3),
            ('url', 'http://howies.com/products/milk/5'),
            ('product_title',
             u'Молоко Красная Цена у/паст. 1% 1л'.encode('utf-8')),
            ('sku', 'ART97665'),
            ('merchant_title', u"Московский магазин"),
            ('reporter_name', 'Jack'),

            ('price_value', 67.1),
            ('url', 'http://howies.com/products/milk/6'),
            ('product_title',
             u'Волшебный Элексир Красная Цена у/паст. 1% 1л'.encode('utf-8')),
            ('sku', ''),
            ('merchant_title', u"Московский магазин"),
            ('reporter_name', 'Jill'),
        ]
        res = self.testapp.post('/reports', data, status=200)
        self.assertEqual(2, len(res.json_body['new_report_keys']))
        self.assertEqual(1, res.json_body['counts']['product'])
        self.assertEqual(0, res.json_body['counts']['category'])
        self.assertEqual(0, res.json_body['counts']['package'])

        new_report_keys = res.json_body['new_report_keys']
        for key in new_report_keys:
            res_ = self.testapp.get('/reports/{}'.format(key), status=200)
            self.assertEqual('ART97665',
                             res_.html.find('td', 'sku').text.strip())

        errors = res.json_body['errors']
        self.assertIn(u'Category lookup failed for product '
                      u'"Волшебный Элексир Красная Цена у/паст. 1% 1л"',
                      errors)

        milk_page = self.testapp.get('/categories/milk', status=200)
        self.assertIn(u'45,90', milk_page.html.find('tr', 'info').text)
        self.assertIn(u'45,90', milk_page.html.find('div', 'cat_price').text)

        from pyramid_mailer import get_mailer
        registry = self.testapp.app.registry
        mailer = get_mailer(registry)

        self.assertEqual(len(mailer.outbox), 1)
        self.assertEqual(mailer.outbox[0].subject,
                         u'Price Watch: отчеты от Jill, Jack')
        self.assertIn(u'Category lookup failed for product '
                      u'&#34;Волшебный Элексир Красная Цена у/паст. 1% 1л&#34;',
                      mailer.outbox[0].html)
        self.assertIn(u'Jill, Jack', mailer.outbox[0].html)

    def test_post_incorrect_date_format(self):
        data = [
            ('price_value', 55.6),
            ('url', 'http://howies.com/products/milk/4'),
            ('product_title',
             u'Молоко Красная Цена у/паст. 3.2% 1л'.encode('utf-8')),
            ('merchant_title', "Howie's grocery"),
            ('reporter_name', 'Jack'),
            ('date_time', '2014.12.30 20:57')
        ]
        res = self.testapp.post('/reports', data, status=400)
        self.assertIn("time data '2014' does not match "
                      "format '%Y-%m-%d %H:%M:%S'", res.body)

    def test_post_multiple_reports_bad_multidict(self):
        data = [
            ('price_value', 55.6),
            ('url', 'http://howies.com/products/milk/4'),
            ('product_title',
             u'Молоко Красная Цена у/паст. 3.2% 1л'.encode('utf-8')),
            ('merchant_title', "Howie's grocery"),
            ('reporter_name', 'Jack'),

            ('price_value', 45.3),
            ('url', 'http://howies.com/products/milk/5'),
            ('product_title',
             u'Молоко Красная Цена у/паст. 1% 1л'.encode('utf-8')),
            ('merchant_title', "Howie's grocery"),
            ('reporter_name', 'Jack'),

            ('price_value', 67.1),
            ('url', 'http://howies.com/products/milk/6'),
            ('product_title',
             u'Волшебный Элексир Красная Цена у/паст. 1% 1л'.encode('utf-8')),
            ('merchant_title', "Howie's grocery"),
            ('reporter_name', 'Jack'),
            ('date_time', '2014-12-1')
        ]
        res = self.testapp.post('/reports', data, status=400)
        self.assertIn('Bad multidict: value counts not equal', res.body)

    def test_report_delete(self):
        res = self.testapp.delete('/reports/{}'.format(self.report_key),
                                  status=200)
        self.assertIn('deleted_report_key', res.body)
        self.testapp.get('/reports/{}'.format(self.report_key), status=404)

    def test_page_get(self):
        res = self.testapp.get('/pages/about', status=200)
        self.assertIn(u'О проекте', res.text)

    def test_page_post(self):
        res = self.testapp.post('/pages', [('slug', 'test')], status=200)
        self.assertIn('new_page', res.body)

        self.testapp.get('/pages/test', status=404)

    def test_merchant_patch(self):
        res = self.testapp.patch(
            u"/merchants/Московский магазин".encode('utf-8'),
            [('title', 'Fred & Co.')],
            status=200)
        self.assertEqual('Fred & Co.', res.json_body['title'])
        self.testapp.get(
            u"/merchants/Московский магазин".encode('utf-8'),
            status=404)
        res = self.testapp.get("/merchants/Fred & Co.", status=200)
        self.assertEqual('Fred & Co.', res.json_body['title'])

    def test_merchants_get(self):
        res = self.testapp.get('/merchants', status=200)
        self.assertIn(u"Московский магазин", res.json_body)

    def test_product_chart_data(self):
        data = [
            ('price_value', 55.6),
            ('url', 'http://howies.com/products/milk/4'),
            ('product_title',
             u'Молоко Deli Milk 1L'.encode('utf-8')),
            ('merchant_title', "Howie's grocery"),
            ('reporter_name', 'Jack'),
            ('date_time', TWO_WEEKS_AGO),

            ('price_value', 54.8),
            ('url', 'http://eddies.com/products/milk/4'),
            ('product_title',
             u'Молоко Deli Milk 1L'.encode('utf-8')),
            ('merchant_title', "Eddie's grocery"),
            ('reporter_name', 'Jack'),
            ('date_time', TWO_WEEKS_AGO),

            ('price_value', 62.1),
            ('url', 'http://eddies.com/products/milk/4'),
            ('product_title',
             u'Молоко Deli Milk 1L'.encode('utf-8')),
            ('merchant_title', "Eddie's grocery"),
            ('reporter_name', 'Jack'),
            ('date_time', ''),
        ]
        self.testapp.post('/reports', data, status=200)

        res = self.testapp.get(u'/products/Молоко Deli '
                               u'Milk 1L'.encode('utf-8'),
                               status=200)
        today_str = datetime.today().strftime('%d.%m')
        weeks_ago_str = TWO_WEEKS_AGO.strftime('%d.%m')
        self.assertIn('["{}", 64.299999999999997]'.format(today_str),
                      res.body)
        self.assertIn('["{}", 55.200000000000003]'.format(weeks_ago_str),
                      res.body)

    def test_display_days(self):
        data = [
            ('price_value', 59.3),
            ('url', 'http://howies.com/products/milk/4'),
            ('product_title',
             u'Молоко Deli Milk 1L'.encode('utf-8')),
            ('merchant_title', "Howie's grocery"),
            ('reporter_name', 'Jack'),
            ('date_time', datetime.now() - timedelta(weeks=7))
        ]
        self.testapp.post('/reports', data, status=200)
        res = self.testapp.get(u'/products/Молоко Deli '
                               u'Milk 1L'.encode('utf-8'),
                               status=200)
        self.assertNotIn('59,30', res.body)

    def test_location_at_root_view(self):
        res = self.testapp.get('/?location=Санкт-Петербург', status=200)
        self.assertIn(u'Санкт-Петербург', res.body.decode('utf-8'))
        self.assertIn('45,90', res.body.decode('utf-8'))

        res = self.testapp.get('/?location=Москва', status=200)
        self.assertIn(u'Москва', res.body.decode('utf-8'))
        self.assertIn('55,60', res.body.decode('utf-8'))

        res = self.testapp.get('/', status=200)
        self.assertIn('50,75', res.body.decode('utf-8'))

    def test_location_at_category_view(self):
        res = self.testapp.get('/categories/milk?location=Санкт-Петербург',
                               status=200)
        self.assertIn(u'Молоко Балтика ультрапас. 3.2% 1л',
                      res.body.decode('utf-8'))
        self.assertNotIn(u'Молоко Farmers Milk 1L', res.body.decode('utf-8'))
        self.assertIn(u'45,90', res.html.find('div', 'cat_price').text)

        res = self.testapp.get('/categories/milk?location=Москва',
                               status=200)
        self.assertNotIn(u'Молоко Балтика ультрапас. 3.2% 1л',
                         res.body.decode('utf-8'))
        self.assertIn(u'Молоко Farmers Milk 1L', res.body.decode('utf-8'))
        self.assertIn(u'55,60', res.html.find('div', 'cat_price').text)

        res = self.testapp.get('/categories/milk', status=200)
        self.assertIn(u'Молоко Балтика ультрапас. 3.2% 1л',
                         res.body.decode('utf-8'))
        self.assertIn(u'Молоко Farmers Milk 1L', res.body.decode('utf-8'))
        self.assertIn(u'50,75', res.html.find('div', 'cat_price').text)

    def test_noindex_tag(self):
        res = self.testapp.get('/')
        self.assertNotIn('<meta name="robots" content="noindex">', res.text)

        res = self.testapp.get(u'/products/Молоко Deli '
                               u'Milk 1L'.encode('utf-8'))
        self.assertNotIn('<meta name="robots" content="noindex">', res.text)

        res = self.testapp.get('/categories/milk')
        self.assertNotIn('<meta name="robots" content="noindex">', res.text)

        res = self.testapp.get('/reports/{}'.format(self.report_key))
        self.assertIn('<meta name="robots" content="noindex">', res.text)

    def test_description_tag(self):
        res = self.testapp.get(u'/products/Молоко Deli '
                               u'Milk 1L'.encode('utf-8'))
        self.assertIn(u'Текущая цена и история цен на '
                      u'Молоко Deli Milk 1L за последний месяц',
                      res.html.find(attrs={"name": "description"})['content'])

        res = self.testapp.get('/', status=200)
        self.assertIn(u'Динамика цен на '
                      u'продукты за последний месяц',
                      res.html.find(attrs={"name": "description"})['content'])

        res = self.testapp.get('/categories/milk')
        self.assertIn(u'Динамика цен на молоко за последний месяц',
                      res.html.find(attrs={"name": "description"})['content'])

        res = self.testapp.get('/reports/{}'.format(self.report_key))
        date_time = format_datetime(self.report.date_time, format='long',
                                    locale='ru')
        self.assertIn(u'\nОтчет о цене на '
                      u'{}\nу продавца {} за {}'.format(
                          self.report.product.title,
                          self.report.merchant.title,
                          date_time),
                      res.html.find(attrs={"name": "description"})['content'])

    def test_sitemap(self):
        res = self.testapp.get('/sitemap.xml'.encode('utf-8'))
        self.assertIn('urlset', res.xml.tag)
        self.assertIn('http://localhost/pages/about', res.text)
        self.assertIn('http://localhost/products/%D0%9C%D0%BE%D0%BB%D0%BE%D0%'
                      'BA%D0%BE%20Deli%20Milk%201L', res.text)
        self.assertIn('http://localhost/categories/milk', res.text)
        self.assertIn('http://localhost/categories/milk?location=%D0%A1%D0%'
                      'B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%'
                      '80%D0%B1%D1%83%D1%80%D0%B3', res.text)
        self.assertIn('http://localhost?location=%D0%A1%D0%'
                      'B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%'
                      '80%D0%B1%D1%83%D1%80%D0%B3', res.text)

    def test_empty_category(self):
        self.testapp.get('/categories/pumpkin', status=200)

    def test_empty_product(self):
        self.testapp.get(u'/products/Никому не нужный '
                         u'сахар 3 кг'.encode('utf-8'), status=200)
Example #12
0
class TestService(TestCase):
    def setUp(self):
        self.config = testing.setUp(
            settings={'pyramid.debug_authorization': True})

        # Set up debug_authorization logging to console
        logging.basicConfig(level=logging.DEBUG)
        debug_logger = logging.getLogger()
        self.config.registry.registerUtility(debug_logger, IDebugLogger)

        self.config.include("cornice")

        self.authz_policy = ACLAuthorizationPolicy()
        self.config.set_authorization_policy(self.authz_policy)

        self.authn_policy = AuthTktAuthenticationPolicy('$3kr1t')
        self.config.set_authentication_policy(self.authn_policy)

        self.config.scan("tests.test_service")
        self.config.scan("tests.test_pyramidhook")
        self.app = TestApp(CatchErrors(self.config.make_wsgi_app()))
        register_service_views(self.config, service)

    def tearDown(self):
        testing.tearDown()

    def test_404(self):
        # a get on a resource that explicitly return a 404 should return 404
        self.app.get("/service", status=HTTPNotFound.code)

    def test_405(self):
        # calling a unknown verb on an existing resource should return a 405
        self.app.post("/service", status=HTTPMethodNotAllowed.code)

    def test_204(self):
        resp = self.app.delete("/service", status=204)
        self.assertNotIn("Content-Type", resp.headers)

    def test_acl_support_unauthenticated_service_patch(self):
        # calling a view with permissions without an auth'd user => 403
        self.app.patch('/service', status=HTTPForbidden.code)

    def test_acl_support_authenticated_allowed_service_patch(self):
        with mock.patch.object(self.authn_policy,
                               'unauthenticated_userid',
                               return_value='bob'):
            result = self.app.patch('/service', status=HTTPOk.code)
            self.assertEqual("yay", result.json)
        # The other user with 'write' permission
        with mock.patch.object(self.authn_policy,
                               'unauthenticated_userid',
                               return_value='dan'):
            result = self.app.patch('/service', status=HTTPOk.code)
            self.assertEqual("yay", result.json)

    def test_acl_support_authenticated_valid_user_wrong_permission_service_patch(
            self):
        with mock.patch.object(self.authn_policy,
                               'unauthenticated_userid',
                               return_value='alice'):
            self.app.patch('/service', status=HTTPForbidden.code)

    def test_acl_support_authenticated_valid_user_permission_denied_service_patch(
            self):
        with mock.patch.object(self.authn_policy,
                               'unauthenticated_userid',
                               return_value='carol'):
            self.app.patch('/service', status=HTTPForbidden.code)

    def test_acl_support_authenticated_invalid_user_service_patch(self):
        with mock.patch.object(self.authn_policy,
                               'unauthenticated_userid',
                               return_value='mallory'):
            self.app.patch('/service', status=HTTPForbidden.code)

    def test_acl_support_authenticated_allowed_service_put(self):
        with mock.patch.object(self.authn_policy,
                               'unauthenticated_userid',
                               return_value='dan'):
            result = self.app.put('/service', status=HTTPOk.code)
            self.assertEqual("updated_view", result.json)

    def test_acl_support_authenticated_valid_user_wrong_permission_service_put(
            self):
        with mock.patch.object(self.authn_policy,
                               'unauthenticated_userid',
                               return_value='bob'):
            self.app.put('/service', status=HTTPForbidden.code)

    def test_acl_support_authenticated_valid_user_permission_denied_service_put(
            self):
        with mock.patch.object(self.authn_policy,
                               'unauthenticated_userid',
                               return_value='carol'):
            self.app.put('/service', status=HTTPForbidden.code)

    def test_acl_support_authenticated_invalid_user_service_put(self):
        with mock.patch.object(self.authn_policy,
                               'unauthenticated_userid',
                               return_value='mallory'):
            self.app.put('/service', status=HTTPForbidden.code)

    def test_class_support(self):
        self.app.get('/fresh-air', status=400)
        resp = self.app.get('/fresh-air', headers={'X-Temperature': '50'})
        self.assertEqual(resp.body, b'fresh air with context!')
Example #13
0
class DwarfTestCase(utils.TestCase):

    def setUp(self):
        super(DwarfTestCase, self).setUp()
        self.app = TestApp(ApiServer().app)

    # Commented out to silence pylint
    # def tearDown(self):
    #     super(DwarfTestCase, self).tearDown()

    def test_list_versions(self):
        resp = self.app.get('/image', status=300)
        self.assertEqual(json.loads(resp.body), list_versions_resp())

    def test_list_images(self):
        # Preload test images
        self.create_image(image1)
        self.create_image(image2)

        resp = self.app.get('/image/v2/images', status=200)
        self.assertEqual(json.loads(resp.body),
                         list_images_resp([image1, image2]))

    def test_show_image(self):
        # Preload a test image
        self.create_image(image1)

        resp = self.app.get('/image/v2/images/%s' % image1['id'], status=200)
        self.assertEqual(json.loads(resp.body), show_image_resp(image1))

    def test_delete_image(self):
        # Preload a test image
        self.create_image(image1)

        resp = self.app.delete('/image/v2/images/%s' % image1['id'],
                               status=204)
        self.assertEqual(resp.body, '')
        self.assertEqual(os.path.exists('/tmp/dwarf/images/%s' % image1['id']),
                         False)

        resp = self.app.get('/image/v2/images', status=200)
        self.assertEqual(json.loads(resp.body), list_images_resp([]))

    def test_update_image(self):
        # Preload a test image
        self.create_image(image1)

        key = 'name'
        val = 'Patched test image 1'

        resp = self.app.patch('/image/v2/images/%s' % image1['id'],
                              params=json.dumps([{'op': 'replace',
                                                  'path': '/' + key,
                                                  'value': val}]),
                              status=200)

        patched = deepcopy(image1)
        patched[key] = val
        self.assertEqual(json.loads(resp.body), update_image_resp(patched))

    def test_create_image(self):
        # Create the image in the database
        resp = self.app.post('/image/v2/images',
                             params=json.dumps(create_image_req(image1)),
                             status=201)
        self.assertEqual(json.loads(resp.body), create_image_resp(image1))

        # Upload the image data
        resp = self.app.put('/image/v2/images/%s/file' % image1['id'],
                            params=image1['data'], status=204)
        with open('/tmp/dwarf/images/%s' % image1['id'], 'r') as fh:
            self.assertEqual(fh.read(), image1['data'])

    # -------------------------------------------------------------------------
    # Additional tests for code coverage

    def test_delete_image_cc(self):
        # Preload a test image
        self.create_image(image1)
        os.unlink(image1['file'])

        resp = self.app.delete('/image/v2/images/%s' % image1['id'],
                               status=204)
        self.assertEqual(resp.body, '')
Example #14
0
class TestResourceRecognition(Test):
    def setUp(self):
        from nefertari.resource import add_resource_routes
        self.config = _create_config()
        add_resource_routes(
            self.config,
            DummyCrudRenderedView,
            'message',
            'messages',
            renderer='string'
        )
        self.config.begin()
        self.app = TestApp(self.config.make_wsgi_app())
        self.collection_path = '/messages'
        self.collection_name = 'messages'
        self.member_path = '/messages/{id}'
        self.member_name = 'message'

    def test_get_collection(self):
        self.assertEqual(self.app.get('/messages').body, six.b('index'))

    def test_get_collection_json(self):
        from nefertari.resource import add_resource_routes
        add_resource_routes(
            self.config,
            DummyCrudRenderedView,
            'message',
            'messages',
            renderer='json'
        )
        self.assertEqual(self.app.get('/messages').body, six.b('"index"'))

    def test_get_collection_nefertari_json(self):
        from nefertari.resource import add_resource_routes
        add_resource_routes(
            self.config,
            DummyCrudRenderedView,
            'message',
            'messages',
            renderer='nefertari_json'
        )
        self.assertEqual(self.app.get('/messages').body, six.b('"index"'))

    def test_get_collection_no_renderer(self):
        from nefertari.resource import add_resource_routes
        add_resource_routes(
            self.config, DummyCrudRenderedView, 'message', 'messages')
        self.assertRaises(ValueError, self.app.get, '/messages')

    def test_post_collection(self):
        result = self.app.post('/messages').body
        self.assertEqual(result, six.b('create'))

    def test_head_collection(self):
        response = self.app.head('/messages')
        self.assertEqual(response.body, six.b(''))
        self.assertEqual(response.status_code, 200)
        self.assertTrue(response.headers)

    def test_get_member(self):
        result = self.app.get('/messages/1').body
        self.assertEqual(result, six.b('show'))

    def test_head_member(self):
        response = self.app.head('/messages/1')
        self.assertEqual(response.body, six.b(''))
        self.assertEqual(response.status_code, 200)
        self.assertTrue(response.headers)

    def test_put_member(self):
        result = self.app.put('/messages/1').body
        self.assertEqual(result, six.b('replace'))

    def test_patch_member(self):
        result = self.app.patch('/messages/1').body
        self.assertEqual(result, six.b('update'))

    def test_delete_member(self):
        result = self.app.delete('/messages/1').body
        self.assertEqual(result, six.b('delete'))
class PyramidPeeweeMarshmallowTestCase(unittest.TestCase):
    def setUp(self):
        from webtest import TestApp  # Imported here in order to avoid dummy warning from pytest

        db.drop_tables([User])
        db.create_tables([User])

        self.app = create_app()
        self.client = TestApp(self.app)

    def test_list_users(self):
        _create_user(first_name='Filipe', last_name='Waitman')

        response = self.client.get('/api/users/')
        assert response.status_code == 200
        assert response.json_body['count'] == 1
        assert response.json_body['next_page'] is None
        assert response.json_body['prev_page'] is None
        assert 'id' in response.json_body['results'][0]
        assert 'created' in response.json_body['results'][0]
        assert response.json_body['results'][0]['first_name'] == 'Filipe'
        assert response.json_body['results'][0]['last_name'] == 'Waitman'

    def test_create(self):
        data = {
            'first_name': 'Filipe',
            'last_name': 'Waitman',
        }

        response = self.client.post_json('/api/users/', data)
        assert response.status_code == 201
        assert response.json_body['first_name'] == 'Filipe'
        assert response.json_body['last_name'] == 'Waitman'
        assert response.json_body.get('id')
        assert response.json_body.get('created')
        assert User.select().filter(id=response.json_body['id']).count() == 1

        instance = User.select().filter(id=response.json_body['id']).get()
        assert instance.first_name == 'Filipe'
        assert instance.last_name == 'Waitman'

    def test_create_errors(self):
        data = {
            'first_name': 'Filipe',
            'last_name': 'Waitman',
        }

        response = self.client.post('/api/users/', data, status=400)
        assert response.status_code == 400
        assert response.json_body == {'first_name': ['Missing data for required field.'], 'last_name': ['Missing data for required field.'], 'status_code': 400}  # noqa

        del data['first_name']
        response = self.client.post_json('/api/users/', data, status=400)
        assert response.status_code == 400
        assert response.json_body == {'first_name': ['Missing data for required field.'], 'status_code': 400}

    def test_retrieve(self):
        user = _create_user(first_name='Filipe', last_name='Waitman')

        response = self.client.get('/api/users/{}/'.format(user.id))
        assert response.status_code == 200
        assert 'id' in response.json_body
        assert 'created' in response.json_body
        assert response.json_body['first_name'] == 'Filipe'
        assert response.json_body['last_name'] == 'Waitman'

    def test_retrieve_errors(self):
        response = self.client.get('/api/users/999/', status=404)
        assert response.status_code == 404
        assert response.json_body == {'status_code': 404}

    def test_update(self):
        user = _create_user(first_name='Filipe', last_name='Waitman')
        data = {
            'last_name': 'New',
        }

        response = self.client.patch_json('/api/users/{}/'.format(user.id), data)
        assert response.status_code == 200
        assert 'id' in response.json_body
        assert 'created' in response.json_body
        assert response.json_body['first_name'] == 'Filipe'
        assert response.json_body['last_name'] == 'New'

        instance = User.select().filter(id=response.json_body['id']).get()
        assert instance.last_name == 'New'

    def test_update_errors(self):
        user = _create_user(first_name='Filipe', last_name='Waitman')
        data = {
            'last_name': '',
        }

        response = self.client.patch_json('/api/users/{}/'.format(user.id), data, status=400)
        assert response.status_code == 400
        assert response.json_body == {'last_name': ['Shorter than minimum length 1.'], 'status_code': 400}

        instance = User.select().filter(id=user.id).get()
        assert instance.last_name == 'Waitman'

    def test_delete(self):
        user = _create_user(first_name='Filipe', last_name='Waitman')

        response = self.client.delete('/api/users/{}/'.format(user.id))
        assert response.status_code == 204
        assert User.select().filter(id=user.id).count() == 0

    def test_doublename(self):
        user = _create_user(first_name='Filipe', last_name='Waitman')

        response = self.client.get('/api/users/{}/doublename/'.format(user.id))
        assert response.status_code == 200
        assert response.json_body == {'doubled': 'FilipeFilipe'}
        assert response.headers['header-passed-in'] == '1'

    def test_pagination(self):
        _create_user(first_name='Filipe', last_name='Waitman')
        _create_user(first_name='John', last_name='Doe')

        response = self.client.get('/api/users/')
        assert response.status_code == 200
        assert response.json_body['count'] == 2
        assert response.json_body['next_page'] is None
        assert response.json_body['prev_page'] is None
        assert len(response.json_body['results']) == 2

        response = self.client.get('/api/users/?per_page=1&x=y')
        assert response.status_code == 200
        assert response.json_body['count'] == 2
        assert response.json_body['next_page'] is not None
        assert response.json_body['prev_page'] is None
        assert len(response.json_body['results']) == 1
        assert 'http' in response.json_body['next_page']
        assert 'localhost' in response.json_body['next_page']
        assert '/api/users/' in response.json_body['next_page']
        assert 'x=y' in response.json_body['next_page']
        assert 'per_page=1' in response.json_body['next_page']
        assert 'page=2' in response.json_body['next_page']

        response = self.client.get('/api/users/?per_page=1&page=2')
        assert response.status_code == 200
        assert response.json_body['count'] == 2
        assert response.json_body['next_page'] is None
        assert response.json_body['prev_page'] is not None
        assert len(response.json_body['results']) == 1

    @mock.patch.object(MyBaseAPI, 'get_current_user', return_value=None)
    def test_permissions(self, *mocks):
        user = _create_user(first_name='Filipe', last_name='Waitman')

        # User API
        response = self.client.get('/api/users/', status=401)
        assert response.status_code == 401

        response = self.client.post('/api/users/', status=401)
        assert response.status_code == 401

        response = self.client.get('/api/users/{}/'.format(user.id), status=401)
        assert response.status_code == 401

        response = self.client.patch('/api/users/{}/'.format(user.id), status=401)
        assert response.status_code == 401

        response = self.client.delete('/api/users/{}/'.format(user.id), status=401)
        assert response.status_code == 401

        response = self.client.get('/api/users/{}/doublename/'.format(user.id), status=401)
        assert response.status_code == 401

        # UserOpen API
        response = self.client.get('/api/users/{}/doublename_open/'.format(user.id))
        assert response.status_code == 200

        # UserReadOnly API
        response = self.client.get('/api/users/read_only/')
        assert response.status_code == 200

        response = self.client.post('/api/users/read_only/', status=403)
        assert response.status_code == 403

    def test_form_data_create(self):
        data = {
            'first_name': 'Filipe',
            'last_name': 'Waitman',
        }

        response = self.client.post_json('/api/users/form_data/', data, status=400)
        assert response.status_code == 400
        assert response.json_body == {'first_name': ['Missing data for required field.'], 'last_name': ['Missing data for required field.'], 'status_code': 400}  # noqa

        response = self.client.post('/api/users/form_data/', data)
        assert response.status_code == 201

    def test_no_pagination_list(self):
        _create_user(first_name='Filipe', last_name='Waitman')

        response = self.client.get('/api/users/no_pagination/')
        assert response.status_code == 200
        assert len(response.json_body) == 1
        assert 'next_page' not in response.json_body
        assert 'prev_page' not in response.json_body
        assert 'id' in response.json_body[0]
        assert 'created' in response.json_body[0]
        assert response.json_body[0]['first_name'] == 'Filipe'
        assert response.json_body[0]['last_name'] == 'Waitman'

    def test_no_pagination_list_via_query_params(self):
        _create_user(first_name='Filipe', last_name='Waitman')

        response = self.client.get('/api/users/?paginate=f')
        assert response.status_code == 200
        assert len(response.json_body) == 1
        assert 'next_page' not in response.json_body
        assert 'prev_page' not in response.json_body
        assert 'id' in response.json_body[0]
        assert 'created' in response.json_body[0]
        assert response.json_body[0]['first_name'] == 'Filipe'
        assert response.json_body[0]['last_name'] == 'Waitman'

    def test_exception_behavior(self):
        response = self.client.get('/api/users/exception/handled/', status=499)
        assert response.status_code == 499
        assert response.json_body == {'detail': 'Now this is a weird HTTP code', 'status_code': 499}

        with pytest.raises(ZeroDivisionError):
            self.client.get('/api/users/exception/unhandled/')

        response = self.client.get('/api/users', status=404)  # Missing trailing slash (out of wrf scope)
        assert response.status_code == 404