Example #1
0
    def test_validation(self):
        app = TestApp(main({}))
        app.get('/service', status=400)

        res = app.post('/service', params='buh', status=400)
        self.assertTrue('Not a json body' in res.body)

        res = app.post('/service', params=json.dumps('buh'))

        self.assertEqual(res.body, json.dumps({'body': '"buh"'}))

        app.get('/service?paid=yup')

        # valid = foo is one
        res = app.get('/service?foo=1&paid=yup')
        self.assertEqual(res.json['foo'], 1)

        # invalid value for foo
        res = app.get('/service?foo=buh&paid=yup', status=400)

        # check that json is returned
        errors = Errors.from_json(res.body)
        self.assertEqual(len(errors), 1)

        # let's see the docstring !
        apidocs = app.app.registry.settings['apidocs']
        post_doc = apidocs[('/service', 'POST')]['docstring']
        self.assertEqual(post_doc, 'The request body should be a JSON object.')
Example #2
0
def test_register_and_verify_user():
    config.activate_profile()
    _clear_db()
    s, user_manager = _get_user_manager()
    app = controllers.make_app()
    app = TestApp(app)
    resp = app.post('/register/new/BillBixby', dict(email="*****@*****.**",
                                                    password="******"))
    assert resp.content_type == "application/json"
    data = simplejson.loads(resp.body)
    assert data == {}
    assert resp.cookies_set['auth_tkt']
    assert app.cookies
    billbixby = user_manager.get_user("BillBixby")
    sample_project = model.get_project(billbixby, billbixby, "SampleProject")
    files = [file.name for file in sample_project.list_files()]
    assert "readme.txt" in files
    
    # should be able to run again without an exception appearing
    resp = app.post('/register/new/BillBixby', dict(email="*****@*****.**",
                                                    password="******"),
                    status=409)
    
    # with the cookie set, we should be able to retrieve the 
    # logged in name
    resp = app.get('/register/userinfo/')
    assert resp.content_type == 'application/json'
    data = simplejson.loads(resp.body)
    assert data['username'] == 'BillBixby'
    assert 'quota' in data
    assert data['quota'] == 15728640
    assert 'amountUsed' in data
    
    resp = app.get("/file/at/BespinSettings/config.js")
    app.post("/file/close/BespinSettings/config.js")
Example #3
0
def injectionattack():
    app = TestApp(test.app)
    app.post('/login', {'username':'******','password':'******'})
    assert app.get('/admin').status == '200 OK'
    app.get('/logout')
    app.reset()
    assert app.get('/admin').status == '401 Unauthorized'
def test_previous_next():
    c = Client(App())

    c.post('/documents/add_submit', {'title': 'Two', 'content': 'Secundus'})

    response = c.get('/documents/?limit=1&offset=0')
    expected_documents = [{
        "id": 1,
        "title": "My Title",
        "content": "My Content",
        "link": "http://localhost/documents/1"
    }]

    assert response.json["documents"] == expected_documents
    assert "http://localhost/documents/add" in response.json["add"]
    assert response.json["previous"] is None
    assert "http://localhost/documents" in response.json["next"]
    assert "limit=1" in response.json["next"]
    assert "offset=1" in response.json["next"]

    response = c.get('/documents/?limit=1&offset=1')
    expected_documents = [{
        "id": 2,
        "title": "Two",
        "content": "Secundus",
        "link": "http://localhost/documents/2"
    }]

    assert response.json["documents"] == expected_documents
    assert "http://localhost/documents/add" in response.json["add"]
    assert "http://localhost/documents" in response.json["previous"]
    assert "limit=1" in response.json["previous"]
    assert "offset=0" in response.json["previous"]
    assert response.json["next"] is None
Example #5
0
class TestApplication(unittest.TestCase):
    def setUp(self):
        logging.basicConfig(level=logging.INFO)
        self.redis = mock.Mock()

        app.db_client = self.redis
        self.test_app = TestApp(app)

    def test_health_check(self):
        resp = self.test_app.get("/health_check")
        self.assertEqual(200, resp.status_int)

    def test_add_vote(self):
        self.test_app.get("/vote/test_key")

        self.redis.incrVote.assert_called_with(u"test_key")
        self.redis.getVote.assert_called_with(u"test_key")

    def test_get_vote(self):
        self.test_app.post("/clear", {"key":"test_key"})
        self.redis.clearVote.assert_called_with("test_key")

    @mock.patch('requests.get')
    def test_proxy_hulu(self, mock_requests):
        response = mock.Mock()
        response.status_code = 200
        mock_requests.return_value = response

        resp = self.test_app.get("/proxy_hulu")
        self.assertEqual(200, resp.status_int)
        mock_requests.assert_called_with("http://www.hulu.com")
Example #6
0
class TestViewBase(unittest.TestCase):
    """In setup, bootstrap the app and make sure we clean up after ourselves

    """
    def setUp(self):
        """Setup Tests"""
        from pyramid.paster import get_app
        from bookie.tests import BOOKIE_TEST_INI
        app = get_app(BOOKIE_TEST_INI, 'bookie')
        from webtest import TestApp
        self.app = TestApp(app)
        testing.setUp()
        res = DBSession.execute(
            "SELECT api_key FROM users WHERE username = '******'").\
            fetchone()
        self.api_key = res['api_key']

    def tearDown(self):
        """Tear down each test"""
        testing.tearDown()
        empty_db()

    def _login_admin(self):
        """Make the login call to the app"""
        self.app.post(
            '/login',
            params={
                "login": u"admin",
                "password": u"admin",
                "form.submitted": u"Log In",
            },
            status=302)
Example #7
0
    def test_simple_validation(self):
        class RegistrationSchema(Schema):
            first_name         = validators.String(not_empty=True)
            last_name          = validators.String(not_empty=True)
            email              = validators.Email()
            username           = validators.PlainText()
            password           = validators.String()
            password_confirm   = validators.String()
            age                = validators.Int()
            chained_validators = [
                validators.FieldsMatch('password', 'password_confirm')
            ]
        

        class RootController(object):
            @expose(schema=RegistrationSchema())
            def index(self, first_name, 
                            last_name, 
                            email, 
                            username, 
                            password,
                            password_confirm,
                            age):
                assert age == 31
                assert isinstance(age, int)
                return 'Success!'
            
            @expose(json_schema=RegistrationSchema())
            def json(self, data):
                assert data['age'] == 31
                assert isinstance(data['age'], int)
                return 'Success!'


        # test form submissions
        app = TestApp(make_app(RootController()))
        r = app.post('/', dict(
            first_name='Jonathan',
            last_name='LaCour',
            email='*****@*****.**',
            username='******',
            password='******',
            password_confirm='123456',
            age='31'
        ))
        assert r.status_int == 200
        assert r.body == 'Success!'
        
        # test JSON submissions
        r = app.post('/json', dumps(dict(
            first_name='Jonathan',
            last_name='LaCour',
            email='*****@*****.**',
            username='******',
            password='******',
            password_confirm='123456',
            age='31'
        )), [('content-type', 'application/json')])
        assert r.status_int == 200
        assert r.body == 'Success!'
 def test_enforce_https_wrong(self):
     config = copy.deepcopy(SHARED_DEFAULTS)
     config["enforce_https"] = True
     application = RoutingApplication(config)
     app = TestApp(application, extra_environ={"REMOTE_ADDR": "127.0.0.1"})
     app.get("/", status=406)
     app.post("/connect", status=406)
Example #9
0
class PostTestCase(DatastoreTestCase):
    def setUp(self):
        super(PostTestCase, self).setUp()
        self.app = TestApp(app)

    def test_successful_login(self):
        User.create('ThePope', 'this is my password')
        data = {
            'username': '******',
            'password': '******'}
        resp = self.app.post('/login', data, headers={'referer': '/login'})
        self.assertEqual(resp.status_code, 302)
        self.assertEqual(resp.location, 'http://localhost/')

    def test_unsuccessful_login_bad_user(self):
        data = {
            'username': '******',
            'password': '******'}
        resp = self.app.post('/login', data)
        self.assertEqual(resp.status_code, 302)
        self.assertEqual(resp.location, 'http://localhost/login')

    def test_unsuccessful_login_bad_password(self):
        User.create('ThePope', 'this is my password')
        data = {
            'username': '******',
            'password': '******'}
        resp = self.app.post('/login', data)
        self.assertEqual(resp.status_code, 302)
        self.assertEqual(resp.location, 'http://localhost/login')
Example #10
0
class FunctionalTests(unittest.TestCase):
    def setUp(self):
        from app import main
        app = main({})
        from webtest import TestApp
        self.testapp = TestApp(app)

    def test_root(self):
        res = self.testapp.get('/')
        assert res.status_int == 200

    def test_encrypt(self):
        data = {'plainText': 'test', 'key': 'b'}
        resp = self.testapp.post(
            '/encrypt',
            json.dumps(data),
            content_type='application/json; utf-8',
            xhr=True
        )
        assert resp.json['data']['originalText'] == 'test'
        assert resp.json['data']['encryptedText'] == 'uftu'

    def test_decrypt(self):
        data = {'cipherText': 'uftu', 'key': 'b'}
        resp = self.testapp.post(
            '/decrypt',
            json.dumps(data),
            content_type='application/json; utf-8',
            xhr=True
        )
        assert resp.json['data']['originalText'] == 'uftu'
        assert resp.json['data']['decryptedText'] == 'test'
Example #11
0
class TestLogin(unittest.TestCase):

    bad_credentials = {'email': '*****@*****.**',
                       'password': '******'}

    # Please use valid credentials and targets
    good_credentials = {'email': '*****@*****.**',
                        'password': '******'}

    def setUp(self):
        # use a default 'dummy' config file.
        config = {'auth.backend': '%s.%s' % (FakeAuthTool.__module__,
                                             FakeAuthTool.__name__),
            'oidstorage.backend': 'memory',
            'oid.host': 'http://localhost',
            'oid.assoc_expires_in': 3600}
        self.app = TestApp(make_app(config))


    def test_bad_login(self):
        response = self.app.post('/1/login', params=self.bad_credentials)
        import pdb; pdb.set_trace()
        self.failIf('Login failed' not in
                    response.body)


    def test_login(self):
        params = self.good_credentials.copy()
        params['output']='json'
        res = self.app.post('/1/login', params, status=200)
        self.failIf(json.loads(res.body)['success'] != True)
Example #12
0
class ApiTestCase(unittest.TestCase):
    def setUp(self):
        self.app = TestApp(api.app)
        self.app.authorization = ('Basic', ('admin', 'password'))

    def test_should_have_ELASTICSEARCH_HOST_defined(self):
        self.assertIsNotNone(api.ELASTICSEARCH_HOST)

    def test_ELASTIC_SEARCH_HOST_should_be_filled_by_environ_var(self):
        IP = "192.169.56.2"

        os.environ["ELASTICSEARCH_HOST"] = IP
        reload(api)
        self.assertEqual(IP, api.ELASTICSEARCH_HOST)

    def test_add_should_return_empty_body(self):
        self.assertEqual(201, self.app.post("/resources").status_code )

    def test_bind_should_return_elasticsearch_host_as_json_in_body(self):
        self.assertDictEqual({"ELASTICSEARCH_HOST": api.ELASTICSEARCH_HOST,
                                "ELASTICSEARCH_PORT": "9200"},
                             json.loads(self.app.post("/resources/example_app/bind-app").body))

    def test_unbind_body_should_be_empty(self):
        self.assertEqual( ("", 200), api.unbind("test"))
Example #13
0
class TestBandController(object):

    def setup(self):
        self.band_catalog = dict()
        web_server.BandController.catalog = self.band_catalog
        self.app = TestApp(web_server.app.wsgifunc(*[]))

    def fill_catalog_with(self, key, band):
        self.band_catalog[key] = band

    def on_post_saves_band_in_catalog_test(self):
        band = create_band(name='BandName')
        self.app.post('/band/1', transform.band_to_json(band))
        assert_in('1', self.band_catalog)
        assert_equals(band, self.band_catalog['1'])

    def on_get_returns_band_from_catalog_test(self):
        band = create_band(name='BandName')
        self.fill_catalog_with('1', band)
        response = self.app.get('/band/1')
        res = transform.json_to_band(response.body)
        assert_equals(res, band)

    def on_get_status_is_not_found_if_band_not_found_test(self):
       self.app.get('/band/non-existing-key', status=404)
Example #14
0
 def test_callable_error_handler(self):
     
     class ColorSchema(Schema):
         colors = ForEach(validators.String(not_empty=True))
     
     class RootController(object):
         
         @expose()
         def errors(self, *args, **kwargs):
             return 'There was an error!'
         
         @expose(schema=ColorSchema(), 
                 error_handler=lambda: '/errors',
                 variable_decode=True)
         def index(self, **kwargs):
             return 'Success!'
     
     # test with error handler
     app = TestApp(make_app(RootController()))
     r = app.post('/', {
         'colors-0' : 'blue',
         'colors-1' : 'red'
     })
     assert r.status_int == 200
     assert r.body == 'Success!'
     
     # test with error handler
     r = app.post('/', {
         'colors-0' : 'blue',
         'colors-1' : ''
     })
     assert r.status_int == 200
     assert r.body == 'There was an error!'
Example #15
0
    def test_SyncEntity(self):
        """Synchronizing an entity."""

        from gaesynkit import handlers
        from webtest import AppError, TestApp

        # Initialize app
        app = TestApp(handlers.app)

        # Make a request
        res = app.post(
            '/gaesynkit/rpc/',
            '{"jsonrpc":"2.0","method":"syncEntity","params":[{"kind":"Book","key":"dGVzdEBkZWZhdWx0ISFCb29rCjI=","version":0,"id":2,"properties":{"title":{"type":"string","value":"The Catcher in the Rye"},"date":{"type":"gd:when","value":"1951/7/16 0:0:0"},"classic":{"type":"bool","value":true},"pages":{"type":"int","value":288},"tags":{"type":"string","value":["novel","identity"]}}},"6eb9a4d405f3ee6c67e965b7693108d2"],"id":3}')
 
        self.assertEqual("200 OK", res.status)
        self.assertEqual(
            simplejson.loads(res.body),
            {u'jsonrpc': u'2.0', u'result': {u'status': 3, u'version': 1, u'key': u'dGVzdEBkZWZhdWx0ISFCb29rCjI='}, u'id': 3})

        res = app.post(
            '/gaesynkit/rpc/',
            '{"jsonrpc":"2.0","method":"syncEntity","params":[{"kind":"Book","key":"dGVzdEBkZWZhdWx0ISFCb29rCjI=","version":1,"id":2,"properties":{"title":{"type":"string","value":"The Catcher in the Rye"},"date":{"type":"gd:when","value":"1951/7/16 0:0:0"},"classic":{"type":"bool","value":true},"pages":{"type":"int","value":287},"tags":{"type":"string","value":["novel","identity"]}}},"7ec49827a52b56fdd24b07410c9bf0d6"],"id":4}')

        self.assertEqual("200 OK", res.status)
        self.assertEqual(
            simplejson.loads(res.body),
            {u'jsonrpc': u'2.0', u'result': {u'status': 2, u'entity': {u'kind': u'Book', u'version': 2, u'properties': {u'date': {u'type': u'gd:when', u'value': u'1951/07/16 00:00:00'}, u'classic': {u'type': u'bool', u'value': True}, u'pages': {u'type': u'int', u'value': 287}, u'tags': {u'type': u'string', u'value': [u'novel', u'identity']}, u'title': {u'type': u'string', u'value': u'The Catcher in the Rye'}}, u'key': u'dGVzdEBkZWZhdWx0ISFCb29rCjI=', u'id': 1}}, u'id': 4})

        res = app.post(
            '/gaesynkit/rpc/',
            '{"jsonrpc":"2.0","method":"syncEntity","params":[{"kind":"Book","key":"dGVzdEBkZWZhdWx0ISFCb29rCjI=","version":0,"id":2,"properties":{"title":{"type":"string","value":"The Catcher in the Rye"},"date":{"type":"gd:when","value":"1951/7/16 0:0:0"},"classic":{"type":"bool","value":true},"pages":{"type":"int","value":287},"tags":{"type":"string","value":["novel","identity"]}}},"7ec49827a52b56fdd24b07410c9bf0d6"],"id":4}')

        self.assertEqual("200 OK", res.status)
Example #16
0
class ViewTests(unittest.TestCase):
    def setUp(self):
        import os
        import pkg_resources
        from pyramid.paster import bootstrap
        pkgroot = pkg_resources.get_distribution('quizr').location
        testing_ini = os.path.join(pkgroot, 'testing.ini')
        env = bootstrap(testing_ini)
        self.closer = env['closer']
        from webtest import TestApp
        self.testapp = TestApp(env['app'])

    def tearDown(self):
        import transaction
        transaction.abort()
        self.closer()

    def login(self):
        self.testapp.post(
            '/register',
            {
                'form.submitted': u'Register',
                'username': u'username',
                'password': u'secret',
                'confirm_password': u'secret',
                'email': u'*****@*****.**',
                'name': u'John Doe',
            },
            status=302,
        )
        self.testapp.post(
            '/login',
            {'login': '******', 'password': '******'},
            status=302,
        )
Example #17
0
def test_log_tween_include_with_comma_separator():
    # This tests automatic instrumentation of Pyramid views, using the
    # NewEvent subscriber

    with mock.patch('notaliens.log.logger') as mock_logger:
        def view_func(request):
            return {
                'status': 0,
                'data': {
                    'foo': 'bar',
                },
            }

        # Create a WSGI app with Pyramid and then wrap it with
        # webtest.TestApp for testing
        config = testing.setUp()
        config.add_route('view', '/view')
        config.add_view(view_func, route_name='view', renderer='json')
        config.include('notaliens.log')
        config.logging_separator(', ')
        app = config.make_wsgi_app()
        app = TestApp(app)

        def info(log_template, template_params):
            assert log_template == 'ms=%(ms)s, view=%(view)s'

        mock_logger.info.side_effect = info
        app.post('/view', params="", status=200)
        assert mock_logger.info.called
