2012-12-19 11 views
6

Possiedo un'app Flask che utilizza Flask-Restless per servire un'API.Come posso testare questa app Flask?

ho appena scritto un po 'di autenticazione che controlla

  1. Se l'host consumatori è riconosciuto
  2. La richiesta include un hash (calcolato tramite la crittografia del contenuto di richiesta di POST e URL per andare d'accordo con un API segreto chiave) e
  3. l'hash è valida

voglio essere in grado di scrivere alcuni test di unità per questo, ma non sono sicuro di come perché le mie funzioni utilizzano la richiesta o bject. Dovrei prendere in giro l'oggetto della richiesta?

Mi piacerebbe qualche consiglio su questo.

Config

API_CONSUMERS = [{'name': 'localhost', 
        'host': '12.0.0.1:5000', 
        'api_key': 'Ahth2ea5Ohngoop5'}, 
       {'name': 'localhost2', 
        'host': '127.0.0.1:5001', 
        'api_key': 'Ahth2ea5Ohngoop6'}] 

metodi di autenticazione

import hashlib 
from flask import request 


def is_authenticated(app): 
    """ 
    Checks that the consumers host is valid, the request has a hash and the 
    hash is the same when we excrypt the data with that hosts api key 

    Arguments: 
    app -- instance of the application 
    """ 
    consumers = app.config.get('API_CONSUMERS') 
    host = request.host 

    try: 
     api_key = next(d['api_key'] for d in consumers if d['host'] == host) 
    except StopIteration: 
     app.logger.info('Authentication failed: Unknown Host (' + host + ')') 
     return False 

    if not request.headers.get('hash'): 
     app.logger.info('Authentication failed: Missing Hash (' + host + ')') 
     return False 

    if request.method == 'GET': 
     hash = calculate_hash_from_url(api_key) 
    elif request.method == 'POST': 
     hash = calculate_hash_from_content(api_key) 

    if hash != request.headers.get('hash'): 
     app.logger.info('Authentication failed: Hash Mismatch (' + host + ')') 
     return False 
    return True 


def calculate_hash_from_url(api_key): 
    """ 
    Calculates the hash using the url and that hosts api key 

    Arguments: 
    api_key -- api key for this host 
    """ 
    data_to_hash = request.base_url + '?' + request.query_string 
    data_to_hash += api_key 
    return hashlib.sha1(request_uri).hexdigest() 


def calculate_hash_from_content(api_key): 
    """ 
    Calculates the hash using the request data and that hosts api key 

    Arguments: 
    api_key -- api key for this host 
    """ 
    data_to_hash = request.data 
    data_to_hash += api_key 
    return hashlib.sha1(data_to_hash).hexdigest() 
+0

Hai guardato [Testing Flask Applications] (http://flask.pocoo.org/docs/testing/)? – sean

+1

Penso che tu usi test_request_object() http://flask.pocoo.org/docs/quickstart/#accessing-request-data – ninMonkey

+0

Ah, potresti essere su qualcosa di scimmia, grazie. –

risposta

11

test_request_object() ha fatto il trucco, grazie scimmia.

from flask import request 

with app.test_request_context('/hello', method='POST'): 
    # now you can do something with the request until the 
    # end of the with block, such as basic assertions: 
    assert request.path == '/hello' 
    assert request.method == 'POST' 
+1

Vuole pubblicare più del codice? È utile vedere come questo si inserisce nel contesto del framework di test unitario. – BoltzmannBrain

0

ho fatto una suite di test naso che ha testato la mia app Graffiti da solo chiamando il metodo e passando il segmento URL, il parametro del metodo . cioè .:

response = self.app.do_something("/item/1234567890") 
assert response.status_code == 200