-1

I am trying to test my flask-api, but im not being able to do this, because the endpoints require login.

I have a simple code:

import os
import requests
from dotenv import load_dotenv
load_dotenv()


ENDPOINT = os.getenv("ENDPOINT")

### - TESTING SALES ENDPOINT - ###
def test_get_all_sales():
    """Test the sales endpoint, where all sales are getted"""
    response = requests.get(f"http://localhost:5000/sales")
    print(response)
    assert response.status_code == 200

When I ran the tests with 'python -m pytest' (I'm using windows, I think in linux the cmd is different), I receive a forbidden error, because endpoint require login.

I am using flask session, where my frontend send a request to auth/login endpoint and a session in backend is stored and return a cookie to frontend store it. So, my auth works in this way. But how can I test these endpoints? Have a way to login, store a temporary cookie and use these endpoint? Or I need to setup something like a apikey in each endpoint when passed, doesnt require login?

My endpoint is like:

@sales.route('/')
@sales.route("/<filters>")
@login_required # abort and return 403.
def sales_list(filters=None): 
    sales = Sale.get_all_sales() // Sale is a model class, with crud methods (simple DAO)
    if sales:    
       return jsonify({'message': "sales fetched sucessfully.", 'data': sales}), 200
    return jsonify({'message': "sales cant be fetched.", 'data': None}), 400

By the way, i thought this is possible because POSTMAN can set cookies and I can make requests to login_required endpoints. So, I think I can do this in python manually too

vitxr
  • 30
  • 1
  • 7
  • Did you try to send a request to your login endpoint first and copy the returned cookie over to your next request? If that works you can even put the first call into a fixture that returns the cookie. And btw, you probably shouldn't test flask via requests. Use the flask test client ([link](https://flask.palletsprojects.com/en/2.2.x/testing/https://flask.palletsprojects.com/en/2.2.x/testing/)) – tilman151 Feb 22 '23 at 15:17
  • Yep, I can get the returned cookie in response headers, but I didnt know what is a fixture, I will search about it and try to implement what your said. Thanks :) – vitxr Feb 22 '23 at 15:20

1 Answers1

0

With the @tilman151 idea, I can figure it out how to set the session cookie.

With your backend setup, in the response of login route, headers should have cookie attached. So, you can store it with requests.Session()

Following, is my working code:

import os
import requests
import pytest
from dotenv import load_dotenv
load_dotenv()

# - Creating a session to keep the cookies - #
r = requests.Session()
ENDPOINT = os.getenv("ENDPOINT")

def login():
    data = { "email": "email-example@gmail.com", "password": "123" }
    response = r.post(f"{ENDPOINT}/auth/login", json=data)
    
    return response

### - TESTING SALES ENDPOINT - ###
def test_get_all_sales():
    """ Test the sales endpoint, where all sales are getted """
    login()
    cookies = { "session": r.cookies.get("session") }
 
    response = r.get(f"{ENDPOINT}/sales", cookies=cookies)
    print(response)
    
    assert response.status_code == 200

sources:

vitxr
  • 30
  • 1
  • 7