Example #18
0
def test_perflog_view_dictionary_w_empty_prefix_extra_logging():
    with mock.patch('notaliens.log.logger') as mock_logger:
        def view_func(request):
            return {
                'status': 0,
                'data': {'output_key': 'output_val'},
            }

        # Create a WSGI app with Pyramid and then wrap it with
        # webtest.TestApp for testing
        config = testing.setUp()
        config.add_route('view', '/view')
        config.add_view(view_func, route_name='view', renderer='json')
        config.include('notaliens.log')
        config.add_logging("", lambda req: {'foo': 'bar'})
        app = config.make_wsgi_app()
        app = TestApp(app)

        def info(log_template, template_params):
            assert 'ms=%(ms)s view=%(view)s foo=%(foo)s' == log_template
            assert template_params['foo'] == 'bar'

        mock_logger.info.side_effect = info

        app.post('/view', status=200)

        assert mock_logger.info.called
Example #19
0
    def test_validation(self):
        app = TestApp(main({}))
        app.get('/service', status=400)

        res = app.post('/service', params='buh', status=400)
        self.assertTrue('Not a json body' in res.body)

        res = app.post('/service', params=json.dumps('buh'))

        self.assertEqual(res.body, json.dumps({'body': '"buh"'}))

        app.get('/service?paid=yup')

        # valid = foo is one
        res = app.get('/service?foo=1&paid=yup')
        self.assertEqual(res.json['foo'], 1)

        # invalid value for foo
        res = app.get('/service?foo=buh&paid=yup', status=400)

        # check that json is returned
        errors = Errors.from_json(res.body)
        self.assertEqual(len(errors), 1)

        # the "apidocs" registry entry contains all the needed information
        # to build up documentation
        # in this case, this means the function is registered and the argument
        # of the service are defined (e.g "validator" is set)
        apidocs = app.app.registry.settings['apidocs']

        self.assertTrue(_json in apidocs[('/service', 'POST')]['validators'])
Example #20
0
class TestService(TestCase):

    def setUp(self):
        self.config = testing.setUp()
        self.config.include("cornice")
        self.config.scan("cornice.tests.test_service")
        self.config.scan("cornice.tests.test_pyramidhook")
        self.app = TestApp(CatchErrors(self.config.make_wsgi_app()))

    def tearDown(self):
        testing.tearDown()

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

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

    def test_acl_support(self):
        self.app.delete('/service')

    def test_class_support(self):
        self.app.get('/fresh-air', status=400)
        resp = self.app.get('/fresh-air', headers={'X-Temperature': '50'})
        self.assertEquals(resp.body, 'fresh air')
Example #21
0
class TestService(unittest.TestCase):

    def setUp(self):
        self.config = testing.setUp()
        self.config.include("cornice")
        self.config.scan("cornice.tests.test_service")
        self.app = TestApp(CatchErrors(self.config.make_wsgi_app()))

    def tearDown(self):
        testing.tearDown()

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

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

    def test_warning(self):

        service = Service(name='blah', path='/blah')
        msg = "'validator' is deprecated, please use 'validators'"

        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")

            # this should raise a warning, but work
            @service.post(validator=())
            def bah(req):
                pass

            self.assertEqual(msg, str(w[-1].message))
class TestXAControlServerApp(TestCase):
    def setUp(self):
        XAControlServerApp.testing = True
        self.app = XAControlServerApp()
        self.apiuser = "******"
        self.apikey = "AUALUON"

        self.testapp = TestApp(self.app.wsgiApp())
        self.testapp.authorization = ('Basic', (self.apiuser, self.apikey))

    def test_status_GET(self):
        res = self.testapp.get('/status', status=200)
        self.assertTrue("MEMORY_USAGE" in res.json)


    def test_relay_POST(self):
        CHANNEL = 0
        STATE = 1
        res = self.testapp.post(
            '/relay/{CHANNEL}/{STATE}'.format(
                CHANNEL=CHANNEL,
                STATE=STATE
            ),
            status=200
        )
        time.sleep(1)
        STATE = 0
        res = self.testapp.post(
            '/relay/{CHANNEL}/{STATE}'.format(
                CHANNEL=CHANNEL,
                STATE=STATE
            ),
            status=200
        )
class TestCommands(unittest2.TestCase):
    def setUp(self):
        # Test application
        self.app = TestApp(alignak_webui.app.session_app)

        self.app.post('/login', {'username': '******', 'password': '******'})

    def tearDown(self):
        self.app.get('/logout')

    def test_commands(self):
        """ Web - commands """
        print('test commands')

        print('get page /commands')
        response = self.app.get('/commands')
        print(response)
        response.mustcontain(
            '<div id="commands">',
            '25 elements out of ',
        )
        self.app.get('/commands/settings')
        self.app.get('/commands/list')
        self.app.get('/commands/table')

    def test_command(self):
        """ Web - command"""
        print('test command')

        print('get page /command')
        response = self.app.get('/command/check_nrpe_version')
        response.mustcontain(
            '<div class="command" id="command_'
        )
Example #24
0
class TestAuthenticatedCORS(TestCase):
    def setUp(self):

        def check_cred(username, *args, **kwargs):
            return [username]

        @implementer(IAuthorizationPolicy)
        class AuthorizationPolicy(object):
            def permits(self, context, principals, permission):
                return permission in principals

        self.config = testing.setUp()
        self.config.include('cornice')
        self.config.add_route('noservice', '/noservice')
        self.config.set_authorization_policy(AuthorizationPolicy())
        self.config.set_authentication_policy(BasicAuthAuthenticationPolicy(
            check_cred))
        self.config.set_default_permission('readwrite')
        self.config.scan('cornice.tests.test_cors')
        self.app = TestApp(CatchErrors(self.config.make_wsgi_app()))

    def tearDown(self):
        testing.tearDown()

    def test_post_on_spam_should_be_forbidden(self):
        self.app.post('/spam', status=403)

    def test_preflight_does_not_need_authentication(self):
        self.app.options('/spam', status=200,
                         headers={'Origin': 'notmyidea.org',
                                  'Access-Control-Request-Method': 'POST'})
Example #25
0
def test_inject_request_id():
    with mock.patch('notaliens.log.logger') as mock_logger:
        def view_func(request):
            return {
                'status': 0,
                'data': {
                    'foo': 'bar',
                },
            }

        # Create a WSGI app with Pyramid and then wrap it with
        # webtest.TestApp for testing
        config = testing.setUp()
        config.add_route('view', '/view')
        config.add_view(view_func, route_name='view', renderer='json')
        config.include('notaliens.log')
        app = config.make_wsgi_app()
        app = TestApp(app)

        def info(log_template, template_params):
            import threading
            import re
            thread_name = threading.current_thread().name

            assert thread_name.startswith('MainThread][request=')
            assert re.search(
                r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}",  # nopep8
                thread_name
            )

        mock_logger.info.side_effect = info
        app.post('/view', params="", status=200)
        assert mock_logger.info.called
class TestUsers(unittest2.TestCase):
    def setUp(self):
        # Test application
        self.app = TestApp(alignak_webui.app.session_app)

        self.app.post('/login', {'username': '******', 'password': '******'})

    def tearDown(self):
        self.app.get('/logout')

    def test_users(self):
        """ Web - users """
        print('test users')

        print('get page /users')
        response = self.app.get('/users')
        response.mustcontain(
            '<div id="users">',
            '9 elements out of 9',
        )
        self.app.get('/users/settings')
        self.app.get('/users/list')
        self.app.get('/users/table')
        self.app.get('/users/templates/list')
        self.app.get('/users/templates/table')
Example #27
0
    def test_custom_with_trailing_slash(self):

        class CustomController(RestController):

            _custom_actions = {
                'detail': ['GET'],
                'create': ['POST'],
                'update': ['PUT'],
                'remove': ['DELETE'],
            }

            @expose()
            def detail(self):
                return 'DETAIL'

            @expose()
            def create(self):
                return 'CREATE'

            @expose()
            def update(self, id):
                return id

            @expose()
            def remove(self, id):
                return id

        app = TestApp(make_app(CustomController()))

        r = app.get('/detail')
        assert r.status_int == 200
        assert r.body == b_('DETAIL')

        r = app.get('/detail/')
        assert r.status_int == 200
        assert r.body == b_('DETAIL')

        r = app.post('/create')
        assert r.status_int == 200
        assert r.body == b_('CREATE')

        r = app.post('/create/')
        assert r.status_int == 200
        assert r.body == b_('CREATE')

        r = app.put('/update/123')
        assert r.status_int == 200
        assert r.body == b_('123')

        r = app.put('/update/123/')
        assert r.status_int == 200
        assert r.body == b_('123')

        r = app.delete('/remove/456')
        assert r.status_int == 200
        assert r.body == b_('456')

        r = app.delete('/remove/456/')
        assert r.status_int == 200
        assert r.body == b_('456')
Example #28
0
class osirisTests(unittest.TestCase):
    def setUp(self):
        conf_dir = os.path.dirname(__file__)
        self.app = loadapp('config:test.ini', relative_to=conf_dir)
        from webtest import TestApp
        self.testapp = TestApp(self.app)

    def tearDown(self):
        # self.app.registry.osiris_store._conn.drop_collection(self.app.registry.settings.get('osiris.store.collection'))
        testing.tearDown()

    def test_token_endpoint(self):
        testurl = '/token?grant_type=password&username=testuser&password=test'
        resp = self.testapp.post(testurl, status=200)
        response = resp.json
        self.assertTrue('access_token' in response and len(response.get('access_token')) == 20)
        self.assertTrue('token_type' in response and response.get('token_type') == 'bearer')
        self.assertTrue('scope' in response and response.get('scope') == '')
        self.assertTrue('expires_in' in response and response.get('expires_in') == '0')
        self.assertEqual(resp.content_type, 'application/json')

    def test_token_endpoint_autherror(self):
        # Not the password
        testurl = '/token?grant_type=password&username=testuser&password=notthepassword'
        resp = self.testapp.post(testurl, status=401)
        self.assertEqual(resp.content_type, 'application/json')

        # No such user
        testurl = '/token?grant_type=password&username=nosuchuser&password=notthepassword'
        resp = self.testapp.post(testurl, status=401)
        self.assertEqual(resp.content_type, 'application/json')

    def test_token_storage(self):
        testurl = '/token?grant_type=password&username=testuser&password=test'
        resp = self.testapp.post(testurl, status=200)
        response = resp.json

        token_store = self.app.registry.osiris_store.retrieve(response.get('access_token'))
        self.assertTrue(token_store)
        self.assertEqual(token_store.get('token'), response.get('access_token'))
        self.assertEqual(token_store.get('username'), 'testuser')

    def test_check_token_endpoint(self):
        testurl = '/token?grant_type=password&username=testuser&password=test'
        resp = self.testapp.post(testurl, status=200)
        response = resp.json
        access_token = response.get('access_token')

        testurl = '/checktoken?access_token=%s&username=testuser' % (str(access_token))
        self.testapp.post(testurl, status=200)

    def test_check_token_endpoint_autherror(self):
        testurl = '/token?grant_type=password&username=testuser&password=test'
        resp = self.testapp.post(testurl, status=200)
        response = resp.json
        access_token = response.get('access_token')

        testurl = '/checktoken?access_token=%s&username=testuser2' % (str(access_token))
        self.testapp.post(testurl, status=401)
Example #29
0
    def test_bad_rest(self):

        class ThingsController(RestController):
            pass

        class RootController(object):
            things = ThingsController()

        # create the app
        app = TestApp(make_app(RootController()))

        # test get_all
        r = app.get('/things', status=404)
        assert r.status_int == 404

        # test get_one
        r = app.get('/things/1', status=404)
        assert r.status_int == 404

        # test post
        r = app.post('/things', {'value': 'one'}, status=404)
        assert r.status_int == 404

        # test edit
        r = app.get('/things/1/edit', status=404)
        assert r.status_int == 404

        # test put
        r = app.put('/things/1', {'value': 'ONE'}, status=404)

        # test put with _method parameter and GET
        r = app.get('/things/1?_method=put', {'value': 'ONE!'}, status=405)
        assert r.status_int == 405

        # test put with _method parameter and POST
        r = app.post('/things/1?_method=put', {'value': 'ONE!'}, status=404)
        assert r.status_int == 404

        # test get delete
        r = app.get('/things/1/delete', status=404)
        assert r.status_int == 404

        # test delete
        r = app.delete('/things/1', status=404)
        assert r.status_int == 404

        # test delete with _method parameter and GET
        r = app.get('/things/1?_method=DELETE', status=405)
        assert r.status_int == 405

        # test delete with _method parameter and POST
        r = app.post('/things/1?_method=DELETE', status=404)
        assert r.status_int == 404

        # test "RESET" custom action
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            r = app.request('/things', method='RESET', status=404)
            assert r.status_int == 404
 def test_fallback_no_required_csrf(self):
     service = Service(name='fallback-csrf', path='/', content_type='application/json')
     service.add_view('POST', lambda _:'', require_csrf=False)
     register_service_views(self.config, service)
     self.config.include('cornice')
     app = self.config.make_wsgi_app()
     testapp = TestApp(app)
     testapp.post('/', status=415, headers={'Content-Type': 'application/xml'})
class TestDeleteUser(BaseTestCase):
    def add_user_root(self):
        "Configure app with /users/<username> route"
        self.config = config_factory()
        self.config.add_route('users',
                              'users/*traverse',
                              factory=tree.UserRoot,
                              use_global_views=True)
        self.app = TestApp(self.config.make_wsgi_app())

    def test_success(self):
        "User can delete itself"
        self.add_user_root()

        user = self.makeUser('thruflo', 'Password')
        Session.add(user)

        self.authenticate()

        # Attempt to delete user
        res = self.app.get('/users/thruflo/delete_user')

        # Verify confirmation message
        self.assertTrue('Are you really sure' in res.body)

        # Verify that the user has not yet been deleted
        self.assertTrue(get_existing_user(username='******') is not None)

        # Delete the user
        res = self.app.post('/users/thruflo/delete_user')

        # Verify that the user has now been deleted
        self.assertTrue(get_existing_user(username='******') is None)

        # User should be logged out
        self.assertTrue(len(res.headers['Set-Cookie']) < 200)

    def test_other_user(self):
        "Non-admin user cannot delete other user"
        self.add_user_root()

        # User to delete
        self.makeUser('alice', 'Password')

        # Login as other user
        bob = self.makeUser('bob', 'Password')
        model.save(bob)
        transaction.commit()
        self.authenticate(username='******', password='******')

        # Try to delete user
        res = self.app.post('/users/alice/delete_user', status=403)

        # Verify that the user has not been deleted
        self.assertTrue(get_existing_user(username='******') is not None)
        # User should still be logged in
        self.assertTrue(len(res.headers['Set-Cookie']) > 250)

    def test_admin(self):
        "Admin should be allowed to delete any user"
        self.add_user_root()

        # User to delete
        self.makeUser('alice', 'Password')

        # Login as admin
        admin = self.makeUser('admin', 'Password')
        admin.roles.append(model.Role(name='admin'))
        model.save(admin)
        transaction.commit()
        self.authenticate(username='******', password='******')

        # Delete user
        res = self.app.post('/users/alice/delete_user')

        # Verify that user has been successfully deleted
        self.assertTrue(get_existing_user(username='******') is None)
        # Admin should still be logged in
        self.assertTrue(len(res.headers['Set-Cookie']) > 250)
