8

I am deploying a Flask app on IIS and using its Windows Authentication, which sets request.environ['REMOTE_USER'] to your windows username if authenticated successfully. Now when writing test cases, how do I fake request.environ['REMOTE_USER']? The test cases are run independent of the IIS server.

My attempt:

from flask import request

def test_insert_cash_flow_through_post(self):
    """Test that you can insert a cash flow through post."""
    request.environ['REMOTE_USER'] = 'foo'
    self.client.post("/index?account=main",
                     data=dict(settlement_date='01/01/2016',
                               transaction_type='Other',
                               certainty='Certain',
                               transaction_amount=1))
    assert CashFlow.query.first().user == 'foo'

The part of my view that handles 'REMOTE_USER' is something like:

cf = CashFlow(...,
              user=request.environ.get('REMOTE_USER'),
              ...)
db.session.add(cf)
allenlin1992
  • 1,920
  • 3
  • 16
  • 28
  • I looked everywhere to see where the Authorized User login name is stored. I don't see it in the Flask docs. Glad to see it here. – Ari Apr 13 '16 at 21:30

2 Answers2

8

Figured out the answer to my own question from Setting (mocking) request headers for Flask app unit test. There is an environ_base parameter that you can pass request environment variables into. It is documented in werkzeug.test.EnvironBuilder.

    def test_insert_cash_flow_through_post(self):
    """Test that you can insert a cash flow through post."""
    assert not CashFlow.query.first()
    self.client.post("/index?account=main",
                     environ_base={'REMOTE_USER': 'foo'},
                     data=dict(settlement_date='01/01/2016',
                               transaction_type='Other',
                               certainty='Certain',
                               transaction_amount=1))
    assert CashFlow.query.first().user == 'foo'
jerrykan
  • 1,076
  • 9
  • 12
allenlin1992
  • 1,920
  • 3
  • 16
  • 28
2

You don't have to fake it. You can set it in your test.

from flask import request

def test_something():
    request.environ['REMOTE_USER'] = 'some user'
    do_something_with_remote_user()
    del request.environ['REMOTE_USER']

If you're worried about preserving any value that may already have been set, you can easily do that, too.

def test_something():
    original_remote_user = request.environ.get('REMOTE_USER')
    do_something_with_remote_user()
    request.environ['REMOTE_USER'] = original_remote_user

You can also handle this at a higher scope, but without knowing how your tests are structured, it's hard to tell you how to do that.

dirn
  • 19,454
  • 5
  • 69
  • 74
  • Thanks for your reply but request.environ is different than os.environ. WSGI provides all the data in request.environ. I think I need to figure out a way to modify request.environ. – allenlin1992 Dec 22 '15 at 16:04
  • Sorry, that was a brain fart. It should work the same way, though. – dirn Dec 22 '15 at 16:13
  • Nevermind, got it to work with 'environ_base' parameter. Thanks for trying. – allenlin1992 Dec 22 '15 at 16:35