def test_exc_done_rollback():
    """No problems with error handler if controller manually rollbacks."""
    app = make_app(RbRoot)
    response = app.get('/doerr?id=28&dorb=1')
    assert 'KARL27' in response, 'Exception handler should have answered'
    assert session.query(User).get(28) is None
    assert session.query(User).get(29) is not None
Exemple #2
0
    def test_validation(self):
        """Data can be converted and validated"""
        response = self.app.get("/istrue?value=true")
        assert response.body == 'True'
        response = self.app.get("/istrue?value=false")
        assert response.body == 'False'

        app = testutil.make_app(MyRoot)
        response = app.get("/istrue?value=foo")
        assert response.raw['msg'] == 'Error Message'

        response = app.get("/save?submit=send&firstname=John&lastname=Doe")
        assert response.raw['fullname'] == "John Doe"
        assert response.raw['submit'] == "send"
        response = app.get("/save?submit=send&firstname=Arthur")
        assert response.raw['fullname'] == "Arthur Miller"
        response = app.get("/save?submit=send&firstname=Arthur&lastname=")
        assert response.raw['fullname'] == "Arthur "
        response = app.get("/save?submit=send&firstname=D&lastname=")
        assert len(response.raw['errors'].keys()) == 1
        assert response.raw['errors'].has_key("firstname")
        assert "characters" in response.raw['errors']["firstname"].lower()
        response = app.get("/save?submit=send&firstname=&lastname=")
        assert len(response.raw['errors'].keys()) == 1
        assert response.raw['errors'].has_key("firstname")
def test_cntrl_commit():
    """It's safe to commit a transaction in the controller."""
    app = make_app(MyRoot)
    response = app.get("/create_person?id=23&docom=1")
    assert 'InvalidRequestError' not in response
    assert session.query(Person).get(23) is not None, \
        'The Person 23 should have been saved during commit inside controller'
    def test_validation(self):
        """Data can be converted and validated"""
        response = self.app.get("/istrue?value=true")
        assert response.body == 'True'
        response = self.app.get("/istrue?value=false")
        assert response.body == 'False'

        app = testutil.make_app(MyRoot)
        response = app.get("/istrue?value=foo")
        assert response.raw['msg'] == 'Error Message'

        response = app.get("/save?submit=send&firstname=John&lastname=Doe")
        assert response.raw['fullname'] == "John Doe"
        assert response.raw['submit'] == "send"
        response = app.get("/save?submit=send&firstname=Arthur")
        assert response.raw['fullname'] == "Arthur Miller"
        response = app.get("/save?submit=send&firstname=Arthur&lastname=")
        assert response.raw['fullname'] == "Arthur "
        response = app.get("/save?submit=send&firstname=D&lastname=")
        assert len(response.raw['errors'].keys()) == 1
        assert response.raw['errors'].has_key("firstname")
        assert "characters" in response.raw['errors']["firstname"].lower()
        response = app.get("/save?submit=send&firstname=&lastname=")
        assert len(response.raw['errors'].keys()) == 1
        assert response.raw['errors'].has_key("firstname")
def test_cntrl_commit2():
    """A commit inside the controller is not rolled back by the exception."""
    app = make_app(MyRoot)
    response = app.get("/create_person?id=24&docom=1&doerr=1")
    assert 'InvalidRequestError' not in response
    assert session.query(Person).get(24) is not None, \
        'The Person 24 should have been saved during commit' \
        ' inside controller and not rolled back'
 def setUp(self):
     testutil.stop_server(tg_only = True)
     self._visit_on = config.get('tools.visit.on', False)
     self._visit_source = config.get('tools.visit.source', 'cookie')
     config.update({'tools.visit.on': True})
     self._visit_timeout = config.get('tools.visit.timeout', 20)
     config.update({'tools.visit.timeout': 50})
     self.cookie_name = config.get("tools.visit.cookie.name", 'tg-visit')
     self._visit_key_param = config.get("tools.visit.form.name", 'tg_visit')
     self.app = testutil.make_app(VisitRoot)
     testutil.start_server()