Example #32
0
class TestResource(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.scan("tests.test_resource")
        self.app = TestApp(CatchErrors(self.config.make_wsgi_app()))

    def tearDown(self):
        testing.tearDown()

    def test_basic_resource(self):
        self.assertEqual(self.app.get("/users").json, {'users': [1, 2]})

        self.assertEqual(self.app.get("/users/1").json, {'name': 'gawel'})

        resp = self.app.get("/users/1?callback=test")

        self.assertIn(b'test({"name": "gawel"})', resp.body, msg=resp.body)

    @mock.patch('cornice.resource.Service')
    def test_without_collection_path_has_one_service(self, mocked_service):
        @resource(path='/nocollection/{id}', name='nocollection')
        class NoCollection(object):
            def __init__(self, request, context=None):
                pass

        self.assertEqual(mocked_service.call_count, 1)

    def test_accept_headers(self):
        # the accept headers should work even in case they're specified in a
        # resource method
        self.assertEqual(
            self.app.post("/users",
                          headers={
                              'Accept': 'text/json'
                          },
                          params=json.dumps({'test': 'yeah'})).json,
            {'test': 'yeah'})

    def patch(self, *args, **kwargs):
        return self.app._gen_request('PATCH', *args, **kwargs)

    def test_head_and_patch(self):
        self.app.head("/users")
        self.app.head("/users/1")

        self.assertEqual(self.patch("/users").json, {'test': 'yeah'})

        self.assertEqual(self.patch("/users/1").json, {'test': 'yeah'})

    def test_context_factory(self):
        self.assertEqual(self.app.put('/users/1').json, {'type': 'context!'})

    def test_explicit_collection_service_name(self):
        route_url = testing.DummyRequest().route_url
        # service must exist
        self.assert_(route_url('collection_user_service'))

    def test_explicit_service_name(self):
        route_url = testing.DummyRequest().route_url
        self.assert_(route_url('user_service', id=42))  # service must exist

    @mock.patch('cornice.resource.Service')
    def test_factory_is_autowired(self, mocked_service):
        @resource(collection_path='/list', path='/list/{id}', name='list')
        class List(object):
            pass

        factory_args = [
            kw.get('factory') for _, kw in mocked_service.call_args_list
        ]
        self.assertEqual([List, List], factory_args)

    def test_acl_is_deprecated(self):
        def custom_acl(request):
            return []

        with self.assertRaises(ConfigurationError):

            @resource(collection_path='/list',
                      path='/list/{id}',
                      name='list',
                      collection_acl=custom_acl,
                      acl=custom_acl)
            class List(object):
                pass

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

    def test_acl_support_unauthenticated_forbidden_thing_get(self):
        # calling a view with permissions without an auth'd user => 403
        with mock.patch.object(self.authn_policy,
                               'authenticated_userid',
                               return_value=None):
            result = self.app.get('/thing', status=HTTPForbidden.code)

    def test_acl_support_authenticated_allowed_thing_get(self):
        with mock.patch.object(self.authn_policy,
                               'unauthenticated_userid',
                               return_value='alice'):
            with mock.patch.object(self.authn_policy,
                                   'authenticated_userid',
                                   return_value='alice'):
                result = self.app.get('/thing', status=HTTPOk.code)
                self.assertEqual("yay", result.json)
Example #33
0
class TestResource(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)

        add_view(ThingImp.collection_get, permission='read')
        thing_resource = add_resource(ThingImp,
                                      collection_path='/thing',
                                      path='/thing/{id}',
                                      name='thing_service',
                                      collection_acl=my_collection_acl)

        add_view(UserImp.get, renderer='json')
        add_view(UserImp.get, renderer='jsonp')
        add_view(UserImp.collection_post, renderer='json', accept='text/json')
        user_resource = add_resource(UserImp,
                                     collection_path='/users',
                                     path='/users/{id}',
                                     name='user_service',
                                     factory=dummy_factory)

        self.config.add_cornice_resource(thing_resource)
        self.config.add_cornice_resource(user_resource)
        self.app = TestApp(CatchErrors(self.config.make_wsgi_app()))

    def tearDown(self):
        testing.tearDown()

    def test_basic_resource(self):
        self.assertEqual(self.app.get("/users").json, {'users': [1, 2]})

        self.assertEqual(self.app.get("/users/1").json, {'name': 'gawel'})

        resp = self.app.get("/users/1?callback=test")

        self.assertIn(b'test({"name": "gawel"})', resp.body, msg=resp.body)

    def test_accept_headers(self):
        # the accept headers should work even in case they're specified in a
        # resource method
        self.assertEqual(
            self.app.post("/users",
                          headers={
                              'Accept': 'text/json'
                          },
                          params=json.dumps({'test': 'yeah'})).json,
            {'test': 'yeah'})

    def patch(self, *args, **kwargs):
        return self.app._gen_request('PATCH', *args, **kwargs)

    def test_head_and_patch(self):
        self.app.head("/users")
        self.app.head("/users/1")

        self.assertEqual(self.patch("/users").json, {'test': 'yeah'})

        self.assertEqual(self.patch("/users/1").json, {'test': 'yeah'})

    def test_context_factory(self):
        self.assertEqual(self.app.put('/users/1').json, {'type': 'context!'})

    def test_explicit_collection_service_name(self):
        route_url = testing.DummyRequest().route_url
        # service must exist
        self.assert_(route_url('collection_user_service'))

    def test_explicit_service_name(self):
        route_url = testing.DummyRequest().route_url
        self.assert_(route_url('user_service', id=42))  # service must exist

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

    def test_acl_support_authenticated_allowed_thing_get(self):
        with mock.patch.object(self.authn_policy,
                               'unauthenticated_userid',
                               return_value='alice'):
            result = self.app.get('/thing', status=HTTPOk.code)
            self.assertEqual("yay", result.json)
Example #34
0
def test_csrf_by_default(csrf_app: TestApp, session: DummySession):
    """CSRF goes throgh if we have a proper token."""

    resp = csrf_app.post("/csrf_sample", {"csrf_token": session.get_csrf_token()})
    assert resp.status_code == 200
Example #35
0
class FunctionalTests(unittest.TestCase):
    def setUp(self):
        self.temp = tempdir.TempDir()
        self.store_dir = os.path.join(os.path.abspath(self.temp.name),
                                      'test_data')
        self.app = main({}, **settings)
        self.storage_location = 'https://storage.onroerenderfgoed.be/'
        collections_include(self.app, self.store_dir)
        self.testapp = TestApp(self.app)

    def tearDown(self):
        self.temp.dissolve()

    def test_list_collections(self):
        res = self.testapp.get('/collections')
        self.assertEqual('200 OK', res.status)
        self.assertIn('application/json', res.headers['Content-Type'])
        self.assertEqual(['TEST_COLLECTION'], res.json_body)

    def test_unexisting_collection(self):
        res = self.testapp.put(
            '/collections/NO_COLLECTION/containers/TEST_CONTAINER_ID',
            expect_errors=True)
        self.assertEqual('404 Not Found', res.status)

    def test_get_home(self):
        res = self.testapp.get('/')
        self.assertEqual('200 OK', res.status)
        self.assertIn('application/json', res.headers['Content-Type'])

    def test_create_container(self):
        res = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID')
        self.assertEqual('200 OK', res.status)
        self.assertIn('application/json', res.headers['Content-Type'])
        self.assertIn('TEST_CONTAINER_ID', res.body)
        self.assertIn(
            self.storage_location +
            'collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID',
            res.body)

    def test_add_object(self):
        # create a container
        cres = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID')
        self.assertEqual('200 OK', cres.status)

        testdata = os.path.join(here, '../', 'fixtures/kasteel.jpg')
        with open(testdata, 'rb') as f:
            bdata = f.read()
        res = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/200x300',
            bdata)
        self.assertEqual('200 OK', res.status)
        self.assertIn(
            self.storage_location +
            'collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/200x300',
            res.body)
        self.assertIn('TEST_CONTAINER_ID', res.body)
        self.assertIn('200x300', res.body)

    def test_add_object_content_length_errors(self):
        # create a container
        cres = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID')
        self.assertEqual('200 OK', cres.status)

        testdata = os.path.join(here, '../', 'fixtures/kasteel.jpg')
        with open(testdata, 'rb') as f:
            bdata = f.read()
        res = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/200x300',
            bdata,
            headers={'Content-Length': ''},
            expect_errors=True,
            status=411)
        self.assertEqual('411 Length Required', res.status)
        res = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/200x300',
            expect_errors=True,
            status=400)
        self.assertEqual('400 Bad Request', res.status)

    def test_get_object(self):
        # create container and add object
        cres = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID')
        self.assertEqual('200 OK', cres.status)
        self.assertIn(
            self.storage_location +
            'collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID',
            cres.body)
        testdata = os.path.join(here, '../', 'fixtures/kasteel.jpg')
        with open(testdata, 'rb') as f:
            bdata = f.read()
        file_size = len(bdata)
        ores = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/200x300',
            bdata)
        self.assertIn(
            self.storage_location +
            'collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/200x300',
            ores.body)
        self.assertEqual('200 OK', ores.status)

        res = self.testapp.get(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/200x300'
        )
        self.assertEqual('200 OK', res.status)
        self.assertEqual(file_size, len(res.body))
        self.assertEqual(bdata, res.body)

    def test_list_object_keys_for_container(self):
        # create container and add objects
        cres = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID')
        self.assertEqual('200 OK', cres.status)
        testdata = os.path.join(here, '../', 'fixtures/kasteel.jpg')
        with open(testdata, 'rb') as f:
            bdata = f.read()
        ores = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/200x300',
            bdata)
        self.assertEqual('200 OK', ores.status)
        testdata = os.path.join(here, '../', 'fixtures/brug.jpg')
        with open(testdata, 'rb') as f:
            bdata = f.read()
        ores = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/400x600',
            bdata)
        self.assertEqual('200 OK', ores.status)

        res = self.testapp.get(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID')
        self.assertEqual('200 OK', res.status)
        l = ast.literal_eval(res.body)
        l = [i.strip() for i in l]
        self.assertTrue('200x300' in l and '400x600' in l)

    def test_update_object(self):
        # create container and add object
        cres = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID')
        self.assertEqual('200 OK', cres.status)
        testdata = os.path.join(here, '../', 'fixtures/kasteel.jpg')
        with open(testdata, 'rb') as f:
            bdata = f.read()
        ores = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/200x300',
            bdata)
        self.assertEqual('200 OK', ores.status)
        self.assertIn(
            self.storage_location +
            'collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/200x300',
            ores.body)

        testdata = os.path.join(here, '../', 'fixtures/brug.jpg')
        with open(testdata, 'rb') as f:
            ubdata = f.read()
        file_size = len(ubdata)
        res = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/200x300',
            ubdata)
        self.assertEqual('200 OK', res.status)
        res = self.testapp.get(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/200x300'
        )
        self.assertEqual('200 OK', res.status)
        self.assertEqual(file_size, len(res.body))
        self.assertEqual(ubdata, res.body)
        self.assertNotEqual(bdata, res.body)

    def test_update_object_validation_failure(self):
        cres = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID')
        self.assertEqual('200 OK', cres.status)
        testdata = os.path.join(here, '../', 'fixtures/kasteel.jpg')
        with open(testdata, 'rb') as f:
            bdata = f.read()
        res = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/1',
            bdata,
            expect_errors=True,
            status=400)
        self.assertDictEqual(
            {
                u'message':
                u'Failed validation: The object key must be 3 characters long'
            }, res.json_body)

    def test_delete_object(self):
        # create container and add object
        cres = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID')
        self.assertEqual('200 OK', cres.status)
        testdata = os.path.join(here, '../', 'fixtures/kasteel.jpg')
        with open(testdata, 'rb') as f:
            bdata = f.read()
        ores = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/200x300',
            bdata)
        self.assertEqual('200 OK', ores.status)

        res = self.testapp.delete(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/200x300'
        )
        self.assertIn(
            self.storage_location +
            'collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/200x300',
            res.json_body['uri'])
        self.assertEqual('200 OK', res.status)
        self.assertIn('TEST_CONTAINER_ID', res.body)
        self.assertIn('200x300', res.body)

        res = self.testapp.get(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/200x300',
            status=404,
            expect_errors=True)
        self.assertEqual('404 Not Found', res.status)

    def test_delete_non_existing_object(self):
        cres = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID')
        self.assertEqual('200 OK', cres.status)
        res = self.testapp.delete(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID/2000x30000',
            expect_errors=True)
        self.assertEqual('404 Not Found', res.status)

    def test_delete_container(self):
        # create container
        cres = self.testapp.put(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID')
        self.assertEqual('200 OK', cres.status)

        res = self.testapp.delete(
            '/collections/TEST_COLLECTION/containers/TEST_CONTAINER_ID')
        self.assertEqual('200 OK', res.status)

    def test_create_container_with_id(self):
        res = self.testapp.post('/collections/TEST_COLLECTION/containers')
        self.assertEqual('201 Created', res.status)
        uuid4hex = re.compile(
            '[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\Z',
            re.I)
        container_key = res.json_body['container_key']
        if isinstance(container_key, unicode):
            container_key = str(container_key)
        self.assertTrue(uuid4hex.match(container_key))
        print(res.json_body['uri'])
Example #36
0
class FunctionalTests(unittest.TestCase):
    def getAssertion():
        ''' Grabs a valid identity assertion from personatestuser.org for testing '''
        url = 'http://personatestuser.org/email_with_assertion/{}'.format(
            urllib.parse.quote(AUDIENCE, safe=''))
        response = requests.get(url)
        persona = response.json()

        return (persona['email'], persona['pass'], persona['assertion'])

    def authenticate():
        ''' Authenticates using Persona. Not used currently. '''
        res = self.testapp.get('/add', status=403)
        # this plucks the csrf token from the Javascript form in the 403 response body
        match = re.search(
            '<input type=\'hidden\'[\s"\+]+name=\'csrf_token\'[\s"\+]+value=\'(?P<csrf>[a-z0-9]+)\'\s+/>',
            res.text)
        csrf_token = match.group('csrf')
        res = self.testapp.post('/login', {
            'assertion': FunctionalTests.assertion,
            'came_from': 'http://*****:*****@example.com',
            'RemoteUserAuthenticationPolicy': ''
        }
        from writers_choice import main
        app = main({}, **settings)
        from webtest import TestApp
        self.testapp = TestApp(
            app, extra_environ={'REMOTE_USER': settings['admin_email']})
        self.session = _initTestingDB()

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

    def test_visit_article_1(self):
        res = self.testapp.get('/2012/01/01/testsida', status=200)
        res.mustcontain(
            '<title>Testsida — Site name</title>',
            '<a href="http://localhost/" id="banner">Site name</a>',
            '<h1>Testsida</h1>', '<p>2012-01-01</p>',
            '<p>Ett <em>stycke</em> till.</p>',
            '<a href="http://localhost/edit/1',
            '<li class="nav_tab"><a href="http://localhost/">Home</a></li>',
            '<li class="nav_tab"><a href="http://localhost/about-us">About us</a></li>'
        )

    def test_visit_evil_article(self):
        res = self.testapp.get('/2011/1/2/ihtml-titlei', status=200)
        res.mustcontain('>&lt;i&gt;HTML-title&lt;/i&gt;</h1>')

    def test_visit_nonexisting_article(self):
        resp = self.testapp.get('/2000/1/1/nothing', status=404)
        resp.mustcontain('No such article.')

    def test_visit_home(self):
        res = self.testapp.get('/', status=200)
        res.mustcontain(
            '<title>Site name</title>',
            '<a href="http://localhost/" id="banner">Site name</a>',
            '<h1><a href="http://localhost/2012/1/1/testsida">Testsida</a></h1>',
            '<a href="http://localhost/2012/1/3/testsida-tva">Testsida två</a>',
            '<h2>Rubrik 1</h2>', '<a href="http://localhost/add',
            '>&lt;i&gt;HTML-title&lt;/i&gt;</a>',
            '<li class="nav_tab"><a href="http://localhost/">Home</a></li>',
            '<li class="nav_tab"><a href="http://localhost/about-us">About us</a></li>'
        )

    def test_visit_home_unauthorized(self):
        res = self.testapp.get(
            '/',
            status=200,
            extra_environ={'REMOTE_USER': '******'})
        self.assertNotIn('<a href="http://localhost/add', res)

    def test_visit_article_1_unauthorized(self):
        res = self.testapp.get(
            '/2012/1/1/testsida',
            status=200,
            extra_environ={'REMOTE_USER': '******'})
        self.assertNotIn('<a href="http://localhost/edit/1', res)

    def test_add_article(self):
        res = self.testapp.get('/add', status=200)
        res.mustcontain(
            '<title>New article — Site name</title>',
            '<a href="http://localhost/" id="banner">Site name</a>',
            '<h1 class="title"><input type="text" name="title" value=""',
            '<form action="http://localhost/add" method="post"',
            '<textarea name="body"', '<input type="checkbox" name="publish"',
            '<input type="submit"')
        res = self.testapp.post('/add', {
            'title': 'Ny sida',
            'body': 'Brödtext.',
            'save-article': ''
        },
                                status=302)
        res = res.follow()
        res.mustcontain(
            '<h1 class="title"><input type="text" name="title" value="Ny sida"',
            '<textarea name="body"', 'Brödtext')

    def test_edit_article(self):
        res = self.testapp.get('/edit/1', status=200)
        res.mustcontain(
            '<title>Editing Testsida — Site name</title>',
            '<a href="http://localhost/" id="banner">Site name</a>',
            '<form action="http://localhost/edit/1" method="post"',
            '<h1 class="title">',
            '<input type="text" name="title" value="Testsida"',
            '>Ett stycke.\n\n'
            'Ett *stycke* till.</textarea>',
            '<input type="checkbox" name="publish"', '<input type="submit"')

        res = self.testapp.post('/edit/1', {
            'title': 'Testande sida',
            'body': 'text.\n',
            'save-article': ''
        },
                                status=302)
        res = res.follow()
        res.mustcontain(
            '<h1 class="title"><input type="text" name="title" value="Testande sida"',
            '<textarea name="body"', 'text.</textarea>')

    def test_add_article_empty_title(self):
        res = self.testapp.post('/add', {
            'title': '',
            'body': 'Brödtext.',
            'save-article': ''
        },
                                status=200)
        res.mustcontain('>Brödtext.</textarea>', '<p class="message">')

    def test_edit_article_empty_title(self):
        res = self.testapp.post('/edit/1', {
            'title': '',
            'body': 'text.\n',
            'save-article': ''
        },
                                status=200)
        res.mustcontain('>text.\n</textarea>', '<p class="message">')

    def test_visit_about_page(self):
        response = self.testapp.get('/about-us', status=200)
        response.mustcontain(
            '<title>About us — Site name</title>',
            '<a href="http://localhost/" id="banner">Site name</a>',
            '<h1>About us</h1>',
            '<p>This page contains some information about the author.</p>\n'
            '<p>Contact: <a href="mailto:[email protected]">Admin</a></p>',
            '<li class="nav_tab"><a href="http://localhost/">Home</a></li>',
            '<li class="nav_tab"><a href="http://localhost/about-us">About us</a></li>'
        )

    def test_visit_nonexisting_page(self):
        response = self.testapp.get('/nonexisting', status=404)
        response.mustcontain('Page not found')
Example #37
0
    def test_validation_hooked_error_response(self):
        app = TestApp(main({}))

        response = app.post('/service4', status=400)
        self.assertTrue(b'<errors>' in response.body)
Example #38
0
    def test_filters(self):
        app = TestApp(main({}))

        # filters can be applied to all the methods of a service
        self.assertTrue(b"filtered response" in app.get('/filtered').body)
        self.assertTrue(b"unfiltered" in app.post('/filtered').body)
class TestLogin(BaseTestCase):
    def test_render_login_form(self):
        """A GET request to the login view should render the login form."""

        res = self.app.get('/auth/login')
        self.failUnless('<input id="username" name="username"' in res.body)

    def test_render_login_next(self):
        """A GET request to the login view will pass through the `next` param.
        """

        res = self.app.get('/auth/login?next=/foo/bar')
        tag = '<input id="next" name="next" type="hidden" value="/foo/bar" />'
        self.failUnless(tag in res.body)

    def test_login(self):
        """Login remembers the user."""

        # Create a user.
        self.makeUser('thruflo', 'Password')
        # Login with the wrong details sets an empty session cookie.
        post_data = {'username': '******', 'password': '******'}
        res = self.app.post('/auth/login', post_data, status="*")
        self.assertTrue(len(res.headers['Set-Cookie']) < 200)
        # Login with the right details remembers the user in the session
        # cookie.
        post_data = {'username': '******', 'password': '******'}
        res = self.app.post('/auth/login', post_data, status="*")
        self.assertTrue(len(res.headers['Set-Cookie']) > 250)

    def test_login_redirect(self):
        """login redirects to ``next``."""

        # Create a user.
        self.makeUser('thruflo', 'Password')
        # Login with the right details redirects to `next`.
        post_data = {
            'username': '******',
            'password': '******',
            'next': '/foo/bar'
        }
        res = self.app.post('/auth/login', post_data, status=302)
        self.assertTrue(res.headers['Location'] == 'http://localhost/foo/bar')
        # If `next` is not provided, redirects to `/`
        post_data = {'username': '******', 'password': '******'}
        res = self.app.post('/auth/login', post_data, status=302)
        self.assertTrue(res.headers['Location'] == 'http://localhost/')
        # Or the 'index' route if exposed.
        self.config = config_factory()
        self.config.add_route('index', 'some/path')
        self.app = TestApp(self.config.make_wsgi_app())
        res = self.app.post('/auth/login', post_data, status=302)
        self.assertEquals(res.location, 'http://localhost/some/path')
        # Or the `simpleauth.after_logout_route` route if specified and
        # exposed.
        settings = {'simpleauth.after_login_route': 'flobble'}
        self.config = config_factory(**settings)
        self.config.add_route('flobble', 'wob')
        self.app = TestApp(self.config.make_wsgi_app())
        res = self.app.post('/auth/login', post_data, status=302)
        self.assertTrue(res.headers['Location'] == 'http://localhost/wob')

    def test_login_event(self):
        """Login fires a ``UserLoggedIn`` event."""

        from pyramid_simpleauth.events import UserLoggedIn
        from pyramid_simpleauth.model import User
        # Setup event listener.
        mock_subscriber = Mock()
        self.config = config_factory()
        self.config.add_subscriber(mock_subscriber, UserLoggedIn)
        self.app = TestApp(self.config.make_wsgi_app())
        # Login.
        self.makeUser('thruflo', 'Password')
        post_data = {'username': '******', 'password': '******'}
        res = self.app.post('/auth/login', post_data, status=302)
        assert res  # to satisfy pyflakes
        # Handler was called with the authentiated user as the second arg.
        self.assertTrue(mock_subscriber.called)
        event = mock_subscriber.call_args_list[0][0][0]
        self.assertTrue(isinstance(event.user, User))
Example #40
0
class BookTest(unittest.TestCase):
    def setUp(self):

        self.app = TestApp(application())
        apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap()
        apiproxy_stub_map.apiproxy.RegisterStub('mail',
                                                mail_stub.MailServiceStub())
        apiproxy_stub_map.apiproxy.RegisterStub(
            'user', user_service_stub.UserServiceStub())
        apiproxy_stub_map.apiproxy.RegisterStub(
            'urlfetch', urlfetch_stub.URLFetchServiceStub())
        apiproxy_stub_map.apiproxy.RegisterStub(
            'memcache', memcache_stub.MemcacheServiceStub())
        stub = datastore_file_stub.DatastoreFileStub('temp', '/dev/null',
                                                     '/dev/null')
        apiproxy_stub_map.apiproxy.RegisterStub('datastore_v3', stub)

        os.environ['APPLICATION_ID'] = "temp"

    def test_book_creation(self):
        self.assertEquals(0, Book.all().count())
        book = Book(title="test",
                    ident="1",
                    author="author",
                    notes="",
                    image="http://example.com/image.gif",
                    url="http://example.com")
        book.put()
        self.assertEquals(1, Book.all().count())
        book = Book(title="test2",
                    ident="2",
                    author="author",
                    notes="",
                    image="http://example.com/image.gif",
                    url="http://example.com")
        book.put()
        self.assertEquals(2, Book.all().count())

    def test_book_deletion(self):
        self.assertEquals(0, Book.all().count())
        book = Book(title="test",
                    ident="1",
                    author="author",
                    notes="",
                    image="http://example.com/image.gif",
                    url="http://example.com")
        book.put()
        self.assertEquals(1, Book.all().count())
        book.delete()
        self.assertEquals(0, Book.all().count())

    def book_with_no_content_returns_404(self):
        self.assertEquals(0, Book.all().count())
        response = self.app.get('/books/1', expect_errors=True)
        self.assertEquals("404 Not Found", response.status)

    def test_book_with_content_returns_200(self):
        self.assertEquals(0, Book.all().count())
        book = Book(title="test",
                    ident="1",
                    author="author",
                    notes="",
                    image="http://example.com/image.gif",
                    url="http://example.com")
        book.put()
        path = "/books/%s" % book.ident
        response = self.app.get(path, expect_errors=True)
        self.assertEquals("200 OK", response.status)

    def test_response_from_book_is_json(self):
        self.assertEquals(0, Book.all().count())
        book = Book(title="test",
                    ident="1",
                    author="author",
                    notes="",
                    image="http://example.com/image.gif",
                    url="http://example.com")
        book.put()
        self.assertEquals(1, Book.all().count())
        response = self.app.get('/books/%s' % book.ident, expect_errors=True)
        try:
            response.json
        except AttributeError:
            assert (False)

    def test_response_contents_from_book(self):
        self.assertEquals(0, Book.all().count())
        book = Book(title="test",
                    ident="1",
                    author="author",
                    notes="",
                    image="http://example.com/image.gif",
                    url="http://example.com")
        book.put()
        self.assertEquals(1, Book.all().count())
        response = self.app.get('/books/%s' % book.ident, expect_errors=True)
        response.mustcontain('"ident": "1"')
        response.mustcontain('"title": "test"')

    def test_response_contents_json_from_book(self):
        self.assertEquals(0, Book.all().count())
        book = Book(title="test",
                    ident="1",
                    author="author",
                    notes="",
                    image="http://example.com/image.gif",
                    url="http://example.com")
        book.put()
        self.assertEquals(1, Book.all().count())
        response = self.app.get('/books/%s' % book.ident, expect_errors=True)
        try:
            json = response.json
        except AttributeError:
            assert (False)
        self.assertEqual(json['ident'], "1")
        self.assertEqual(json['title'], "test")

    def test_book_views_return_correct_mime_type(self):
        self.assertEquals(0, Book.all().count())
        book = Book(title="test",
                    ident="1",
                    author="author",
                    notes="",
                    image="http://example.com/image.gif",
                    url="http://example.com")
        book.put()
        self.assertEquals(1, Book.all().count())
        response = self.app.get('/books/%s' % book.ident, expect_errors=True)
        self.assertEquals(response.content_type, "application/json")

    def test_book_deletion_via_service(self):
        self.assertEquals(0, Book.all().count())
        book = Book(title="test",
                    ident="1",
                    author="author",
                    notes="",
                    image="http://example.com/image.gif",
                    url="http://example.com")
        book.put()
        self.assertEquals(1, Book.all().count())
        response = self.app.delete('/books/%s' % book.ident,
                                   expect_errors=True)
        self.assertEquals(0, Book.all().count())

    def test_book_addition_via_service_put(self):
        json = """{
            "ident": "1", 
            "title": "test",
            "author": "author",
            "notes": "",
            "image": "http://example.com/image.gif",
            "url": "http://example.com"
        }"""
        self.assertEquals(0, Book.all().count())
        response = self.app.put('/books/1', params=json, expect_errors=True)
        self.assertEquals(1, Book.all().count())
        response = self.app.get('/books/1', expect_errors=True)
        self.assertEquals("200 OK", response.status)

    def test_book_update_via_service_put(self):
        self.assertEquals(0, Book.all().count())
        book = Book(title="test",
                    ident="1",
                    author="author",
                    notes="",
                    image="http://example.com/image.gif",
                    url="http://example.com")
        book.put()
        self.assertEquals(1, Book.all().count())
        json = """{
            "ident": "1", 
            "title": "test update",
            "author": "author",
            "notes": "",
            "image": "http://example.com/image.gif",
            "url": "http://example.com"
        }"""
        response = self.app.put('/books/1', params=json, expect_errors=True)
        self.assertEquals(1, Book.all().count())
        response = self.app.get('/books/1', expect_errors=True)
        self.assertEquals("200 OK", response.status)
        try:
            json = response.json
        except AttributeError:
            assert (False)
        self.assertEqual(json['ident'], "1")
        self.assertEqual(json['title'], "test update")

    def test_book_addition_via_service_post(self):
        json = """{
            "ident": "1", 
            "title": "test",
            "author": "author",
            "notes": "",
            "image": "http://example.com/image.gif",
            "url": "http://example.com"
        }"""
        self.assertEquals(0, Book.all().count())
        response = self.app.post('/books', params=json, expect_errors=True)
        self.assertEquals(1, Book.all().count())
        response = self.app.get('/books/1', expect_errors=True)
        self.assertEquals("200 OK", response.status)
Example #41
0
class TestWithWebtest(unittest.TestCase):
    def setUp(self):
        self.testapp = TestApp(
            main({}, **{
                'sqlalchemy.url': os.environ.get('DB', 'sqlite://'),
                'secret.authn_policy': 'so_secret',
                'secret.unencrypted_cookie': 'itsaseekreet',
                'mako.directories': 'pyconca:templates',
            }))
        Base.metadata.drop_all(DBSession.bind)
        Base.metadata.create_all(DBSession.bind)
        with transaction.manager:
            self._admin_id = 1
            self._speaker_id = 2
            self._admin_talk_id = 11
            self._speaker_talk_id = 12
            self._schedule_slot_id = 21
            admin = User(id=self._admin_id,
                         username='******',
                         password='******',
                         first_name='Admin',
                         last_name='Istrator',
                         email='*****@*****.**')
            speaker = User(id=self._speaker_id,
                           username='******',
                           password='******',
                           first_name='Spe',
                           last_name='Aker',
                           email='*****@*****.**')
            admin_group = Group(name='admin')
            admin.groups.append(admin_group)
            admin_talk = Talk(id=self._admin_talk_id,
                              owner_id=self._admin_id,
                              title="atitle",
                              type="talk",
                              level="novice",
                              abstract="aabstract",
                              outline="aoutline",
                              reviewer_notes="areviewer_notes")
            speaker_talk = Talk(id=self._speaker_talk_id,
                                owner_id=self._speaker_id,
                                title="stitle",
                                type="tutorial",
                                level="experienced",
                                abstract="sabstract",
                                outline="soutline",
                                reviewer_notes="sreviewer_notes")
            start = datetime(2012, 11, 10, 15, 00)
            end = datetime(2012, 11, 10, 15, 30)
            schedule_slot = ScheduleSlot(id=self._schedule_slot_id,
                                         room="room",
                                         start=start,
                                         end=end,
                                         code="X%s" %
                                         (self._schedule_slot_id, ))
            DBSession.add_all([
                admin, speaker, admin_group, admin_talk, speaker_talk,
                schedule_slot
            ])

    def tearDown(self):
        DBSession.remove()

    def _loginAs(self, who):
        response = self.testapp.post('/login', {
            'login.submit': 'Login',
            'username': who,
            'password': who,
        })
        self.assertEquals('302 Found', response.status)

    def _getJsonFrom(self, uri, who=None, **kwargs):
        if who is not None:
            headers = self._loginAs(who)
        response = self.testapp.get(uri, **kwargs)
        return json.loads(response.body)

    def test_root(self):
        response = self.testapp.get('/', status=200)
        self.assertEquals('200 OK', response.status)
        title = "PyCon.ca - building your Python Canada Community | PyCon Canada"
        self.failUnless(title in response.body, response.body)

    def test_login(self):
        self._loginAs('admin')
        index_response = self.testapp.get('/', status=200)
        self.failUnless('Logout' in index_response.body, index_response.body)
        self.failIf('Login' in index_response.body, index_response.body)

    ### USER API

    def test_user_api_index__not_logged_in(self):
        data = self._getJsonFrom('/user.json', status=403)
        self.assertEquals({}, data['data'])

    def test_user_api_index__as_admin(self):
        data = self._getJsonFrom('/user.json', who='admin', status=200)
        self.assertEquals(2, len(data['data']['user_list']))

    def test_user_api_index__as_speaker(self):
        data = self._getJsonFrom('/user.json', who='speaker', status=403)
        self.assertEquals({}, data['data'])

    def test_user_api_get__not_logged_in(self):
        data = self._getJsonFrom('/user/2.json', status=403)
        self.assertEquals({}, data['data'])

    def test_user_api_get_admin__as_admin(self):
        data = self._getJsonFrom('/user/1.json', who='admin', status=200)
        self.assertEquals(self._admin_id, data['data']['user']['id'])

    def test_user_api_get_speaker__as_admin(self):
        data = self._getJsonFrom('/user/2.json', who='admin', status=200)
        self.assertEquals(self._speaker_id, data['data']['user']['id'])

    def test_user_api_get_admin__as_speaker(self):
        data = self._getJsonFrom('/user/1.json', who='speaker', status=403)
        self.assertEquals({}, data['data'])

    def test_user_api_get_speaker__as_speaker(self):
        data = self._getJsonFrom('/user/2.json', who='speaker', status=200)
        self.assertEquals(self._speaker_id, data['data']['user']['id'])

    ### TALK API

    def _assertTalkNotScheduled(self, data):
        self.assertTrue(data['data']['talk']['room'] is None)
        self.assertTrue(data['data']['talk']['start'] is None)
        self.assertTrue(data['data']['talk']['end'] is None)
        self.assertTrue(data['data']['talk']['duration'] is None)

    def test_talk_api_index__not_logged_in(self):
        data = self._getJsonFrom('/talk.json', status=403)
        self.assertEquals({}, data['data'])

    def test_talk_api_index__as_admin(self):
        data = self._getJsonFrom('/talk.json', who='admin', status=200)
        self.assertEquals(2, len(data['data']['talk_list']))

    def test_talk_api_index__as_speaker(self):
        data = self._getJsonFrom('/talk.json', who='speaker', status=200)
        self.assertEquals(1, len(data['data']['talk_list']), data)
        self.assertEquals(self._speaker_talk_id,
                          data['data']['talk_list'][0]['id'])
        self.assertEquals(self._speaker_id,
                          data['data']['talk_list'][0]['owner_id'])
        self.assertEquals('stitle', data['data']['talk_list'][0]['title'])

    def test_talk_api_get__not_logged_in(self):
        data = self._getJsonFrom('/talk/11.json', status=403)
        self.assertEquals({}, data['data'])

    def test_talk_api_get_admin__as_admin(self):
        data = self._getJsonFrom('/talk/11.json', who='admin', status=200)
        self.assertEquals(self._admin_talk_id, data['data']['talk']['id'])
        self._assertTalkNotScheduled(data)

    def test_talk_api_get_speaker__as_admin(self):
        data = self._getJsonFrom('/talk/12.json', who='admin', status=200)
        self.assertEquals(self._speaker_talk_id, data['data']['talk']['id'])
        self._assertTalkNotScheduled(data)

    def test_talk_api_get_admin__as_speaker(self):
        data = self._getJsonFrom('/talk/11.json', who='speaker', status=403)
        self.assertEquals({}, data['data'])

    def test_talk_api_get_speaker__as_speaker(self):
        data = self._getJsonFrom('/talk/12.json', who='speaker', status=200)
        self.assertEquals(self._speaker_talk_id, data['data']['talk']['id'])
        self._assertTalkNotScheduled(data)

    def test_talk_api_talk_is_scheduled(self):
        start = datetime(2012, 11, 10, 15, 00)
        end = datetime(2012, 11, 10, 15, 30)
        with transaction.manager:
            talk = DBSession.query(Talk).get(self._admin_talk_id)
            schedule_slot = DBSession.query(ScheduleSlot).get(
                self._schedule_slot_id)
            schedule_slot.talk = talk
        data = self._getJsonFrom('/talk/11.json', who='admin', status=200)
        self.assertEquals("room", data['data']['talk']['room'])
        self.assertEquals("2012-11-10T10:00:00-05:00",
                          data['data']['talk']['start'])
        self.assertEquals("2012-11-10T10:30:00-05:00",
                          data['data']['talk']['end'])
        self.assertEquals(30, data['data']['talk']['duration'])

    def test_schedule_slot_api_get__not_logged_in(self):
        data = self._getJsonFrom('/schedule_slot/21.json', status=403)
        self.assertEquals({}, data['data'])

    def test_schedule_slot_api_index__as_admin(self):
        data = self._getJsonFrom('/schedule_slot.json',
                                 who='admin',
                                 status=200)
        self.assertEquals(1, len(data['data']['schedule_slot_list']))
        self.assertEquals(
            {
                'duration': 30,
                'start': '2012-11-10T10:00:00-05:00',
                'end': '2012-11-10T10:30:00-05:00',
                'id': self._schedule_slot_id,
                'room': 'room',
                'talk_id': None,
            }, data['data']['schedule_slot_list'][0])
class TestLogout(BaseTestCase):
    def test_logout(self):
        """Logout forgets the user."""

        # Create a user.
        self.makeUser('thruflo', 'Password')
        # Login.
        post_data = {'username': '******', 'password': '******'}
        res = self.app.post('/auth/login', post_data, status=302)
        self.assertTrue(len(res.headers['Set-Cookie']) > 250)
        # Logout.
        res = self.app.post('/auth/logout', status=302)
        self.assertTrue(len(res.headers['Set-Cookie']) < 200)

    def test_logout_redirects(self):
        """Logout redirects."""

        # The response redirects to `/` by default with no routes or settings.
        res = self.app.post('/auth/logout', status=302)
        self.assertTrue(res.headers['Location'] == 'http://localhost/')
        # The response redirects to the `index` route if exposed.
        self.config = config_factory()
        self.config.add_route('index', 'some/path')
        self.app = TestApp(self.config.make_wsgi_app())
        res = self.app.post('/auth/logout', status=302)
        self.assertTrue(
            res.headers['Location'] == 'http://localhost/some/path')
        # The response redirects to the `simpleauth.after_logout_route` route
        # if specified.
        settings = {'simpleauth.after_logout_route': 'flobble'}
        self.config = config_factory(**settings)
        self.config.add_route('flobble', 'wob')
        self.app = TestApp(self.config.make_wsgi_app())
        res = self.app.post('/auth/logout', status=302)
        self.assertTrue(res.headers['Location'] == 'http://localhost/wob')

    def test_loggedout_event(self):
        """Logout fires a ``UserLoggedOut`` event."""

        from pyramid_simpleauth.events import UserLoggedOut
        from pyramid_simpleauth.model import User
        # Setup event listener.
        mock_subscriber = Mock()
        self.config = config_factory()
        self.config.add_subscriber(mock_subscriber, UserLoggedOut)
        self.app = TestApp(self.config.make_wsgi_app())
        # Login.
        self.makeUser('thruflo', 'Password')
        post_data = {'username': '******', 'password': '******'}
        res = self.app.post('/auth/login', post_data, status=302)
        # Logout.
        res = self.app.post('/auth/logout', status=302)
        assert res  # to satisfy pyflakes
        # Handler was called with the authentiated user as the second arg.
        self.assertTrue(mock_subscriber.called)
        event = mock_subscriber.call_args_list[0][0][0]
        self.assertTrue(isinstance(event.user, User))

    def test_loggedout_event_requires_user(self):
        """Logout only fires a ``UserLoggedOut`` event when there was an
          authenticated user.
        """

        from pyramid_simpleauth.events import UserLoggedOut
        # Setup event listener.
        mock_subscriber = Mock()
        self.config = config_factory()
        self.config.add_subscriber(mock_subscriber, UserLoggedOut)
        self.app = TestApp(self.config.make_wsgi_app())
        # Logout.
        res = self.app.post('/auth/logout', status=302)
        assert res  # to satisfy pyflakes
        # Handler was not called.
        self.assertFalse(mock_subscriber.called)
Example #43
0
    class TestServiceDescription(TestCase):
        def setUp(self):
            self.config = testing.setUp()
            self.config.include("cornice")
            self.config.scan("cornice.tests.test_service_description")
            self.app = TestApp(CatchErrors(self.config.make_wsgi_app()))

        def tearDown(self):
            testing.tearDown()

        def test_get_from_colander(self):
            schema = CorniceSchema.from_colander(FooBarSchema)
            attrs = schema.as_dict()
            self.assertEqual(len(attrs), 6)

        def test_description_attached(self):
            # foobar should contain a schema argument containing the cornice
            # schema object, so it can be introspected if needed
            # accessing Service.schemas emits a warning
            with warnings.catch_warnings(record=True) as w:
                warnings.simplefilter("always")
                self.assertTrue('POST' in foobar.schemas)
                self.assertEqual(len(w), 1)

        def test_schema_validation(self):
            # using a colander schema for the service should automatically
            # validate the request calls. Let's make some of them here.
            resp = self.app.post('/foobar', status=400)
            self.assertEqual(resp.json['status'], 'error')

            errors = resp.json['errors']
            # we should at have 1 missing value in the QS...
            self.assertEqual(
                1, len([e for e in errors if e['location'] == "querystring"]))

            # ... and 2 in the body (a json error as well)
            self.assertEqual(
                2, len([e for e in errors if e['location'] == "body"]))

            # let's do the same request, but with information in the
            # querystring
            resp = self.app.post('/foobar?yeah=test', status=400)

            # we should have no missing value in the QS
            self.assertEqual(
                0,
                len([
                    e for e in resp.json['errors']
                    if e['location'] == "querystring"
                ]))

            # and if we add the required values in the body of the post,
            # then we should be good
            data = {'foo': 'yeah', 'bar': 'open'}
            resp = self.app.post('/foobar?yeah=test',
                                 params=json.dumps(data),
                                 status=200)

            self.assertEqual(resp.json, {u'baz': None, "test": "succeeded"})

        def test_schema_validation2(self):
            resp = self.app.get('/foobar?yeah=test', status=200)
            self.assertEqual(resp.json, {"test": "succeeded"})

        def test_bar_validator(self):
            # test validator on bar attribute
            data = {'foo': 'yeah', 'bar': 'closed'}
            resp = self.app.post('/foobar?yeah=test',
                                 params=json.dumps(data),
                                 status=400)

            self.assertEqual(
                resp.json, {
                    u'errors': [{
                        u'description': u'The bar is not open.',
                        u'location': u'body',
                        u'name': u'bar'
                    }],
                    u'status':
                    u'error'
                })

        def test_foo_required(self):
            # test required attribute
            data = {'bar': 'open'}
            resp = self.app.post('/foobar?yeah=test',
                                 params=json.dumps(data),
                                 status=400)

            self.assertEqual(
                resp.json, {
                    u'errors': [{
                        u'description': u'foo is missing',
                        u'location': u'body',
                        u'name': u'foo'
                    }],
                    u'status':
                    u'error'
                })

        def test_default_baz_value(self):
            # test required attribute
            data = {'foo': 'yeah', 'bar': 'open'}
            resp = self.app.post('/foobar?yeah=test',
                                 params=json.dumps(data),
                                 status=200)

            self.assertEqual(resp.json, {u'baz': None, "test": "succeeded"})

        def test_ipsum_error_message(self):
            # test required attribute
            data = {'foo': 'yeah', 'bar': 'open', 'ipsum': 5}
            resp = self.app.post('/foobar?yeah=test',
                                 params=json.dumps(data),
                                 status=400)

            self.assertEqual(
                resp.json, {
                    u'errors': [{
                        u'description': u'5 is greater than maximum value 3',
                        u'location': u'body',
                        u'name': u'ipsum'
                    }],
                    u'status':
                    u'error'
                })

        def test_integers_fail(self):
            # test required attribute
            data = {
                'foo': 'yeah',
                'bar': 'open',
                'ipsum': 2,
                'integers': ('a', '2')
            }
            resp = self.app.post('/foobar?yeah=test',
                                 params=json.dumps(data),
                                 status=400)

            self.assertEqual(
                resp.json, {
                    u'errors': [{
                        u'description': u'"a" is not a number',
                        u'location': u'body',
                        u'name': u'integers.0'
                    }],
                    u'status':
                    u'error'
                })

        def test_integers_ok(self):
            # test required attribute
            data = {
                'foo': 'yeah',
                'bar': 'open',
                'ipsum': 2,
                'integers': ('1', '2')
            }
            self.app.post('/foobar?yeah=test',
                          params=json.dumps(data),
                          status=200)

        def test_nested_schemas(self):

            data = {
                "title": "Mushroom",
                "fields": [{
                    "name": "genre",
                    "description": "Genre"
                }]
            }

            nested_data = {
                "title": "Mushroom",
                "fields": [{
                    "schmil": "Blick"
                }]
            }

            self.app.post('/nested', params=json.dumps(data), status=200)
            self.app.post('/nested',
                          params=json.dumps(nested_data),
                          status=400)
Example #44
0
 def test_instantiated_schema(self):
     app = TestApp(main({}))
     with self.assertRaises(ValueError):
         app.post('/m_item/42', status=200)
Example #45
0
class ApiRoutesTestCase(unittest.TestCase):

    def setUp(self):
        self.app = TestApp(api.app)
        self.app.authorization = ('Basic', ('admin', 'password'))

    def test_should_return_a_list_of_plans(self):
        response = self.app.get("/resources/plans")
        self.assertEqual(200, response.status_code)

    def test_should_post_to_add_and_get_a_201(self):
        response = self.app.post("/resources")
        self.assertEqual(201, response.status_code)

    def test_should_post_to_bind_passing_a_name_and_receive_201(self):
        response = self.app.post("/resources/myappservice/bind")
        self.assertEqual(201, response.status_code)

    def test_should_delete_to_unbind_and_receive_200(self):
        response = self.app.delete("/resources/myappservice")
        self.assertEqual(200, response.status_code)

    @responses.activate
    def test_status_OK(self):
        HOST = "1.2.3.4"
        os.environ["ELASTICSEARCH_HOST"] = HOST
        reload(api)

        elasticsearch_healthy = '''
{
  "status" : 200,
  "name" : "Briquette",
  "cluster_name" : "elasticsearch",
  "version" : {
    "number" : "1.6.0",
    "build_hash" : "cdd3ac4dde4f69524ec0a14de3828cb95bbb86d0",
    "build_timestamp" : "2015-06-09T13:36:34Z",
    "build_snapshot" : false,
    "lucene_version" : "4.10.4"
  },
  "tagline" : "You Know, for Search"
}
        '''

        responses.add(responses.GET, 'http://1.2.3.4:9200/',
                  body=elasticsearch_healthy, status=200,
                  content_type='application/json')

        response = self.app.get("/resources/myappservice/status")
        self.assertEqual(len(responses.calls), 1)
        self.assertEqual(204, response.status_code)

    @responses.activate
    def test_status_error(self):
        HOST = "1.2.3.4"
        os.environ["ELASTICSEARCH_HOST"] = HOST
        reload(api)

        responses.add(responses.GET, 'http://1.2.3.4:9200/',
                  body='broken', status=404,
                  content_type='application/json')

        response = self.app.get("/resources/myappservice/status", status = 500)
        self.assertEqual(len(responses.calls), 1)
        self.assertEqual(500, response.status_code)
Example #46
0
 def test_api_server(self):
     server = api.IdentityApiServer()
     app = TestApp(server.app)
     resp = app.post('/v2.0/tokens', json.dumps(REQ))
     self.assertEqual(resp.status, '200 OK')
     self.assertEqual(json.loads(resp.body), TOKENS_RESPONSE)
Example #47
0
class AdminApiTest(unittest.TestCase):
    """Test the bookie admin api calls."""
    _api_key = None

    @property
    def api_key(self):
        """Cache the api key for all calls."""
        if not self._api_key:
            res = DBSession.execute(
                "SELECT api_key FROM users WHERE username = '******'").fetchone(
                )
            self._api_key = res['api_key']
        return self._api_key

    def setUp(self):
        from pyramid.paster import get_app
        app = get_app(BOOKIE_TEST_INI, 'main')
        from webtest import TestApp
        self.testapp = TestApp(app)
        testing.setUp()

    def tearDown(self):
        """We need to empty the bmarks table on each run"""
        testing.tearDown()
        empty_db()

    def test_list_inactive_users(self):
        """Test that we can fetch the inactive users."""
        # for now just make sure we can get a 200 call on it.
        params = {'api_key': self.api_key}
        res = self.testapp.get('/api/v1/a/accounts/inactive',
                               params=params,
                               status=200)
        # by default we shouldn't have any inactive users
        data = json.loads(res.body)
        users = [u for u in data['users']]
        for u in users:
            eq_(0, u['invite_ct'], "Count should be 0 to start.")

    def test_invite_ct(self):
        """Test we can call and get the invite counts."""
        # for now just make sure we can get a 200 call on it.
        params = {'api_key': self.api_key}
        res = self.testapp.get('/api/v1/a/accounts/invites',
                               params=params,
                               status=200)
        # we should get back tuples of username/count
        data = json.loads(res.body)['users']
        found = False
        invite_count = None
        for user, count in data:
            if user == u'admin':
                found = True
                invite_count = count

        ok_(found, "There should be the admin user." + res.body)
        eq_(0, invite_count,
            "The admin user shouldn't have any invites." + res.body)

    def test_set_invite_ct(self):
        """Test we can set the invite count for the user"""
        # for now just make sure we can get a 200 call on it.
        params = {'api_key': self.api_key}
        res = self.testapp.post('/api/v1/a/accounts/invites/admin/10',
                                params=params,
                                status=200)
        # we should get back tuples of username/count
        data = json.loads(res.body)
        eq_('admin', data.get('username'),
            "The admin user data is returned to us." + res.body)
        eq_(10, int(data.get('invite_ct')),
            "The admin user now has 10 invites." + res.body)

        # and of course when we're done we need to unset it back to 0 or else
        # the test above blows up...sigh.
        res = self.testapp.post('/api/v1/a/accounts/invites/admin/0',
                                params=params,
                                status=200)
Example #48
0
class BookieAPITest(unittest.TestCase):
    """Test the Bookie API"""
    def setUp(self):
        from pyramid.paster import get_app
        app = get_app(BOOKIE_TEST_INI, 'bookie')
        from webtest import TestApp
        self.testapp = TestApp(app)
        testing.setUp()

        global API_KEY
        res = DBSession.execute(
            "SELECT api_key FROM users WHERE username = '******'").fetchone()
        API_KEY = res['api_key']

    def tearDown(self):
        """We need to empty the bmarks table on each run"""
        testing.tearDown()
        empty_db()

    def _get_good_request(self, content=False, second_bmark=False):
        """Return the basics for a good add bookmark request"""
        session = DBSession()

        # the main bookmark, added second to prove popular will sort correctly
        prms = {
            'url': u'http://google.com',
            'description': u'This is my google desc',
            'extended': u'And some extended notes about it in full form',
            'tags': u'python search',
            'api_key': API_KEY,
            'username': '******',
            'inserted_by': 'chrome_ext',
        }

        # if we want to test the readable fulltext side we want to make sure we
        # pass content into the new bookmark
        if content:
            prms['content'] = "<p>There's some content in here dude</p>"

        # req_params = urllib.urlencode(prms)
        res = self.testapp.post(
            '/api/v1/admin/bmark?',
            content_type='application/json',
            params=json.dumps(prms),
        )

        if second_bmark:
            prms = {
                'url': u'http://bmark.us',
                'description': u'Bookie',
                'extended': u'Exteded notes',
                'tags': u'bookmarks',
                'api_key': API_KEY,
                'username': '******',
                'inserted_by': 'chrome_ext',
            }

            # if we want to test the readable fulltext side we want to make
            # sure we pass content into the new bookmark
            prms['content'] = "<h1>Second bookmark man</h1>"

            # req_params = urllib.urlencode(prms)
            res = self.testapp.post('/api/v1/admin/bmark?',
                                    content_type='application/json',
                                    params=json.dumps(prms))

        session.flush()
        transaction.commit()
        # Run the celery task for indexing this bookmark.
        tasks.reindex_fulltext_allbookmarks(sync=True)
        return res

    def test_add_bookmark(self):
        """We should be able to add a new bookmark to the system"""
        # we need to know what the current admin's api key is so we can try to
        # add
        res = DBSession.execute(
            "SELECT api_key FROM users WHERE username = '******'").fetchone()
        key = res['api_key']

        test_bmark = {
            'url': u'http://bmark.us',
            'description': u'Bookie',
            'extended': u'Extended notes',
            'tags': u'bookmarks',
            'api_key': key,
        }

        res = self.testapp.post('/api/v1/admin/bmark',
                                params=test_bmark,
                                status=200)

        ok_('"location":' in res.body,
            "Should have a location result: " + res.body)
        ok_('description": "Bookie"' in res.body,
            "Should have Bookie in description: " + res.body)

    def test_bookmark_fetch(self):
        """Test that we can get a bookmark and it's details"""
        self._get_good_request(content=True)
        res = self.testapp.get('/api/v1/admin/bmark/{0}?api_key={1}'.format(
            GOOGLE_HASH, API_KEY),
                               status=200)

        # make sure we can decode the body
        bmark = json.loads(res.body)['bmark']
        eq_(GOOGLE_HASH, bmark[u'hash_id'],
            "The hash_id should match: " + str(bmark[u'hash_id']))

        ok_(u'tags' in bmark,
            "We should have a list of tags in the bmark returned")

        ok_(
            bmark[u'tags'][0][u'name'] in [u'python', u'search'],
            "Tag should be either python or search:" +
            str(bmark[u'tags'][0][u'name']))

        ok_(u'readable' not in bmark, "We should not have readable content")

        eq_(u'python search', bmark[u'tag_str'],
            "tag_str should be populated: " + str(dict(bmark)))

        # to get readble content we need to pass the flash with_content
        res = self.testapp.get(
            '/api/v1/admin/bmark/{0}?api_key={1}&with_content=true'.format(
                GOOGLE_HASH, API_KEY),
            status=200)

        # make sure we can decode the body
        bmark = json.loads(res.body)['bmark']

        ok_(u'readable' in bmark, "We should have readable content")

        ok_(
            'dude' in bmark['readable']['content'],
            "We should have 'dude' in our content: " +
            bmark['readable']['content'])

    def test_bookmark_fetch_fail(self):
        """Verify we get a failed response when wrong bookmark"""
        self._get_good_request()

        # test that we get a 404
        self.testapp.get('/api/v1/admin/bmark/{0}?api_key={1}'.format(
            BMARKUS_HASH, API_KEY),
                         status=404)

    def test_bookmark_remove(self):
        """A delete call should remove the bookmark from the system"""
        self._get_good_request(content=True, second_bmark=True)

        # now let's delete the google bookmark
        res = self.testapp.delete('/api/v1/admin/bmark/{0}?api_key={1}'.format(
            GOOGLE_HASH, API_KEY),
                                  status=200)

        ok_('message": "done"' in res.body,
            "Should have a message of done: " + res.body)

        # we're going to cheat like mad, use the sync call to get the hash_ids
        # of bookmarks in the system and verify that only the bmark.us hash_id
        # is in the response body
        res = self.testapp.get('/api/v1/admin/extension/sync',
                               params={'api_key': API_KEY},
                               status=200)

        ok_(GOOGLE_HASH not in res.body,
            "Should not have the google hash: " + res.body)
        ok_(BMARKUS_HASH in res.body,
            "Should have the bmark.us hash: " + res.body)

    def test_bookmark_recent_user(self):
        """Test that we can get list of bookmarks with details"""
        self._get_good_request(content=True)
        res = self.testapp.get('/api/v1/admin/bmarks?api_key=' + API_KEY,
                               status=200)

        # make sure we can decode the body
        bmark = json.loads(res.body)['bmarks'][0]
        eq_(GOOGLE_HASH, bmark[u'hash_id'],
            "The hash_id should match: " + str(bmark[u'hash_id']))

        ok_(u'tags' in bmark,
            "We should have a list of tags in the bmark returned")

        ok_(
            bmark[u'tags'][0][u'name'] in [u'python', u'search'],
            "Tag should be either python or search:" +
            str(bmark[u'tags'][0][u'name']))

        res = self.testapp.get(
            '/api/v1/admin/bmarks?with_content=true&api_key=' + API_KEY,
            status=200)

        # make sure we can decode the body
        # @todo this is out because of the issue noted in the code. We'll
        # clean this up at some point.
        # bmark = json.loads(res.body)['bmarks'][0]
        # ok_('here dude' in bmark[u'readable']['content'],
        #     "There should be content: " + str(bmark))

    def test_bookmark_recent(self):
        """Test that we can get list of bookmarks with details"""
        self._get_good_request(content=True)
        res = self.testapp.get('/api/v1/bmarks?api_key=' + API_KEY, status=200)

        # make sure we can decode the body
        bmark = json.loads(res.body)['bmarks'][0]
        eq_(GOOGLE_HASH, bmark[u'hash_id'],
            "The hash_id should match: " + str(bmark[u'hash_id']))

        ok_(u'tags' in bmark,
            "We should have a list of tags in the bmark returned")

        ok_(
            bmark[u'tags'][0][u'name'] in [u'python', u'search'],
            "Tag should be either python or search:" +
            str(bmark[u'tags'][0][u'name']))

        res = self.testapp.get(
            '/api/v1/admin/bmarks?with_content=true&api_key=' + API_KEY,
            status=200)

        # make sure we can decode the body
        # @todo this is out because of the issue noted in the code. We'll
        # clean this up at some point.
        # bmark = json.loads(res.body)['bmarks'][0]
        # ok_('here dude' in bmark[u'readable']['content'],
        #     "There should be content: " + str(bmark))

    def test_bookmark_sync(self):
        """Test that we can get the sync list from the server"""
        self._get_good_request(content=True, second_bmark=True)

        # test that we only get one resultback
        res = self.testapp.get('/api/v1/admin/extension/sync',
                               params={'api_key': API_KEY},
                               status=200)

        eq_(res.status, "200 OK", msg='Get status is 200, ' + res.status)

        ok_(GOOGLE_HASH in res.body,
            "The google hash id should be in the json: " + res.body)
        ok_(BMARKUS_HASH in res.body,
            "The bmark.us hash id should be in the json: " + res.body)

    def test_search_api(self):
        """Test that we can get list of bookmarks ordered by clicks"""
        self._get_good_request(content=True, second_bmark=True)

        res = self.testapp.get('/api/v1/bmarks/search/google', status=200)

        # make sure we can decode the body
        bmark_list = json.loads(res.body)
        results = bmark_list['search_results']
        eq_(len(results), 1,
            "We should have one result coming back: {0}".format(len(results)))

        bmark = results[0]

        eq_(
            GOOGLE_HASH, bmark[u'hash_id'],
            "The hash_id {0} should match: {1} ".format(
                str(GOOGLE_HASH), str(bmark[u'hash_id'])))

        ok_('clicks' in bmark, "The clicks field should be in there")

    def test_bookmark_tag_complete(self):
        """Test we can complete tags in the system

        By default we should have tags for python, search, bookmarks

        """
        self._get_good_request(second_bmark=True)

        res = self.testapp.get('/api/v1/admin/tags/complete',
                               params={
                                   'tag': 'py',
                                   'api_key': API_KEY
                               },
                               status=200)

        ok_('python' in res.body,
            "Should have python as a tag completion: " + res.body)

        # we shouldn't get python as an option if we supply bookmarks as the
        # current tag. No bookmarks have both bookmarks & python as tags
        res = self.testapp.get('/api/v1/admin/tags/complete',
                               params={
                                   'tag': 'py',
                                   'current': 'bookmarks',
                                   'api_key': API_KEY
                               },
                               status=200)

        ok_('python' not in res.body,
            "Should not have python as a tag completion: " + res.body)

    def test_account_information(self):
        """Test getting a user's account information"""
        res = self.testapp.get('/api/v1/admin/account?api_key=' + API_KEY,
                               status=200)

        # make sure we can decode the body
        user = json.loads(res.body)

        eq_(user['username'], 'admin',
            "Should have a username of admin {0}".format(user))

        ok_('password' not in user,
            'Should not have a field password {0}'.format(user))
        ok_('_password' not in user,
            'Should not have a field password {0}'.format(user))
        ok_('api_key' not in user,
            'Should not have a field password {0}'.format(user))

    def test_account_update(self):
        """Test updating a user's account information"""
        params = {'name': u'Test Admin'}
        res = self.testapp.post(str("/api/v1/admin/account?api_key=" +
                                    str(API_KEY)),
                                content_type='application/json',
                                params=json.dumps(params),
                                status=200)

        # make sure we can decode the body
        user = json.loads(res.body)

        eq_(user['username'], 'admin',
            "Should have a username of admin {0}".format(user))
        eq_(user['name'], 'Test Admin',
            "Should have a new name of Test Admin {0}".format(user))

        ok_('password' not in user,
            "Should not have a field password {0}".format(user))
        ok_('_password' not in user,
            "Should not have a field password {0}".format(user))
        ok_('api_key' not in user,
            "Should not have a field password {0}".format(user))

    def test_account_apikey(self):
        """Fetching a user's api key"""
        res = self.testapp.get("/api/v1/admin/api_key?api_key=" + str(API_KEY),
                               status=200)

        # make sure we can decode the body
        user = json.loads(res.body)

        eq_(user['username'], 'admin',
            "Should have a username of admin {0}".format(user))
        ok_('api_key' in user,
            "Should have an api key in there: {0}".format(user))

    def test_account_password_change(self):
        """Change a user's password"""
        params = {'current_password': '******', 'new_password': '******'}

        res = self.testapp.post("/api/v1/admin/password?api_key=" +
                                str(API_KEY),
                                params=params,
                                status=200)

        # make sure we can decode the body
        user = json.loads(res.body)

        eq_(user['username'], 'admin',
            "Should have a username of admin {0}".format(user))
        ok_('message' in user,
            "Should have a message key in there: {0}".format(user))

        params = {'current_password': '******', 'new_password': '******'}
        res = self.testapp.post("/api/v1/admin/password?api_key=" +
                                str(API_KEY),
                                params=params,
                                status=200)

    def test_account_password_failure(self):
        """Change a user's password, in bad ways"""
        params = {'current_password': '******', 'new_password': '******'}

        res = self.testapp.post("/api/v1/admin/password?api_key=" +
                                str(API_KEY),
                                params=params,
                                status=403)

        # make sure we can decode the body
        user = json.loads(res.body)

        eq_(user['username'], 'admin',
            "Should have a username of admin {0}".format(user))
        ok_('error' in user,
            "Should have a error key in there: {0}".format(user))
        ok_('typo' in user['error'],
            "Should have a error key in there: {0}".format(user))

    def test_api_ping_success(self):
        """We should be able to ping and make sure we auth'd and are ok"""
        res = self.testapp.get('/api/v1/admin/ping?api_key=' + API_KEY,
                               status=200)
        ping = json.loads(res.body)

        ok_(ping['success'], "Should success be true")

    def test_api_ping_failed_nouser(self):
        """If you don't supply a username, you've failed the ping"""
        res = self.testapp.get('/api/v1/ping?api_key=' + API_KEY, status=200)
        ping = json.loads(res.body)

        ok_(not ping['success'], "Success should be false")
        eq_(ping['message'], "Missing username in your api url.")

    def test_api_ping_failed_missing_api(self):
        """If you don't supply a username, you've failed the ping"""
        res = self.testapp.get('/ping?api_key=' + API_KEY, status=200)
        ping = json.loads(res.body)

        ok_(not ping['success'], "Success should be false")
        eq_(ping['message'], "The API url should be /api/v1")
Example #49
0
def test_csrf_by_default_fail(csrf_app: TestApp, session: DummySession):
    """CSRF error is raised by default if we try to POST to a view and we don't have token."""

    with pytest.raises(BadCSRFToken):
        csrf_app.post("/csrf_sample")
Example #50
0
class Webserver(BotPlugin):
    def __init__(self, bot):
        self.webserver = None
        self.webchat_mode = False
        self.ssl_context = None
        self.test_app = TestApp(bottle_app)
        super().__init__(bot)

    def get_configuration_template(self):
        return {
            'HOST': '0.0.0.0',
            'PORT': 3141,
            'SSL': {
                'enabled': False,
                'host': '0.0.0.0',
                'port': 3142,
                'certificate': "",
                'key': ""
            }
        }

    def check_configuration(self, configuration):
        # it is a pain, just assume a default config if SSL is absent or set to None
        if configuration.get('SSL', None) is None:
            configuration['SSL'] = {
                'enabled': False,
                'host': '0.0.0.0',
                'port': 3142,
                'certificate': "",
                'key': ""
            }
        super().check_configuration(configuration)

    def activate(self):
        if not self.config:
            self.log.info('Webserver is not configured. Forbid activation')
            return

        host = self.config['HOST']
        port = self.config['PORT']
        ssl = self.config['SSL']
        interfaces = [(host, port)]
        if ssl['enabled']:
            # noinspection PyTypeChecker
            interfaces.append(
                (ssl['host'], ssl['port'], ssl['key'], ssl['certificate']))
        self.log.info('Firing up the Rocket')
        self.webserver = Rocket(
            interfaces=interfaces,
            app_info={'wsgi_app': bottle_app},
        )
        self.webserver.start(background=True)
        self.log.debug('Liftoff!')

        super().activate()

    def deactivate(self):
        if self.webserver is not None:
            self.log.debug('Sending signal to stop the webserver')
            self.webserver.stop()
        super().deactivate()

    # noinspection PyUnusedLocal
    @botcmd(template='webstatus')
    def webstatus(self, mess, args):
        """
        Gives a quick status of what is mapped in the internal webserver
        """
        return {
            'rules':
            (((route.rule, route.name) for route in bottle_app.routes))
        }

    @webhook
    def echo(self, incoming_request):
        """
        A simple test webhook
        """
        self.log.debug("Your incoming request is :" + str(incoming_request))
        return str(incoming_request)

    @botcmd(split_args_with=' ')
    def webhook_test(self, _, args):
        """
            Test your webhooks from within err.

        The syntax is :
        !webhook test [relative_url] [post content]

        It triggers the notification and generate also a little test report.
        """
        url = args[0]
        content = ' '.join(args[1:])

        # try to guess the content-type of what has been passed
        try:
            # try if it is plain json
            loads(content)
            contenttype = 'application/json'
        except ValueError:
            # try if it is a form
            splitted = content.split('=')
            # noinspection PyBroadException
            try:
                payload = '='.join(splitted[1:])
                loads(unquote(payload))
                contenttype = 'application/x-www-form-urlencoded'
            except Exception as _:
                contenttype = 'text/plain'  # dunno what it is

        self.log.debug('Detected your post as : %s' % contenttype)

        response = self.test_app.post(url,
                                      params=content,
                                      content_type=contenttype)
        return TEST_REPORT % (url, contenttype, response.status_code)

    @botcmd(admin_only=True)
    def generate_certificate(self, mess, args):
        """
        Generate a self-signed SSL certificate for the Webserver
        """
        if not has_crypto:
            yield (
                "It looks like pyOpenSSL isn't installed. Please install this "
                "package using for example `pip install pyOpenSSL`, then try again"
            )
            return

        yield (
            "Generating a new private key and certificate. This could take a "
            "while if your system is slow or low on entropy")
        key_path = os.sep.join(
            (self.bot_config.BOT_DATA_DIR, "webserver_key.pem"))
        cert_path = os.sep.join(
            (self.bot_config.BOT_DATA_DIR, "webserver_certificate.pem"))
        make_ssl_certificate(key_path=key_path, cert_path=cert_path)
        yield "Certificate successfully generated and saved in {}".format(
            self.bot_config.BOT_DATA_DIR)

        suggested_config = self.config
        suggested_config['SSL']['enabled'] = True
        suggested_config['SSL']['host'] = suggested_config['HOST']
        suggested_config['SSL']['port'] = suggested_config['PORT'] + 1
        suggested_config['SSL']['key'] = key_path
        suggested_config['SSL']['certificate'] = cert_path
        yield ("To enable SSL with this certificate, the following config "
               "is recommended:")
        yield "{!r}".format(suggested_config)
Example #51
0
class BotTest(plugintest.PluginTestCase):
    def setUp(self):
        self.bot = self.prepare_bot(pushitbot.PushItBot('botToken'))
        self.webapp = TestApp(
            pushitbot.extend_webapp(wsgi_app([self.bot]), self.bot))

    def test_ping(self):
        self.assertEqual(self.webapp.get('/ping/').text, '<b>Pong!</b>')

    def test_chat(self):
        self.receive_message('invalid')
        self.assertReplied(u'''\
I'm not really chatty. Give /help a try if you need something.''')

    def test_token(self):
        self.assertIsNone(self.bot.pushit.read_data(1, 'token'))

        self.receive_message('/token')

        token = self.bot.pushit.read_data(1, 'token')
        self.assertIsNotNone(token)
        self.assertIsNotNone(self.bot.pushit.read_data('token', token))

        self.assertReplied(_TOKEN_TEXT % {'token': token})

        return token

    def test_revoke(self):
        token1 = self.test_token()

        self.receive_message('/revoke')
        self.assertIsNone(self.bot.pushit.read_data('token', token1))
        token2 = self.bot.pushit.read_data(1, 'token')
        self.assertIsNotNone(token2)
        self.assertReplied('''\
Your _old_ token has been revoked.
You can now use the following token to access the HTTP API:

*%(token)s*

Your API URL: /pushit/%(token)s
Your WebPush URL: http://fopina.github.io/tgbot-pushitbot/webpush/#%(token)s

Please send /help command if you have any problem''' % {'token': token2})

    def test_notify_invalid_token(self):
        res = self.webapp.post_json('/pushit/123', params={'msg': 'hello'})
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.json['ok'], False)
        self.assertEqual(res.json['code'], -1)
        self.assertEqual(res.json['description'], 'Invalid token')

    def test_notify_blocked(self):
        token = self.test_token()

        self.push_fake_result('...', status_code=403)
        res = self.webapp.post_json('/pushit/%s' % token,
                                    params={'msg': 'hello'})
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.json['ok'], False)
        self.assertEqual(res.json['code'], 403)
        self.assertEqual(res.json['description'], 'User blocked PushItBot')

    def test_notify_other_tg_error(self):
        token = self.test_token()

        self.push_fake_result('...', status_code=400)
        res = self.webapp.post_json('/pushit/%s' % token,
                                    params={'msg': 'hello'})
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.json['ok'], False)
        self.assertEqual(res.json['code'], 400)
        self.assertEqual(res.json['description'], '...')

    def test_notify_urlencoded(self):
        token = self.test_token()
        res = self.webapp.post('/pushit/%s' % token, params={'msg': 'hello'})
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.json['ok'], True)
        # assert message was sent
        self.assertReplied('hello')

    def test_notify_json(self):
        token = self.test_token()
        res = self.webapp.post_json('/pushit/%s' % token,
                                    params={'msg': 'world'})
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.json['ok'], True)
        # assert message was sent and no format
        r = self.pop_reply()[1]
        self.assertEqual(r['text'], 'world')
        self.assertNotIn('parse_mode', r)

    def test_notify_get(self):
        token = self.test_token()
        res = self.webapp.get('/pushit/%s' % token,
                              params={
                                  'msg': '1 2 3',
                                  'format': 'Markdown'
                              })
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.json['ok'], True)
        # assert message was sent with markdown format
        # assert message was sent and no format
        r = self.pop_reply()[1]
        self.assertEqual(r['text'], '1 2 3')
        self.assertEqual(r['parse_mode'], 'Markdown')

    def test_notify_broken(self):
        token = self.test_token()
        res = self.webapp.post('/pushit/%s' % token, params={'wrong': 'field'})
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.json['ok'], False)
        self.assertEqual(res.json['description'],
                         'Please check API documentation')
        # assert no messages were sent
        self.assertNoReplies()

        res = self.webapp.post('/pushit/%s' % token,
                               params={
                                   'msg': 'corrent',
                                   'format': 'wrong'
                               })
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.json['ok'], False)
        self.assertEqual(res.json['description'],
                         'Please check API documentation')
        # assert no messages were sent
        self.assertNoReplies()

    def test_notify_raw(self):
        token = self.test_token()
        res = self.webapp.post_json('/pushit/%s/raw' % token,
                                    params={'msg': 'world'})
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.json['ok'], True)
        r = self.pop_reply()[1]
        self.assertEqual(r['text'], '```\n{\n    "msg": "world"\n}\n```')
        self.assertEqual(r['parse_mode'], 'Markdown')

        res = self.webapp.get('/pushit/%s/raw/' % token,
                              params={'anything': 'else'})
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.json['ok'], True)
        r = self.pop_reply()[1]
        self.assertEqual(r['text'], '```\n{\n    "anything": "else"\n}\n```')
        self.assertEqual(r['parse_mode'], 'Markdown')

        res = self.webapp.post('/pushit/%s/raw/' % token,
                               params={'yet': 'another'})
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.json['ok'], True)
        r = self.pop_reply()[1]
        self.assertEqual(r['text'], '```\n{\n    "yet": "another"\n}\n```')
        self.assertEqual(r['parse_mode'], 'Markdown')

    def test_stats(self):
        token = self.test_token()

        self.receive_message('/stats')
        self.assertReplied('`Pushed messages so far:` *0*')

        res = self.webapp.post_json('/pushit/%s' % token,
                                    params={'msg': 'world'})
        self.assertEqual(res.json['ok'], True)

        self.receive_message('/stats')
        self.assertReplied('`Pushed messages so far:` *1*')

    def test_start_token(self):
        self.receive_message('/start token')

        token = self.bot.pushit.read_data(1, 'token')
        self.assertIsNotNone(token)

        self.assertReplied(_TOKEN_TEXT % {'token': token})
        self.assertReplied(_HELP_TEXT)

    def test_help(self):
        self.receive_message('/help')
        self.assertReplied(_HELP_TEXT)

        self.receive_message('/start')
        self.assertReplied(_HELP_TEXT)

    def test_no_new_token(self):
        import mock

        with mock.patch('os.urandom', return_value='1' * 16):
            self.test_token()
            self.receive_message('/revoke')
            self.assertReplied(
                'Failed to generate a token... Please try again.')
            self.receive_message('/token',
                                 sender={
                                     'id': 2,
                                     'first_name': 'Paul'
                                 })
