lundi 19 décembre 2016

How to automatically envoke context factory inside view tests with urldispatch

I have an existing Pyramid application that makes use of url dispatch. It has urls of the form '/kind1/{id1}/kind2/{id2}.../action'. So traversal sould have been ideal but it wasn't used.

In each view there is a function call that fetches the instance from the url. Eg there might be a call like thingy_instance = get_thingy_from_url(request)

Now I needed to add permissions to the views. So I added context factories to the route configuration stuff. Something like: config.add_route('thingy_action','/kind1/{id1}/kind2/{id2}.../action', factory='ThingyContext')

Now it would make sense for ThingyContext to fetch the thing, so that in the view itself I can do stuff like thingy_instance = request.context.thingy_instance, instead of thingy_instance = get_thingy_from_url(request)

This so far is pretty straight forward and doable. But it breaks all the unit tests that directly test the views because the request context doesn't get filled in.

eg, a test like so:

def test_thingy_action_scenario(self):
    stuff...
    x = thingy_action(request)

would give me an exception like:

Traceback (most recent call last):
  File "/home/sheena/Workspace/Waxed/waxed_backend/waxed_backend/concerns/accountable_basics/tests/view_tests.py", line 72, in test_alles
    self.assertRaises(UserNotFound,lambda:get_user(request))
  File "/usr/lib/python2.7/unittest/case.py", line 473, in assertRaises
    callableObj(*args, **kwargs)
  File "/home/sheena/Workspace/Waxed/waxed_backend/waxed_backend/concerns/accountable_basics/tests/view_tests.py", line 72, in <lambda>
    self.assertRaises(UserNotFound,lambda:get_user(request))
  File "/home/sheena/Workspace/Waxed/waxed_backend/waxed_backend/concerns/accountable_basics/views.py", line 69, in get_user
    oUser = request.context.oUser
AttributeError: 'NoneType' object has no attribute 'thingy_instance'

In short. In the tests request.context is None. But when accessing the views via their urls it all works fine.

eg: this kind of thing works with the new set up curl -X POST --header 'Accept: application/json' 'http://stuff/kind1/{id1}/kind2/{id2}.../action/'

So what's a graceful way of dealing with this? I want to use the context inside the view, and have the tests pass.

Aucun commentaire:

Enregistrer un commentaire