def test_exc_rollback2():
    """An exception within a controller method causes a rollback.

    Try to create a user that should rollback because of an exception
    so user XX should not exist.

    """
    app = make_app(RbRoot)
    response = app.get('/doerr?id=XX')
    assert 'KARL27' in response, 'Exception handler should have answered'
    assert session.query(User).get('XX') is None
def test_cntrl_flush():
    """It's safe to flush in the controller."""
    app = make_app(MyRoot)
    response = app.get("/create_person?id=25&doflush=1")
    assert 'No exceptions occurred' in response
    response = app.get("/create_person?id=25&doflush=0", status=500)
    assert 'IntegrityError' in response
    response = app.get("/create_person?id=25&doflush=1")
    assert 'IntegrityError' in response
    response = app.get("/create_person?id=25&doflush=2")
    assert 'No exceptions occurred' in response
def test_user_exception():
    """If a controller raises an exception, transactions are rolled back."""
    capture_log("gearshift.database")
    app = make_app(MyRoot)
    response = app.get("/create_person?id=19&docom=0&doerr=1&name=Martin%20GAL")
    print_log()
    assert 'KARL25' in response, \
        'The exception handler should have answered us'
    p = session.query(Person).get(19)
    assert p is None, \
        'This Person should have been rolled back: %s' % p
Exemple #10
0
 def setUp(self):
     testutil.stop_server(tg_only=True)
     self._visit_on = config.get('tools.visit.on', False)
     self._visit_source = config.get('tools.visit.source', 'cookie')
     config.update({'tools.visit.on': True})
     self._visit_timeout = config.get('tools.visit.timeout', 20)
     config.update({'tools.visit.timeout': 50})
     self.cookie_name = config.get("tools.visit.cookie.name", 'tg-visit')
     self._visit_key_param = config.get("tools.visit.form.name", 'tg_visit')
     self.app = testutil.make_app(VisitRoot)
     testutil.start_server()
def test_raise_sa_exception():
    """If a controller causes an SA exception, it is raised properly."""
    capture_log("gearshift.database")
    app = make_app(MyRoot)
    response = app.get("/create_person?id=20")
    print_log()
    assert 'No exceptions occurred' in response
    response = app.get("/create_person?id=20", status=500)
    assert 'KARL25' not in response, \
        'Exception should NOT have been handled by our handler'
    assert 'DBAPIError' in response, \
        'The page should have displayed an SQLAlchemy exception'
def test_implicit_trans_no_error():
    """If a controller runs sucessfully, the transaction is commited."""
    capture_log("gearshift.database")
    app = make_app(MyRoot)
    response = app.get("/no_error?name=A.%20Dent")
    print_log()
    q = session.query(Person)
    arthur = q.filter_by(name="A. Dent").first()
    assert 'someconfirmhandler' in response, \
        'The no error should have redirected to someconfirmhandler'
    assert arthur is not None, 'Person arthur should have been saved!'
    assert arthur.name == "A. Dent", 'Person arthur should be named "A. Dent"'
 def test_allow_json_config(self):
     """JSON output can be enabled via config."""
     config.update({'tg.allow_json':True})
     class JSONRoot(controllers.RootController):
         @expose(template="gearshift.tests.simple")
         def allowjsonconfig(self):
             return dict(title="Foobar", mybool=False, someval="foo",
                  tg_template="gearshift.tests.simple")
     app = testutil.make_app(JSONRoot)
     response = app.get('/allowjsonconfig?tg_format=json')
     assert response.headers["Content-Type"] == "application/json"
     config.update({'tg.allow_json': False})