Example #52
0
class TestLogin(unittest2.TestCase):
    def setUp(self):
        print("setting up ...")

        # Test application
        self.app = TestApp(alignak_webui.app.session_app)
        print("App: %s" % self.app)

    def test_login_refused(self):
        """ Login - refused"""
        print('test login/logout process - login refused')

        print('get login page')
        response = self.app.get('/login')
        # print response.body
        response.mustcontain(
            '<form role="form" method="post" action="/login">')

        print('login refused - credentials')
        response = self.app.post('/login', {
            'username': None,
            'password': None
        })
        redirected_response = response.follow()
        redirected_response.mustcontain(
            'Access denied! Check your username and password.')

        print('login refused - fake credentials')
        response = self.app.post('/login', {
            'username': '******',
            'password': '******'
        })
        redirected_response = response.follow()
        redirected_response.mustcontain(
            'Access denied! Check your username and password.')

        # / sends a status 302: redirected to /login page
        response = self.app.get('/', status=302)
        redirected_response = response.follow()

        # /ping sends a status 401: unauthorized
        response = self.app.get('/ping', status=401)

        # /heartbeat sends a status 401: unauthorized
        response = self.app.get('/heartbeat', status=401)

    def test_login_accepted_session(self):
        """ Login - accepted session """
        print('test login accepted')

        print('get login page')
        response = self.app.get('/login')
        response.mustcontain(
            '<form role="form" method="post" action="/login">')

        print('login accepted - go to home page')
        response = self.app.post('/login', {
            'username': '******',
            'password': '******'
        },
                                 status=302)
        print('Response: %s' % response)

        # A session cookie now exists
        assert self.app.cookies['Alignak-WebUI']
        print('cookies: ')
        for cookie in self.app.cookiejar:
            print('cookie: ', cookie.__dict__)
            if cookie.name == 'Alignak-WebUI':
                assert cookie.expires is None

        # A session exists and it contains: current user, his realm and his live synthesis
        session = response.request.environ['beaker.session']
        assert 'current_user' in session and session['current_user']
        assert session['current_user'].name == 'admin'
        assert 'current_realm' in session and session['current_realm']
        assert session['current_realm'].name == 'All'
        # assert 'current_ls' in session and session['current_ls']

    def test_login_accepted(self):
        """ Login - accepted"""
        print('test login accepted')

        print('get login page')
        response = self.app.get('/login')
        response.mustcontain(
            '<form role="form" method="post" action="/login">')

        print('login accepted - go to home page')
        response = self.app.post('/login', {
            'username': '******',
            'password': '******'
        },
                                 status=302)
        print('Response: %s' % response)

        # Redirected twice: /login -> / -> /livestate
        redirected_response = response.follow()
        print("Redirected response: %s" % redirected_response)
        # print('Redirected response: %s' % redirected_response)
        redirected_response = redirected_response.follow()
        # print('Redirected response: %s' % redirected_response)
        redirected_response.mustcontain('<div id="livestate">')

        # /ping, now sends a status 200
        response = self.app.get('/ping')
        print('ping response: %s' % response)
        response.mustcontain('pong')

        # /heartbeat, now sends a status 200
        response = self.app.get('/heartbeat', status=200)
        print('heartbeat response: %s' % response)
        response.mustcontain('Current logged-in user: admin')

        # Require header refresh
        self.app.get('/ping?action=header', status=204)
        response = self.app.get('/ping?action=refresh', status=200)
        assert response.json == {
            'status':
            'ok',
            'message':
            'missing template name. Use /ping?action=refresh&template=name.'
        }
        response = self.app.get('/ping?action=refresh&template=_header_states',
                                status=200)
        response.mustcontain('"hosts-states-popover-content')
        response.mustcontain('"services-states-popover-content')

        print('logout - go to login page')
        response = self.app.get('/logout')
        redirected_response = response.follow()
        redirected_response.mustcontain(
            '<form role="form" method="post" action="/login">')
        # A host cookie still exists - sure? looks strange because the session is deleted!
        assert self.app.cookies['Alignak-WebUI']
        print('cookies: ', self.app.cookiejar)
        for cookie in self.app.cookiejar:
            print('cookie: ', cookie.name, cookie.expires)
            if cookie.name == 'Alignak-WebUI':
                assert cookie.expires is None

    def test_logout(self):
        """ Logout from the application"""
        print('test logout')

        print('login accepted - got to home page')
        response = self.app.post('/login', {
            'username': '******',
            'password': '******'
        })
        # Redirected twice: /login -> / -> /livestate !
        redirected_response = response.follow()
        print("Redirected response: %s" % redirected_response)
        redirected_response = redirected_response.follow()
        redirected_response.mustcontain('<div id="livestate">')
        # A host cookie now exists
        assert self.app.cookies['Alignak-WebUI']

        print('get home page /')
        response = self.app.get('/')
        redirected_response = response.follow()
        redirected_response.mustcontain('<div id="livestate">')

        # /ping, sends a status 200, but refresh is required
        print('ping refresh required, data loaded')
        response = self.app.get('/ping')
        print(response)
        # response.mustcontain('refresh')

        # Reply with required refresh done
        response = self.app.get('/ping?action=done')
        print(response)
        # response.mustcontain('pong')

        print('logout')
        response = self.app.get('/logout')
        redirected_response = response.follow()
        redirected_response.mustcontain(
            '<form role="form" method="post" action="/login">')
        # print 'click on logout'
        # response = response.click(href='/logout')
        # redirected_response = response.follow()
        # redirected_response.mustcontain('<form role="form" method="post" action="/login">')

        # /ping sends a status 401: unauthorized
        response = self.app.get('/ping', status=401)
        response.mustcontain('No user session')

        # /heartbeat sends a status 401: unauthorized
        response = self.app.get('/heartbeat', status=401)
        response.mustcontain('Session expired')

        print('get home page /')
        response = self.app.get('/')
        redirected_response = response.follow()
        redirected_response.mustcontain(
            '<form role="form" method="post" action="/login">')
