miércoles, 1 de junio de 2016

Testeando ruta PUT en Pyramid

Sigo con mi aplicación que simula ser una API REST. Estoy haciendo cambios sobre la marcha y me quedé estancado en el verbo PUT. Se supone que el controlador asociado a dicho verbo debería ser de la siguiente forma:
@view_config(route_name='put_ficheros_modificacion', renderer='json')
def put_ficheros_modificacion(request):
    usuario = request.matchdict['fichero']
    data = request.POST.get('data')
    ficheros = Ficheros()
    modificacion_fichero = ficheros.modificacion(usuario, data)
    return {'ficheroModificacion': modificacion_fichero}
Y la prueba unitaria correspondiente debe usar un Request y no un DummyRequest
def test_put_ficheros_modificacion(self):
        from .views.actividades import put_ficheros_modificacion
        from pyramid.request import Request
        fixture = self.fixture['put_ficheros_modificacion']

        parametros = {'data':fixture['data']}
        peticion = Request.blank('', {}, POST=parametros)       
        peticion.matchdict = {'fichero':'fcornejo'}

        respuesta = put_ficheros_modificacion(peticion)
        self.assertEqual(respuesta['ficheroModificacion']['palabras'], fixture['data']['palabras'])

Básicamente sirve. Sin embargo, de esta forma, lo que se envía es un parámetro data que contiene por contenido al diccionario que guardo en mi fixture pero como texto. Así que tengo un error como el siguiente:
$ nosetests
....E
======================================================================
ERROR: test_put_ficheros_modificacion (aplicacion.tests.ViewTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/var/www/ambiente/aplicacion/aplicacion/tests.py", line 81, in test_put_ficheros_modificacion
    self.assertEqual(respuesta['ficheroModificacion']['palabras'], fixture['data']['palabras'])
TypeError: string indices must be integers
Precisamente porque la respuesta que estoy recibiendo en respuesta por parte de la aplicación es texto. Pues que esto se solucionaría cuidando un poco más los parámetros POST, básicamente creo que soportaría con el diccionario. Pero, eso haría que tuviera que hacer un request.POST.get() por cada clave. Que sería una buena idea para validar datos en el controlador, aunque supongo que habrá después otra forma

Total que mi gran solución es que el cliente envíe todo como json. Pues sí, creo que es la mejor idea posible. El controlador asociado queda de la siguiente forma:
@view_config(route_name='put_ficheros_modificacion', renderer='json')
def put_ficheros_modificacion(request):
    usuario = request.matchdict['fichero']
    data = request.json_body['data']
    ficheros = Ficheros()
    modificacion_fichero = ficheros.modificacion(usuario, data)
    return {'ficheroModificacion': modificacion_fichero}
Tampoco el test unitario ha cambiado tanto, excepto por configurar body en lugar de POST
    def test_put_ficheros_modificacion(self):
        from .views.actividades import put_ficheros_modificacion
        from pyramid.request import Request
        import json
        fixture = self.fixture['put_ficheros_modificacion']


        parametros = json.dumps({'data':fixture['data']})
        peticion = Request.blank('', {}, body=parametros)  
        peticion.matchdict = {'fichero':fixture['usuario']}

        respuesta = put_ficheros_modificacion(peticion)
        self.assertEqual(respuesta['ficheroModificacion']['palabras'], fixture['data']['palabras'])
Así que ahora el cliente debe enviar datos JSON. Lo que es mantiene todo simple y divertido a la hora de usar curl Supongo que eso abre la necesidad de validar el formato y cosas por el estilo, pero eso vendrá después. Y

Fuentes:
pyramid.request
Request and Response Objects

No hay comentarios:

Publicar un comentario

Otros apuntes interesantes

Otros apuntes interesantes