def test_exc_rollback():
    """An exception within a controller method causes a rollback.

    Try to create a user that should rollback because of an exception
    so user 25 should not exist, but user 26 should be present since it
    is created by the exception handler.

    """
    app = make_app(RbRoot)
    response = app.get('/doerr?id=26')
    assert 'KARL27' in response, 'Exception handler should have answered'
    assert session.query(User).get(26) is None
    assert session.query(User).get(27) is not None
 def test_allow_json_config_false(self):
     """Make sure JSON can still be restricted with a global config on."""
     config.update({'tg.allow_json': False})
     class JSONRoot(controllers.RootController):
         @expose(template="gearshift.tests.simple")
         def allowjsonconfig(self):
             return dict(title="Foobar", mybool=False, someval="foo",
                  tg_template="gearshift.tests.simple")
     testutil.stop_server()
     app = testutil.make_app(JSONRoot)
     testutil.start_server()
     response = app.get('/allowjsonconfig')
     response = app.get('/allowjsonconfig?tg_format=json', status=500)
     assert response.headers["Content-Type"] == "text/html"
     config.update({'tg.allow_json': True})
Exemple #16
0
    def test_allow_json_config(self):
        """JSON output can be enabled via config."""
        config.update({'tg.allow_json': True})

        class JSONRoot(controllers.RootController):
            @expose(template="gearshift.tests.simple")
            def allowjsonconfig(self):
                return dict(title="Foobar",
                            mybool=False,
                            someval="foo",
                            tg_template="gearshift.tests.simple")

        app = testutil.make_app(JSONRoot)
        response = app.get('/allowjsonconfig?tg_format=json')
        assert response.headers["Content-Type"] == "application/json"
        config.update({'tg.allow_json': False})
Exemple #17
0
 def test_visit_from_form_with_cookie_fallback(self):
     """Test if visit key is retrieved from cookie if not found in params."""
     _app = self.app
     try:
         testutil.stop_server(tg_only=True)
         config.update({'tools.visit.source': 'form,cookie'})
         _app = testutil.make_app(VisitRoot)
         testutil.start_server()
         # first visit's cookie
         print self.app.get("/")
         first_key = self.app.get("/").raw.get('key')
         # second request with no params
         response = self.app.get("/")
     finally:
         config.update({'tools.visit.source': self._visit_source})
         self.app = _app
     assert first_key == response.raw['key']
 def test_visit_from_form_with_cookie_fallback(self):
     """Test if visit key is retrieved from cookie if not found in params."""
     _app = self.app
     try:
         testutil.stop_server(tg_only = True)
         config.update({'tools.visit.source': 'form,cookie'})
         _app = testutil.make_app(VisitRoot)
         testutil.start_server()
         # first visit's cookie
         print self.app.get("/")
         first_key = self.app.get("/").raw.get('key')
         # second request with no params
         response = self.app.get("/")
     finally:
         config.update({'tools.visit.source': self._visit_source})
         self.app = _app
     assert first_key == response.raw['key']
 def test_visit_from_form(self):
     """Test if the visit key is retrieved from the request params."""
     _app = self.app
     try:
         testutil.stop_server(tg_only = True)
         config.update({'tools.visit.source': 'cookie,form'})
         self.app = testutil.make_app(VisitRoot)
         testutil.start_server()
         # first visit's cookie
         first_key = self.app.get("/").raw.get('key')
         # second request with no cookies
         self.app.cookies = {}
         response = self.app.get("/",
             params={self._visit_key_param: first_key})
     finally:
         config.update({'tools.visit.source': self._visit_source})
         self.app = _app
     assert first_key == response.raw['key']
Exemple #20
0
 def test_visit_from_form(self):
     """Test if the visit key is retrieved from the request params."""
     _app = self.app
     try:
         testutil.stop_server(tg_only=True)
         config.update({'tools.visit.source': 'cookie,form'})
         self.app = testutil.make_app(VisitRoot)
         testutil.start_server()
         # first visit's cookie
         first_key = self.app.get("/").raw.get('key')
         # second request with no cookies
         self.app.cookies = {}
         response = self.app.get("/",
                                 params={self._visit_key_param: first_key})
     finally:
         config.update({'tools.visit.source': self._visit_source})
         self.app = _app
     assert first_key == response.raw['key']