Example #53
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'))
Example #54
0
class TestStatics(object):
    def setup(self):
        self.app = TestApp(StaticsMiddleware(FakeApp, './tests'))

    def test_plain_request(self):
        r = self.app.get('/test.html')
        assert 'Welcome to TurboGears 2.0' in r

    def test_unknown_content_type(self):
        r = self.app.get('/empty_file.unknown')
        assert r.content_type == 'application/octet-stream'
        assert 'EMPTY' in r

    def test_if_modified_since(self):
        r = self.app.get(
            '/empty_file.unknown',
            headers={'If-Modified-Since': 'Sat, 29 Oct 1994 19:43:31 GMT'})
        assert 'EMPTY' in r

    @raises(HTTPBadRequest)
    def test_if_modified_since_invalid_date(self):
        r = self.app.get('/empty_file.unknown',
                         headers={'If-Modified-Since': 'This is not a date'})

    def test_if_modified_since_future(self):
        next_year = datetime.utcnow()
        next_year.replace(year=next_year.year + 1)

        r = self.app.get(
            '/empty_file.unknown',
            headers={'If-Modified-Since': FileServeApp.make_date(next_year)},
            status=304)

    def test_if_none_match(self):
        r = self.app.get('/empty_file.unknown')
        etag = r.headers['ETag']

        r = self.app.get('/empty_file.unknown',
                         headers={'If-None-Match': etag},
                         status=304)

    def test_if_none_match_different(self):
        r = self.app.get('/empty_file.unknown',
                         headers={'If-None-Match': 'Probably-Not-The-Etag'})
        assert 'EMPTY' in r

    def test_make_date(self):
        res = FileServeApp.make_date(datetime(2000, 1, 1, 0, 0, 0, 0))
        assert res == 'Sat, 01 Jan 2000 00:00:00 GMT'

    def test_304_on_post(self):
        r = self.app.post('/empty_file.unknown', status=304)

    def test_forbidden_path(self):
        r = self.app.get('/missing/../test.html', status=404)
        assert 'Out of bounds' in r

    def test_FileApp_non_existing_file(self):
        fa = TestApp(FileServeApp('this_does_not_exists.unknown', 0))
        r = fa.get('/', status=403)
        assert '403' in r
