3

I'm testing my Flask application using FlaskClient, in order to avoid to run a Flask server always when I'm testing my application.

I've created a 'sign_in' view that returns an 'Authorization' header with a encrypted token when the user logs successfully in my front-end.

This view works normally in a normal environment, it returns the 'Authorization' header correctly, however when I'm testing this view, inside the test environment, it does not return the 'Authorization' header. The view returns None in 'Authorization' header.

I've already tried some solutions on the internet, such as to add self.app.config['TESTING'] = True in my test case, but the terminal raises an error 'FlaskClient' object has no attribute 'config' that I've already tried to look for a solution, but without success.

I would like to know what may be happening.

Does anyone know any solution for this question?

I send my code below for analysis.

Thank you in advance.

view.py

@app.route("/sign_in", methods = ["POST"])
def sign_in():
    ...

    username, password = ...

    try:
        encoded_jwt_token = auth_login(username, password)
    except UserDoesNotExistException as error:
        return str(error), error.status_code

    resp = Response("Returned Token")
    resp.headers['Authorization'] = encoded_jwt_token

    return resp

test.py

class TestAPIAuthLogin(TestCase):

    def setUp(self):
        self.app = catalog_app.test_client()
        # self.app.config['TESTING'] = True  # config does not exist

    def test_get_api_auth_login_user_test(self):
        username = "test"
        password = get_string_in_hash_sha512("test")
        authorization = 'Basic ' + get_string_in_base64(username + ":" + password)

        headers = {
            'Access-Control-Allow-Origin': '*',
            'Content-Type': 'application/json',
            'Authorization': authorization
        }

        response = self.app.get('/sign_in', headers=headers)
        # it returns None 
        authorization = response.headers.get("Authorization")

        self.assertIsNotNone(authorization)
        self.assertNotEqual(authorization, "")
rmmariano
  • 896
  • 1
  • 18
  • 32

3 Answers3

1

I believe this may be to do with the way HTTP requests process headers, where they capitalise them and add HTTP_ as a prefix. Try changing your header to HTTP_AUTHORIZATION instead of just Authorization, since the test client will not be setting this properly.

Jamie J
  • 1,168
  • 1
  • 9
  • 22
  • I tried to get this header instead of `Authorization`, however this tip did not work, unfortunately. I printed the list of headers that are returned and there is not an `HTTP_AUTHORIZATION` header, but there is an `Authorization` header that returns `None`. Thank you. – rmmariano Apr 15 '19 at 14:41
  • Ah sorry for being unclear, I meant you should add `HTTP_AUTHORIZATION` in the request header, so your request would be: `headers = { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json','HTTP_AUTHORIZATION': authorization}` – Jamie J Apr 15 '19 at 15:06
  • I tried to follow your tip, but it did not work yet. Thank you for your help. – rmmariano Apr 15 '19 at 16:35
  • Now I've figure out what was happening. I tried to describe in an answer. Thank you for your help Kathy. – rmmariano Apr 15 '19 at 16:54
0

I'm sorry guys for this silly question. Now I've figure the answer out. The problem was that I was trying to do a GET request in a view that is using a POST method.

I've just replaced the request from

response = self.app.get('/sign_in', headers=headers)

to

response = self.app.post('/sign_in', headers=headers)

and now it started to work.

I will let this question here in case of someone gets the same silly error.

Thank you so much.

rmmariano
  • 896
  • 1
  • 18
  • 32
0

If similar issue for DRF clients, You can use,

client = APIClient()
client.credentials(HTTP_AUTHORIZATION='Token {token}'.format(token=token))

Ref: https://www.django-rest-framework.org/api-guide/testing/#credentialskwargs

Sachin G.
  • 1,870
  • 19
  • 24