Exemple #21
0
    def test_allow_json_config_false(self):
        """Make sure JSON can still be restricted with a global config on."""
        config.update({'tg.allow_json': False})

        class JSONRoot(controllers.RootController):
            @expose(template="gearshift.tests.simple")
            def allowjsonconfig(self):
                return dict(title="Foobar",
                            mybool=False,
                            someval="foo",
                            tg_template="gearshift.tests.simple")

        testutil.stop_server()
        app = testutil.make_app(JSONRoot)
        testutil.start_server()
        response = app.get('/allowjsonconfig')
        response = app.get('/allowjsonconfig?tg_format=json', status=500)
        assert response.headers["Content-Type"] == "text/html"
        config.update({'tg.allow_json': True})
 def test_cookie_permanent(self):
     """Check that the visit cookie can be made permanent."""
     permanent = config.get('tools.visit.cookie.permanent', False)
     try:
         # set cookie permanent for this test only (needs restart)
         testutil.stop_server(tg_only = False)
         config.update({'tools.visit.cookie.permanent': True})
         app = testutil.make_app(VisitRoot)
         testutil.start_server()
         response = app.get('/')
         cookies = SimpleCookie(response.headers['Set-Cookie'])
         morsel = cookies[self.cookie_name]
     finally:
         config.update({'tools.visit.cookie.permanent': permanent})
     assert morsel['max-age'] == '3000'
     expires = time.mktime(time.strptime(morsel['expires'],
         '%a, %d-%b-%Y %H:%M:%S GMT')[:8] + (0,))
     should_expire = time.mktime(time.gmtime()) + int(morsel['max-age'])
     assert abs(should_expire - expires) < 3, (should_expire, expires, should_expire - expires)
def test_allow_json():

    class NewRoot(controllers.RootController):
        _cp_config = { "tools.flash.on" : True }
        
        @expose(template="gearshift.tests.doesnotexist", allow_json=True)
        def test(self):
            return dict(title="Foobar", mybool=False, someval="niggles")

    app = make_app(NewRoot)
    response = app.get("/test", headers= dict(accept="application/json"))
    values = simplejson.loads(response.body)
    assert values == dict(title="Foobar", mybool=False, someval="niggles",
        tg_flash=None)
    assert response.headers["Content-Type"] == "application/json"
    response = app.get("/test?tg_format=json")
    values = simplejson.loads(response.body)
    assert values == dict(title="Foobar", mybool=False, someval="niggles",
        tg_flash=None)
    assert response.headers["Content-Type"] == "application/json"
def test_session_freshness():
    """Check for session freshness.

    Changes made to the data in thread B should be reflected in thread A.

    """
    test_table.insert().execute(dict(id=1, val='a'))
    app = make_app(FreshRoot)
    response = app.get("/test1", status = 200)
    assert 'AssertionError' not in response
    # Call test2 in a different thread
    class ThreadB(threading.Thread):
        def run(self):
            response = app.get("/test2", status=200)
            assert 'AssertionError' not in response
    thrdb = ThreadB()
    thrdb.start()
    thrdb.join()
    response = app.get("/test3", status=200)
    assert 'AssertionError' not in response
Exemple #25
0
 def test_cookie_permanent(self):
     """Check that the visit cookie can be made permanent."""
     permanent = config.get('tools.visit.cookie.permanent', False)
     try:
         # set cookie permanent for this test only (needs restart)
         testutil.stop_server(tg_only=False)
         config.update({'tools.visit.cookie.permanent': True})
         app = testutil.make_app(VisitRoot)
         testutil.start_server()
         response = app.get('/')
         cookies = SimpleCookie(response.headers['Set-Cookie'])
         morsel = cookies[self.cookie_name]
     finally:
         config.update({'tools.visit.cookie.permanent': permanent})
     assert morsel['max-age'] == '3000'
     expires = time.mktime(
         time.strptime(morsel['expires'], '%a, %d-%b-%Y %H:%M:%S GMT')[:8] +
         (0, ))
     should_expire = time.mktime(time.gmtime()) + int(morsel['max-age'])
     assert abs(should_expire - expires) < 3, (should_expire, expires,
                                               should_expire - expires)
 def test_cookie_expires(self):
     """Test if the visit timeout mechanism works."""
     timeout = config.get('tools.visit.timeout', 50)
     _app = self.app
     try:
         # set expiration to one second for this test only
         testutil.stop_server(tg_only = True)
         config.update({'tools.visit.timeout': 1.0/60})
         self.app = testutil.make_app(VisitRoot)
         testutil.start_server()
         response = self.app.get("/")
         morsel = response.cookies_set[self.cookie_name]
         time.sleep(2) # 2 seconds
         response = self.app.get("/", headers=cookie_header(response))
     finally:
         config.update({'tools.visit.timeout': timeout})
         self.app = _app
     assert response.cookies_set[
             self.cookie_name] != morsel, \
         'cookie values should not match'
     assert response.raw['new'], \
         'this should be a new visit, as the cookie has expired'