Example #55
0
class TestApi(test_interface.TestInterface):

    def setUp(self):
        super(TestApi, self).setUp()
        self.app = TestApp(get_app(constants.config))

    def tearDown(self):
        super(TestApi, self).tearDown()
        self.app = None

    @unittest.skip
    def test_usage_run_for_all(self):
        """Asserts a usage run generates data for all tenants"""

        usage = helpers.get_usage(self.start, self.end)

        with mock.patch('distil.interface.Interface') as Interface:

            tenants = []

            for tenant in constants.TENANTS:
                t = mock.Mock(spec=interface.Tenant)
                t.usage.return_value = usage
                t.conn = mock.Mock()
                t.tenant = tenant
                t.id = tenant['id']
                t.name = tenant['name']
                t.description = tenant['description']
                tenants.append(t)

            ceil_interface = mock.Mock(spec=interface.Interface)

            ceil_interface.tenants = tenants

            Interface.return_value = ceil_interface

            # patch to mock out the novaclient call
            with mock.patch('distil.helpers.flavor_name') as flavor_name:
                flavor_name.side_effect = lambda x: x

                resp = self.app.post("/collect_usage")
                self.assertEquals(resp.status_int, 200)

                tenants = self.session.query(models.Tenant)
                self.assertTrue(tenants.count() > 0)

                usages = self.session.query(models.UsageEntry)
                self.assertTrue(usages.count() > 0)
                resources = self.session.query(models.Resource)

                self.assertEquals(resources.count(), len(usage.values()))

    def test_sales_run_for_all(self):
        """Assertion that a sales run generates all tenant orders"""
        numTenants = 7
        numResources = 5

        now = datetime.utcnow().\
            replace(hour=0, minute=0, second=0, microsecond=0)

        helpers.fill_db(self.session, numTenants, numResources, now)

        for i in range(numTenants):
            resp = self.app.post("/sales_order",
                                 params=json.dumps({"tenant": "tenant_id_" +
                                                    str(i)}),
                                 content_type='application/json')
            resp_json = json.loads(resp.body)
            print resp_json

            query = self.session.query(models.SalesOrder)
            self.assertEquals(query.count(), i + 1)

            self.assertEquals(len(resp_json['resources']), numResources)

    def test_sales_run_single(self):
        """Assertion that a sales run generates one tenant only"""
        numTenants = 5
        numResources = 5

        now = datetime.utcnow().\
            replace(hour=0, minute=0, second=0, microsecond=0)
        helpers.fill_db(self.session, numTenants, numResources, now)
        resp = self.app.post("/sales_order",
                             params=json.dumps({"tenant": "tenant_id_0"}),
                             content_type="application/json")
        resp_json = json.loads(resp.body)

        query = self.session.query(models.SalesOrder)
        self.assertEquals(query.count(), 1)
        # todo: assert things in the response
        self.assertEquals(len(resp_json['resources']), numResources)

    def test_sales_raises_400(self):
        """Assertion that 400 is being thrown if content is not json."""
        resp = self.app.post("/sales_order", expect_errors=True)
        self.assertEquals(resp.status_int, 400)

    def test_sales_order_no_tenant_found(self):
        """Test that if a tenant is provided and not found,
        then we throw an error."""
        resp = self.app.post('/sales_order',
                             expect_errors=True,
                             params=json.dumps({'tenant': 'bogus tenant'}),
                             content_type='application/json')
        self.assertEquals(resp.status_int, 400)

    def test_tenant_dict(self):
        """Checking that the tenant dictionary is built correctly
           based on given entry data."""
        num_resources = 3
        num_services = 2
        volume = 5

        entries = helpers.create_usage_entries(num_resources,
                                               num_services, volume)

        tenant = mock.MagicMock()
        tenant.name = "tenant_1"
        tenant.id = "tenant_id_1"

        db = mock.MagicMock()
        db.get_resource_metadata.return_value = {}

        tenant_dict = web.build_tenant_dict(tenant, entries, db)

        self.assertEquals(len(tenant_dict['resources']), num_resources)
        self.assertEquals(tenant_dict['tenant_id'], "tenant_id_1")
        self.assertEquals(tenant_dict['name'], "tenant_1")

        for resource in tenant_dict['resources'].values():
            for service in resource['services']:
                self.assertEquals(service['volume'], volume)

    def test_tenant_dict_no_entries(self):
        """Test to ensure that the function handles an
           empty list of entries correctly."""
        entries = []

        tenant = mock.MagicMock()
        tenant.name = "tenant_1"
        tenant.id = "tenant_id_1"

        db = mock.MagicMock()
        db.get_resource_metadata.return_value = {}

        tenant_dict = web.build_tenant_dict(tenant, entries, db)

        self.assertEquals(len(tenant_dict['resources']), 0)
        self.assertEquals(tenant_dict['tenant_id'], "tenant_id_1")
        self.assertEquals(tenant_dict['name'], "tenant_1")

    def test_add_cost_to_tenant(self):
        """Checking that the rates are applied correctly,
           and that we get correct total values."""
        volume = 3600
        rate = {'rate': Decimal(0.25), 'unit': 'hour'}

        test_tenant = {
            'resources': {
                'resouce_ID_1': {
                    'services': [{'name': 'service_1',
                                  'volume': Decimal(volume),
                                  'unit': 'second'},
                                 {'name': 'service_2',
                                  'volume': Decimal(volume),
                                  'unit': 'second'}]
                },
                'resouce_ID_2': {
                    'services': [{'name': 'service_1',
                                  'volume': Decimal(volume),
                                  'unit': 'second'},
                                 {'name': 'service_2',
                                  'volume': Decimal(volume),
                                  'unit': 'second'}]
                }
            }
        }

        service_cost = round(
            convert_to(volume, 'second', rate['unit']) * rate['rate'], 2)
        total_cost = service_cost * 4

        ratesManager = mock.MagicMock()
        ratesManager.rate.return_value = rate

        tenant_dict = web.add_costs_for_tenant(test_tenant, ratesManager)

        self.assertEquals(tenant_dict['total_cost'], str(total_cost))
        for resource in tenant_dict['resources'].values():
            self.assertEquals(resource['total_cost'], str(service_cost * 2))
            for service in resource['services']:
                self.assertEquals(service['volume'],
                                  str(convert_to(volume, 'second',
                                                 rate['unit'])))
                self.assertEquals(service['unit'], rate['unit'])
                self.assertEquals(service['cost'], str(service_cost))

    def test_add_cost_to_empty_tenant(self):
        """An empty tenant should not be charged anything,
           nor cause errors."""

        empty_tenant = {'resources': {}}

        ratesManager = mock.MagicMock()

        tenant_dict = web.add_costs_for_tenant(empty_tenant, ratesManager)

        self.assertEquals(tenant_dict['total_cost'], str(0))

    def test_get_last_collected(self):
        """test to ensure last collected api call returns correctly"""
        now = datetime.utcnow()
        self.session.add(models._Last_Run(last_run=now))
        self.session.commit()
        resp = self.app.get("/last_collected")
        resp_json = json.loads(resp.body)
        self.assertEquals(resp_json['last_collected'], str(now))

    def test_get_last_collected_default(self):
        """test to ensure last collected returns correct default value"""
        resp = self.app.get("/last_collected")
        resp_json = json.loads(resp.body)
        self.assertEquals(resp_json['last_collected'], str(dawn_of_time))
Example #56
0
class ServerTestCase(unittest.TestCase):
    def setUp(self):
        self.mock_packagecache = mock.Mock(spec=cache.PackageCache)
        self.mock_packagestore = mock.Mock(spec=disk.DiskPackageStore)
        self.mock_pypi = mock.Mock(spec=pypi.PyPI)
        self.app = TestApp(
            server.configure_app(self.mock_pypi,
                                 self.mock_packagestore,
                                 self.mock_packagecache,
                                 testing=True))

    def test_index(self):
        response = self.app.get("/")
        self.assertIn(b"PyPI Cache", response.body)

    def test_static(self):
        self.app.get("/static/css/bootstrap.css")

    def test_simple(self):
        response = self.app.get("/simple")
        self.assertIn(b"simple", response.body)

    def test_simple_package(self):
        content = """<html><a href="mypackage">mypackage-1.0</a></html>"""
        self.mock_pypi.get_simple_package_info.return_value = content
        response = self.app.get("/simple/mypackage/")
        self.assertEqual(response.body, content)

    def test_local_package(self):
        self.mock_packagestore.list_files.return_value = [
            dict(package="mypackage",
                 firstletter="m",
                 filename="mypackage-1.0.tar.gz",
                 md5="ahashabcdef")
        ]
        response = self.app.get("/local/mypackage/")
        self.assertIn(
            """<a href="/packages/mypackage/mypackage-1.0.tar.gz#md5=ahashabcdef">mypackage-1.0.tar.gz</a>""",
            response.body)
        self.mock_packagestore.list_files.assert_called_with("mypackage")

    def test_packages_source_sdist(self):
        for url in [
                "/packages/source/M/MyPackage/MyPackage-1.0.tar.gz",
                "/packages/MyPackage/MyPackage-1.0.tar.gz",
        ]:
            logging.info("Testing url {0}".format(url))
            self.mock_packagecache.get_file.return_value = "--package-data--"
            response = self.app.get(url)
            self.assertEqual("application/x-tar",
                             response.headers["Content-Type"])
            self.assertEqual(b"--package-data--", response.body)

            self.mock_packagecache.get_file.assert_called_with(
                "MyPackage", "MyPackage-1.0.tar.gz", python_version=None)

    def test_packages_source_notfound(self):
        def fail(*args, **kwargs):
            raise exceptions.NotFound("Unknown package")

        self.mock_packagecache.get_file.side_effect = fail
        self.app.get("/packages/source/m/mypackage/mypackage-1.1.tar.gz",
                     status=404)
        self.mock_packagecache.get_file.assert_called_with(
            "mypackage", "mypackage-1.1.tar.gz", python_version=None)

    @unittest.skip("Need to figure out PUT under flask")
    def test_put_package_file(self):
        response = self.app.put(
            "/packages/source/m/mypackage/mypackage-1.0.tar.gz",
            "--package-data--")
        self.assertDictEqual(response.json, {"uploaded": "ok"})
        self.assertTrue(self.mock_packagecache.add_file.called)
        args, kwargs = self.mock_packagecache.add_file.call_args
        self.assertEqual(args[:2], ("mypackage", "mypackage-1.0.tar.gz"))
        self.assertEqual(args[2].getvalue(), b"--package-data--")

    def test_post_packge_file(self):
        response = self.app.post("/uploadpackage/",
                                 upload_files=[
                                     ("sdist", "mypackage-1.0.tar.gz",
                                      b"--package-data--")
                                 ])
        self.assertDictEqual(response.json, {"uploaded": "ok"})
        self.assertTrue(self.mock_packagestore.add_file.called)
        args, kwargs = self.mock_packagestore.add_file.call_args
        self.assertEqual(args[:2], ("mypackage", "mypackage-1.0.tar.gz"))
        self.assertEqual(args[2].getvalue(), b"--package-data--")

    def test_post_missing_package_data(self):
        """Test a post with no pacakge data

        """
        response = self.app.post("/uploadpackage/", status=400)
        self.assertDictEqual(response.json, {
            "error": True,
            "message": "Missing package data."
        })

    def test_post_requirements_txt(self):
        self.mock_packagecache.cache_requirements_txt.return_value = {
            "processed": "requirements"
        }
        response = self.app.post("/requirements.txt",
                                 upload_files=[
                                     ("requirements", "requirements.txt",
                                      b"mypackage==1.0")
                                 ])
        self.assertDictEqual(response.json, {"processed": "requirements"})
        args, kwargs = self.mock_packagecache.cache_requirements_txt.call_args
        self.assertEqual(args[0].getvalue(), b"mypackage==1.0")

    def test_post_no_requirements_txt(self):
        """Test a post to requirements.txt without a upload_files

        """
        response = self.app.post("/requirements.txt", status=400)
        self.assertDictEqual(response.json, {
            "error": True,
            "message": "Missing requirements data."
        })

    def test_packages_bdist(self):
        self.mock_packagecache.get_file.return_value = "--package-data--"
        response = self.app.get(
            "/packages/2.7/m/mypackage/mypackage-1.0-py2.7.egg")
        self.assertEqual("application/zip", response.headers["Content-Type"])
        self.assertEqual(b"--package-data--", response.body)

        self.mock_packagecache.get_file.assert_called_with(
            "mypackage", "mypackage-1.0-py2.7.egg", python_version="2.7")