Exemple #27
0
 def test_cookie_expires(self):
     """Test if the visit timeout mechanism works."""
     timeout = config.get('tools.visit.timeout', 50)
     _app = self.app
     try:
         # set expiration to one second for this test only
         testutil.stop_server(tg_only=True)
         config.update({'tools.visit.timeout': 1.0 / 60})
         self.app = testutil.make_app(VisitRoot)
         testutil.start_server()
         response = self.app.get("/")
         morsel = response.cookies_set[self.cookie_name]
         time.sleep(2)  # 2 seconds
         response = self.app.get("/", headers=cookie_header(response))
     finally:
         config.update({'tools.visit.timeout': timeout})
         self.app = _app
     assert response.cookies_set[
             self.cookie_name] != morsel, \
         'cookie values should not match'
     assert response.raw['new'], \
         'this should be a new visit, as the cookie has expired'
def test_allow_json():
    class NewRoot(controllers.RootController):
        _cp_config = {"tools.flash.on": True}

        @expose(template="gearshift.tests.doesnotexist", allow_json=True)
        def test(self):
            return dict(title="Foobar", mybool=False, someval="niggles")

    app = make_app(NewRoot)
    response = app.get("/test", headers=dict(accept="application/json"))
    values = simplejson.loads(response.body)
    assert values == dict(title="Foobar",
                          mybool=False,
                          someval="niggles",
                          tg_flash=None)
    assert response.headers["Content-Type"] == "application/json"
    response = app.get("/test?tg_format=json")
    values = simplejson.loads(response.body)
    assert values == dict(title="Foobar",
                          mybool=False,
                          someval="niggles",
                          tg_flash=None)
    assert response.headers["Content-Type"] == "application/json"
def test_user_redirect():
    """If a controller redirects, transactions are committed."""
    app = make_app(MyRoot)
    app.get("/create_person?id=22&doerr=2")
    assert session.query(Person).get(22) is not None, \
        'The controller only redirected, the Person should have been saved'
def test_Rest_Dispatch():
    d = gearshift.dispatch.RestDispatcher()
    conf = {'/people': {'request.dispatch': d}}

    app = make_app(Root, conf=conf)
    
    response = app.get("/")
    assert response.status == "200 OK"

    # Get all people
    response = app.get("/people")
    assert response.status == "200 OK"
#    print response.body
    assert response.body == "GET People person_id=all"
    
    # Get person 345
    response = app.get("/people/345")
    assert response.status == "200 OK"
    assert response.body == "GET People person_id=345"

    # Get edit form for person 345
    response = app.get("/people/345/edit")
    assert response.status == "200 OK"
    assert response.body == "edit People person_id=345"
    
    # Get all phones for all people
    response = app.get("/people/phones")
    assert response.status == "200 OK"
    assert response.body == "GET Phones phone_id=all, person_id=all"

    # Get phone 5 for person 3
    response = app.get("/people/3/phones/5")
    assert response.status == "200 OK"
    assert response.body == "GET Phones phone_id=5, person_id=3"

    # Get phone 1 for person 1 (repeated value)
    response = app.get("/people/1/phones/1")
    assert response.status == "200 OK"
    assert response.body == "GET Phones phone_id=1, person_id=1"

    # Create a new phone for a person 4
    response = app.post("/people/4/phones/", dict(phone="new"))
    assert response.status == "201 Created"
    assert response.body == "POST Phones person_id=4, phone=new"

    # Update phone 3 for a person 4
    response = app.put("/people/4/phones/3", dict(phone="update"))
    assert response.status == "200 OK"
    assert response.body == "PUT Phones phone_id=3, person_id=4, phone=update"

    # Update phone 3 for a person 4
    response = app.post("/people/4/phones/3?_method=PUT", dict(phone="update"))
    assert response.status == "200 OK"
    assert response.body == "PUT Phones phone_id=3, person_id=4, phone=update"

    # Get all ringtones for all phones for all people
    response = app.get("/people/phones/ringtones")
    assert response.status == "200 OK"
    assert response.body == "GET Ringtones phone_id=all, person_id=all"

    # Get all ringtones for phone 5
    response = app.get("/people/phones/5/ringtones")
    assert response.status == "200 OK"
    assert response.body == "GET Ringtones phone_id=5, person_id=all"

    # Get all ringtones for all phones for a person 3
    response = app.get("/people/3/phones/ringtones")
    assert response.status == "200 OK"
    assert response.body == "GET Ringtones phone_id=all, person_id=3"

    # Get ringtone 4 for phone 45 for a person 3
    response = app.get("/people/3/phones/45/ringtones/4")
    assert response.status == "200 OK"
    assert response.body == "GET Ringtone ringtone_id=4, phone_id=45, " \
                       "person_id=3"

    # Should not exist
    response = app.get("/phones/2", status=404)

    # Should not exist
    response = app.get("/phones/2/people/3", status=404)

    # Request JSON using .json
    response = app.put("/people/2.json")
    assert response.body == "PUT People person_id=2, format=json"
        "baz": validators.Int(not_empty=True)},
              failsafe_schema=FailsafeSchema.defaults)
    def failsafedefaults(self, tg_errors=None, bar=1, baz=2):
        return dict(title="Failsafe map defaults", bar=bar, baz=baz)


class NestedController(Controller):

    @expose()
    @validate(validators={"bar": validators.Int(not_empty=True)})
    @error_handler()
    def nest(self, bar=""):
        return dict(title="Nested")


app = testutil.make_app()

class TestErrorHandler(unittest.TestCase):

    def test_defaultErrorHandler(self):
        """Default error handler."""
        response = app.get("/defaulterror?bar=abc")
        self.failUnless("Default error handler" in response)
        response = app.get("/defaulterror?bar=true")
        self.failUnless("Default error provider" in response)

    def test_specialisedErrorHandler(self):
        """Error handler specialisation."""
        response = app.get("/specialisederror?bar=abc&[email protected]")
        self.failUnless("Default error handler" in response)
        response = app.get("/specialisederror?baz=abc&bar=1")
def test_getting_json_with_accept_but_using_tg_format():
    app = make_app(ExposeRoot)
    response = app.get("/with_json_via_accept?tg_format=json")
    assert '"title": "Foobar"' in response
def test_getting_plaintext():
    app = make_app(ExposeRoot)
    response = app.get("/with_json_via_accept",
                       headers=dict(Accept="text/plain"))
    assert response.body == "This is a plain text for foo."
def test_gettingjson():
    app = make_app(ExposeRoot)
    response = app.get("/with_json?tg_format=json")
    assert '"title": "Foobar"' in response
def test_gettingjsonviaaccept():
    app = make_app(ExposeRoot)
    response = app.get("/with_json_via_accept",
                       headers=dict(Accept="application/json"))
    assert '"title": "Foobar"' in response
def test_gettinghtml():
    app = make_app(ExposeRoot)
    response = app.get("/with_json")
    assert "Paging all foo" in response
def test_getting_json_with_accept_but_using_tg_format():
    app = make_app(ExposeRoot)
    response = app.get("/with_json_via_accept?tg_format=json")
    assert '"title": "Foobar"' in response
def test_getting_plaintext():
    app = make_app(ExposeRoot)
    response = app.get("/with_json_via_accept",
        headers=dict(Accept="text/plain"))
    assert response.body == "This is a plain text for foo."