class BaseTestAPI(unittest.TestCase):
    """ Test login, logout, and session handling """

    @classmethod
    def setUpClass(cls):
        """Set up resources to be shared within a test class"""
        cls.session_id = ""

        with create_validator_app().app_context():
            # update application's db config options so unittests
            # run against test databases
            suite = cls.__name__.lower()
            config = dataactcore.config.CONFIG_DB
            cls.num = randint(1, 9999)
            config['db_name'] = 'unittest{}_{}_data_broker'.format(cls.num, suite)
            dataactcore.config.CONFIG_DB = config
            create_database(CONFIG_DB['db_name'])
            run_migrations()

            # drop and re-create test user db/tables
            setup_user_db()
            # drop and re-create test job db/tables
            setup_job_tracker_db()
            # drop and re-create test error db/tables
            setup_error_db()
            # drop and re-create test validation db/tables
            setup_validation_db()
            # load e-mail templates
            setup_emails()

            # set up default e-mails for tests
            test_users = {
                'admin_user': '******',
                'agency_user': '******',
                'agency_user_2': '*****@*****.**',
                'no_permissions_user': '******'
            }
            user_password = '******'
            admin_password = '******'

            # get user info and save as class variables for use by tests
            sess = GlobalDB.db().session
            admin_cgac = CGAC(cgac_code='SYS', agency_name='Admin Agency')
            cls.admin_cgac_code = admin_cgac.cgac_code
            sess.add(admin_cgac)
            sess.commit()

            cgac = CGAC(cgac_code='000', agency_name='Example Agency')

            # set up users for status tests
            def add_user(email, name, username, website_admin=False):
                user = UserFactory(
                    email=email, website_admin=website_admin,
                    name=name, username=username,
                    affiliations=[UserAffiliation(
                        cgac=cgac,
                        permission_type_id=PERMISSION_TYPE_DICT['writer']
                    )]
                )
                user.salt, user.password_hash = get_password_hash(user_password, Bcrypt())
                sess.add(user)

            add_user(test_users['agency_user'], "Test User", "testUser")
            add_user(test_users['agency_user_2'], "Test User 2", "testUser2")

            # add new users
            create_user_with_password(test_users["admin_user"], admin_password, Bcrypt(), website_admin=True)
            create_user_with_password(test_users["no_permissions_user"], user_password, Bcrypt())

            agency_user = sess.query(User).filter(User.email == test_users['agency_user']).one()
            cls.agency_user_id = agency_user.user_id

            sess.commit()

        # set up info needed by the individual test classes
        cls.test_users = test_users
        cls.user_password = user_password
        cls.admin_password = admin_password
        cls.local = CONFIG_BROKER['local']

    def setUp(self):
        """Set up broker unit tests."""
        app = create_broker_app()
        app.config['TESTING'] = True
        app.config['DEBUG'] = False
        self.app = TestApp(app)

    @classmethod
    def tearDownClass(cls):
        """Tear down class-level resources."""
        GlobalDB.close()
        drop_database(CONFIG_DB['db_name'])

    def tearDown(self):
        """Tear down broker unit tests."""

    def login_admin_user(self):
        """Log an admin user into broker."""
        # TODO: put user data in pytest fixture; put credentials in config file
        user = {"username": self.test_users['admin_user'], "password": self.admin_password}
        response = self.app.post_json("/v1/login/", user, headers={"x-session-id": self.session_id})
        self.session_id = response.headers["x-session-id"]
        return response

    def login_user(self, username=None):
        """Log an agency user (non-admin) into broker."""
        # TODO: put user data in pytest fixture; put credentials in config file
        if username is None:
            username = self.test_users['agency_user']
        user = {"username": username, "password": self.user_password}
        response = self.app.post_json("/v1/login/", user, headers={"x-session-id": self.session_id})
        self.session_id = response.headers["x-session-id"]
        return response

    def logout(self):
        """Log user out of broker."""
        return self.app.post("/v1/logout/", {}, headers={"x-session-id": self.session_id})

    def session_route(self):
        """Get session."""
        return self.app.get("/v1/session/", headers={"x-session-id": self.session_id})

    def check_response(self, response, status, message=None):
        """Perform common tests on API responses."""
        self.assertEqual(response.status_code, status)
        self.assertEqual(response.headers.get("Content-Type"), "application/json")
        try:
            self.assertIsInstance(response.json, dict)
        except AttributeError:
            self.fail("Response is missing JSON component")
        json = response.json
        if message:
            self.assertEqual(message, json["message"])
class TestChangePassword(BaseTestCase):
    def test_wrong_old_password(self):
        "No password change if old password is not corret"

        # Create a user.
        user = self.makeUser('thruflo', 'Password')
        Session.add(user)
        old_hash = user.password

        self.authenticate()

        # Attempt to change password.
        post_data = {
            'old_password': '******',
            'new_password': '******',
            'new_confirm': 'swordpas',
            'next': '/foo/bar',
        }
        res = self.app.post('/auth/change_password', post_data)

        # Verify that password hasn't changed
        Session.add(user)
        Session.refresh(user)
        self.assertTrue("Wrong current password" in res.body)
        self.assertTrue("/foo/bar" in res.body)
        self.assertEquals(user.password, old_hash)

    def test_wrong_old_password_returns_valid_user(self):
        "Bug fix: user template param must not be None"
        from pyramid_simpleauth.view import change_password
        from pyramid import testing

        # Create a user.
        user = self.makeUser('thruflo', 'Password')
        Session.add(user)

        post_data = {
            'old_password': '******',
            'new_password': '******',
            'new_confirm': 'sworDpas',
        }
        request = testing.DummyRequest(post=post_data)
        request.user = user
        testing.setUp(settings={})
        res = change_password(request)

        self.assertTrue(res['user'])

    def test_new_passwords_dont_match(self):
        "No password change if new passwords don't match"

        # Create a user.
        user = self.makeUser('thruflo', 'Password')
        Session.add(user)
        old_hash = user.password

        self.authenticate()

        # Attempt to change password.
        post_data = {
            'old_password': '******',
            'new_password': '******',
            'new_confirm': 'oswdrpsa',
        }
        res = self.app.post('/auth/change_password', post_data)

        # Verify that password hasn't changed
        Session.add(user)
        Session.refresh(user)
        self.assertTrue("Fields do not match" in res.body)
        self.assertEquals(user.password, old_hash)

    def test_sucess(self):
        "If all conditions are met, change password"

        # Create a user.
        user = self.makeUser('thruflo', 'Password')
        Session.add(user)
        old_hash = user.password

        self.authenticate()

        # Attempt to change password.
        post_data = {
            'old_password': '******',
            'new_password': '******',
            'new_confirm': 'sworDpas',
            'next': '/foo/bar',
        }
        res = self.app.post('/auth/change_password', post_data)

        # Verify that password has changed
        Session.add(user)
        Session.refresh(user)
        self.assertNotEquals(user.password, old_hash)

        # Verify redirect
        self.assertEquals(res.headers['Location'], 'http://localhost/foo/bar')

    def test_sucess_logs_user_out(self):
        "Changing a user password logs the user out."

        from pyramid_simpleauth.events import UserLoggedOut
        from pyramid_simpleauth.model import User
        mock_subscriber = Mock()
        self.config = config_factory()
        self.config.add_subscriber(mock_subscriber, UserLoggedOut)
        self.app = TestApp(self.config.make_wsgi_app())

        # Create a user.
        user = self.makeUser('thruflo', 'Password')
        Session.add(user)
        old_hash = user.password

        self.authenticate()

        # Attempt to change password.
        post_data = {
            'old_password': '******',
            'new_password': '******',
            'new_confirm': 'sworDpas',
            'next': '/foo/bar',
        }
        res = self.app.post('/auth/change_password', post_data)

        # Verify logged out.
        self.assertTrue(len(res.headers['Set-Cookie']) < 200)

        # Handler was called with the authentiated user as the second arg.
        self.assertTrue(mock_subscriber.called)
        event = mock_subscriber.call_args_list[0][0][0]
        self.assertTrue(isinstance(event.user, User))
class TestSignup(BaseTestCase):
    def test_render_signup_form(self):
        """A GET request to the signup view should render the signup form."""

        res = self.app.get('/auth/signup')
        self.failUnless('<input id="username" name="username"' in res.body)

    def test_signup(self):
        """Signup saves a user and their email address."""

        # Sanity check there isn't an existing user.
        existing = get_existing_user(username='******')
        self.assertTrue(existing is None)
        # Signup.
        post_data = {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'confirm': 'Password'
        }
        res = self.app.post('/auth/signup', post_data, status=302)
        assert res  # to satisfy pyflakes
        # Now there is a user.
        existing = get_existing_user(username='******')
        self.assertTrue(existing is not None)
        # And their email address is...
        self.assertTrue(existing.emails[0].address == '*****@*****.**')

    def test_signup_remember(self):
        """Signup logs the user in."""

        # The first request sets an empty session cookie.
        res = self.app.post('/auth/signup', {}, status="*")
        self.assertTrue(len(res.headers['Set-Cookie']) < 200)
        # Signup sets a cookie to remember the user.
        post_data = {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'confirm': 'Password'
        }
        res = self.app.post('/auth/signup', post_data, status=302)
        self.assertTrue(len(res.headers['Set-Cookie']) > 250)

    def test_signup_redirect(self):
        """Signup redirects to the user's profile page."""

        # Signup.
        post_data = {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'confirm': 'Password'
        }
        res = self.app.post('/auth/signup', post_data, status=302)
        # The response redirects to `/` by default with no routes or settings.
        self.assertTrue(res.headers['Location'] == 'http://localhost/')
        # The response redirects to the `users` route if exposed.
        self.config = config_factory()
        self.config.add_route('users', 'some/path')
        self.app = TestApp(self.config.make_wsgi_app())
        post_data = {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'confirm': 'Password'
        }
        res = self.app.post('/auth/signup', post_data, status=302)
        self.assertTrue(
            res.headers['Location'] == 'http://localhost/some/path')
        # The response redirects to the `simpleauth.after_signup_route` route
        # if specified.
        settings = {'simpleauth.after_signup_route': 'flobble'}
        self.config = config_factory(**settings)
        self.config.add_route('flobble', 'wob')
        self.app = TestApp(self.config.make_wsgi_app())
        post_data = {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'confirm': 'Password'
        }
        res = self.app.post('/auth/signup', post_data, status=302)
        self.assertTrue(res.headers['Location'] == 'http://localhost/wob')

    def test_signup_event(self):
        """Signup fires a ``UserSignedUp`` event."""

        from pyramid_simpleauth.events import UserSignedUp
        from pyramid_simpleauth.model import User
        # Setup event listener.
        mock_subscriber = Mock()
        self.config = config_factory()
        self.config.add_subscriber(mock_subscriber, UserSignedUp)
        self.app = TestApp(self.config.make_wsgi_app())
        # Signup.
        post_data = {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'confirm': 'Password'
        }
        res = self.app.post('/auth/signup', post_data, status=302)
        assert res  # to satisfy pyflakes
        # Handler was called with the authentiated user as the second arg.
        self.assertTrue(mock_subscriber.called)
        event = mock_subscriber.call_args_list[0][0][0]
        self.assertTrue(isinstance(event.user, User))
Example #60
0
class TestReactivateFunctional(TestCase):
    def _reset_admin(self):
        """Reset the admin account"""
        DBSession.execute(
            "UPDATE users SET activated='1' WHERE username='******';")
        Activation.query.delete()
        transaction.commit()

    def setUp(self):
        from pyramid.paster import get_app
        from bookie.tests import BOOKIE_TEST_INI
        app = get_app(BOOKIE_TEST_INI, 'bookie')
        from webtest import TestApp
        self.testapp = TestApp(app)
        testing.setUp()

    def tearDown(self):
        self._reset_admin()
        testing.tearDown()

    def test_activate_form_bad(self):
        """Test bad call to reset"""
        res = self.testapp.post('/api/v1/suspend',
                                content_type='application/json',
                                status=406)
        success = json.loads(res.body)['error']
        self.assertTrue(
            success is not None,
            "Should not be successful with no email address: " + str(res))

        res = self.testapp.post('/api/v1/suspend',
                                params={'email': '*****@*****.**'},
                                status=404)
        success = json.loads(res.body)
        self.assertTrue(
            'error' in success,
            "Should not be successful with invalid email address: " + str(res))

    @patch('bookie.lib.message.sendmail')
    def test_activate_form(self, mock_sendmail):
        """ Functional test to see if we can submit the api to reset an account

        Now by doing this we end up marking the account deactivated which
        causes other tests to 403 it up. Need to reinstate the admin account on
        tearDown

        """
        res = self.testapp.post('/api/v1/suspend',
                                params={'email': u'*****@*****.**'},
                                status=200)

        success = json.loads(res.body)
        self.assertTrue(
            'message' in success,
            "Should be successful with admin email address: " + str(res))
        self.assertTrue(mock_sendmail.called)

    @patch('bookie.lib.message.sendmail')
    def test_activate_form_dual(self, mock_sendmail):
        """Test that we can't resubmit for reset, get prompted to email

        If we reset and then try to say "I've forgotten" a second time, we
        should get a nice message. And that message should allow us to get a
        second copy of the email sent.

        """
        res = self.testapp.post('/api/v1/suspend',
                                params={'email': u'*****@*****.**'},
                                status=200)
        self.assertTrue(mock_sendmail.called)

        success = json.loads(res.body)
        self.assertTrue('message' in success,
                        "Should be successful with admin email address")

        res = self.testapp.post('/api/v1/suspend',
                                params={'email': u'*****@*****.**'},
                                status=406)

        success = json.loads(res.body)
        self.assertTrue('error' in success,
                        "Should not be successful on second try: " + str(res))

        self.assertTrue('already' in str(res),
                        "Should find 'already' in the response: " + str(res))

    @patch('bookie.lib.message.sendmail')
    def test_reactivate_process(self, mock_sendmail):
        """Walk through all of the steps at a time

        - First we mark that we've forgotten
        - Then use make sure we get a 403 accessing something
        - Then we go back through our activation using our code
        - Finally verify we can access the earlier item

        """
        res = self.testapp.post('/api/v1/suspend',
                                params={'email': u'*****@*****.**'},
                                status=200)
        self.assertTrue(mock_sendmail.called)

        success = json.loads(res.body)
        self.assertTrue('message' in success,
                        "Should be successful with admin email address")

        # now let's try to login
        # the migrations add a default admin account
        user_data = {
            'login': '******',
            'password': '******',
            'form.submitted': 'true'
        }

        res = self.testapp.post('/login', params=user_data, status=200)

        self.assertTrue(
            'account deactivated' in str(res),
            "Login should have failed since we're not active: " + str(res))

        act = Activation.query.first()
        self.testapp.delete(
            "/api/v1/suspend?username={0}&code={1}&password={2}".format(
                user_data['login'], act.code, 'admin'),
            status=200)

        self.assertTrue('activated' in str(res),
                        "Should be prompted to login now: " + str(res))

        user_data = {
            'login': '******',
            'password': '******',
            'form.submitted': 'true'
        }

        res = self.testapp.post('/login', params=user_data, status=302)