def test_gettingjson():
    app = make_app(ExposeRoot)
    response = app.get("/with_json?tg_format=json")
    assert '"title": "Foobar"' in response
def test_gettinghtml():
    app = make_app(ExposeRoot)
    response = app.get("/with_json")
    assert "Paging all foo" in response
 def setUp(self):
     testutil.mount(MyRoot(), '/')
     testutil.mount(SubApp(), '/subthing')
     testutil.mount(SubApp(), '/subthing/subsubthing')
     self.app = testutil.make_app()
     super(TestURLs, self).setUp()
Exemple #42
0
 def setUp(self):
     testutil.mount(MyRoot(), '/')
     testutil.mount(SubApp(), '/subthing')
     testutil.mount(SubApp(), '/subthing/subsubthing')
     self.app = testutil.make_app()
     super(TestURLs, self).setUp()
def test_Rest_Dispatch():
    d = gearshift.dispatch.RestDispatcher()
    conf = {'/people': {'request.dispatch': d}}

    app = make_app(Root, conf=conf)

    response = app.get("/")
    assert response.status == "200 OK"

    # Get all people
    response = app.get("/people")
    assert response.status == "200 OK"
    #    print response.body
    assert response.body == "GET People person_id=all"

    # Get person 345
    response = app.get("/people/345")
    assert response.status == "200 OK"
    assert response.body == "GET People person_id=345"

    # Get edit form for person 345
    response = app.get("/people/345/edit")
    assert response.status == "200 OK"
    assert response.body == "edit People person_id=345"

    # Get all phones for all people
    response = app.get("/people/phones")
    assert response.status == "200 OK"
    assert response.body == "GET Phones phone_id=all, person_id=all"

    # Get phone 5 for person 3
    response = app.get("/people/3/phones/5")
    assert response.status == "200 OK"
    assert response.body == "GET Phones phone_id=5, person_id=3"

    # Get phone 1 for person 1 (repeated value)
    response = app.get("/people/1/phones/1")
    assert response.status == "200 OK"
    assert response.body == "GET Phones phone_id=1, person_id=1"

    # Create a new phone for a person 4
    response = app.post("/people/4/phones/", dict(phone="new"))
    assert response.status == "201 Created"
    assert response.body == "POST Phones person_id=4, phone=new"

    # Update phone 3 for a person 4
    response = app.put("/people/4/phones/3", dict(phone="update"))
    assert response.status == "200 OK"
    assert response.body == "PUT Phones phone_id=3, person_id=4, phone=update"

    # Update phone 3 for a person 4
    response = app.post("/people/4/phones/3?_method=PUT", dict(phone="update"))
    assert response.status == "200 OK"
    assert response.body == "PUT Phones phone_id=3, person_id=4, phone=update"

    # Get all ringtones for all phones for all people
    response = app.get("/people/phones/ringtones")
    assert response.status == "200 OK"
    assert response.body == "GET Ringtones phone_id=all, person_id=all"

    # Get all ringtones for phone 5
    response = app.get("/people/phones/5/ringtones")
    assert response.status == "200 OK"
    assert response.body == "GET Ringtones phone_id=5, person_id=all"

    # Get all ringtones for all phones for a person 3
    response = app.get("/people/3/phones/ringtones")
    assert response.status == "200 OK"
    assert response.body == "GET Ringtones phone_id=all, person_id=3"

    # Get ringtone 4 for phone 45 for a person 3
    response = app.get("/people/3/phones/45/ringtones/4")
    assert response.status == "200 OK"
    assert response.body == "GET Ringtone ringtone_id=4, phone_id=45, " \
                       "person_id=3"

    # Should not exist
    response = app.get("/phones/2", status=404)

    # Should not exist
    response = app.get("/phones/2/people/3", status=404)

    # Request JSON using .json
    response = app.put("/people/2.json")
    assert response.body == "PUT People person_id=2, format=json"
def test_gettingjsonviaaccept():
    app = make_app(ExposeRoot)
    response = app.get("/with_json_via_accept",
            headers=dict(Accept="application/json"))
    assert '"title": "Foobar"' in response