Skip to content

Commit

Permalink
Adding More Tests
Browse files Browse the repository at this point in the history
To Fix last 4 tests in app_login.feature
  • Loading branch information
TheManWhoLikesToCode committed Jan 23, 2024
1 parent ed6a082 commit 83e88c7
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 28 deletions.
9 changes: 7 additions & 2 deletions backend/app.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from functools import wraps
from json import JSONDecodeError
import logging
import os
import threading
Expand Down Expand Up @@ -71,7 +72,11 @@ def index():
@app.route('/login', methods=['POST'])
@cross_origin(supports_credentials=True)
def login():
data = request.json
try:
data = request.get_json()
except JSONDecodeError:
return jsonify({'error': 'Invalid JSON format'}), 400

username = data.get('username')
password = data.get('password')

Expand All @@ -89,7 +94,7 @@ def login():
bb_session_manager.put_bb_session(username, bb_session)

resp = make_response(
jsonify({'message': 'Logged in successfully'}))
jsonify({'message': 'Logged in successfully'}), 200)
resp.set_cookie('user_session', bb_session.session_id,
max_age=3600, secure=True, httponly=True)
return resp
Expand Down
58 changes: 48 additions & 10 deletions backend/features/app_login.feature
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,60 @@ Feature: Backend Flask App - Login
As a system
I want users to have to login

Scenario: Successful Login
Given App is running
When I pass valid credentials to the login endpoint
Then The response of "200" and "Logged in Successfully" should be returned
Scenario: Successful Login
Given the app is running
When I pass valid credentials to the login endpoint
Then the response of "200" and "Logged in successfully" should be returned
And cookies should be set

Scenario: Unsuccessful Login - Incorrect username and password
Given App is running
Given the app is running
When I pass an incorrect username and password to the login endpoint
Then The response of "401" and "The username you entered cannot be identified." should be returned
Then the response of "401" and "The username you entered cannot be identified." should be returned

Scenario: Unsuccessful Login - Incorrect password
Given App is running
Given the app is running
When I pass an incorrect password to the login endpoint
Then The response of "401" and "The password you entered was incorrect." should be returned
Then the response of "401" and "The password you entered was incorrect." should be returned

Scenario: Unsuccessful Login - Incorrect username
Given App is running
Given the app is running
When I pass an incorrect username to the login endpoint
Then The response of "401" and "The username you entered cannot be identified." should be returned
Then the response of "401" and "The username you entered cannot be identified." should be returned

Scenario: Unsuccessful Login - Missing password
Given the app is running
When I pass only a username to the login endpoint
Then the response of "400" and "Missing username or password" should be returned

Scenario: Unsuccessful Login - Missing username
Given the app is running
When I pass only a password to the login endpoint
Then the response of "400" and "Missing username or password" should be returned

Scenario: Unsuccessful Login - Missing username and password
Given the app is running
When I pass no credentials to the login endpoint
Then the response of "400" and "Missing username or password" should be returned

Scenario: Unsuccessful Login - Invalid JSON Format in Request
Given the app is running
When I pass data in an invalid JSON format to the login endpoint
Then the response of "400" and "Invalid request format" should be returned

Scenario: Server Error During Login Process
Given the app is running
When I pass valid credentials but the server encounters an internal error during login
Then the response of "500" and the specific error message should be returned

Scenario: Already Logged In
Given the app is running
And the user is already logged in
When I pass valid credentials to the login endpoint again
Then the response of "200" and "Already logged in" should be returned

Scenario: Session Cookie Attributes Verification
Given the app is running
When I pass valid credentials to the login endpoint
Then the response should include a 'Set-Cookie' header with 'user_session' cookie
And the cookie should have 'HttpOnly' and 'Secure' attributes set
103 changes: 87 additions & 16 deletions backend/features/steps/all_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ def step_impl(context, session_id, user1, user2):

@given('I have valid credentials')
def step_impl(context):
context.username = os.getenv('TEST_USERNAME')
context.password = os.getenv('TEST_PASSWORD')
context.username = os.environ.get('TEST_USERNAME')
context.password = os.environ.get('TEST_PASSWORD')
context.session = BlackboardSession(
username=context.username, password=context.password)

Expand All @@ -92,7 +92,7 @@ def step_impl(context):
username='InvalidUsername', password='InvalidPassword')
context.logged_in = context.session.is_logged_in

@given('App is running')
@given('the app is running')
def step_impl(context):
assert context.client

Expand Down Expand Up @@ -216,8 +216,8 @@ def step_impl(context):
@when('I pass valid credentials to the login endpoint')
def step_impl(context):
context.page = context.client.post('/login', json=dict(
username=os.getenv('TEST_USERNAME'),
password=os.getenv('TEST_PASSWORD')
username=os.environ.get('TEST_USERNAME'),
password=os.environ.get('TEST_PASSWORD')
), headers={'Content-Type': 'application/json'}, follow_redirects=True)
response = context.page.get_json()
assert response['message'] == 'Logged in successfully'
Expand All @@ -244,11 +244,62 @@ def step_impl(context):
def step_impl(context):
context.page = context.client.post('/login', json=dict(
username='InvalidUsername',
password=os.getenv('TEST_PASSWORD')
password=os.environ.get('TEST_PASSWORD')
), headers={'Content-Type': 'application/json'}, follow_redirects=True)
response = context.page.get_json()
assert response['error'] == 'The username you entered cannot be identified.'

@when('I pass only a username to the login endpoint')
def step_impl(context):
context.page = context.client.post('/login', json=dict(
username='InvalidUsername',
password=''
), headers={'Content-Type': 'application/json'}, follow_redirects=True)
response = context.page.get_json()
assert response['error'] == 'Missing username or password'

@when('I pass only a password to the login endpoint')
def step_impl(context):
context.page = context.client.post('/login', json=dict(
username='',
password='InvalidPassword'
), headers={'Content-Type': 'application/json'}, follow_redirects=True)
response = context.page.get_json()
assert response['error'] == 'Missing username or password'

@when('I pass no credentials to the login endpoint')
def step_impl(context):
context.page = context.client.post('/login', json=dict(
username='',
password=''
), headers={'Content-Type': 'application/json'}, follow_redirects=True)
response = context.page.get_json()
assert response['error'] == 'Missing username or password'

@when('I pass data in an invalid JSON format to the login endpoint')
def step_impl(context):
invalid_json_data = 'Invalid JSON format'
context.page = context.client.post('/login', data=invalid_json_data, headers={'Content-Type': 'application/json'}, follow_redirects=True)
response = context.page.get_json()
assert response['error'] == 'Invalid JSON payload received.'


@when('I pass valid credentials but the server encounters an internal error when logging in')
def step_impl(context):
with patch('blackboard_session.BlackboardSession.login') as mock_login:
mock_login.side_effect = Exception("Internal server error")
try:
context.session.login()
except Exception as e:
context.exception_message = str(e)

@when('the user is already logged in')
def step_impl(context):
# Assuming 'context.session' is an instance of BlackboardSession
context.session.login() # First login
context.second_login_response = context.session.login() # Second login attempt


#* Then steps
@then('a new session should be created for "{username}"')
def step_impl(context, username):
Expand Down Expand Up @@ -355,18 +406,38 @@ def step_impl(context, message):
def step_impl(context, message):
assert context.get_download_tasks_response == message

@then('The response of "200" and "Logged in Successfully" should be returned')
def step_impl(context):
assert context.page.get_json() == {'message': 'Logged in successfully'}
@then('the response of "{status_code}" and "{message}" should be returned')
def step_impl(context, status_code, message):
expected_status_code = int(status_code)

@then('The response of "401" and "The username you entered cannot be identified." should be returned')
def step_impl(context):
assert context.page.get_json() == {'error': 'The username you entered cannot be identified.'}
# Ensure that context.page contains the response object
assert hasattr(context, 'page'), "context does not have 'page' attribute. Make sure the HTTP request was made."

# Get the actual status code from the response
actual_status_code = context.page.status_code
assert actual_status_code == expected_status_code, f"Expected status code {expected_status_code}, got {actual_status_code}"

# Parse the JSON response body
response_json = context.page.get_json()

@then('The response of "401" and "The password you entered was incorrect." should be returned')
# Check the message or error based on the status code
if expected_status_code == 200:
assert response_json.get('message') == message, f"Expected message '{message}', got '{response_json.get('message')}'"
else:
assert response_json.get('error') == message, f"Expected error message '{message}', got '{response_json.get('error')}'"

@then('cookies should be set')
def step_impl(context):
assert context.page.get_json() == {'error': 'The password you entered was incorrect.'}
# Ensure that context.page contains the response object
assert hasattr(context, 'page'), "context does not have 'page' attribute. Make sure the HTTP request was made."

# Check if the 'user_session' cookie is set in the response
cookies = context.page.headers.get('Set-Cookie')
assert cookies is not None, "No cookies were set in the response."

# Further check for the specific 'user_session' cookie
assert 'user_session' in cookies, "The 'user_session' cookie was not set in the response."

@then('The response of "429" and "Too many requests, please try again later." should be returned')
@then('an internal server error should be raised')
def step_impl(context):
assert context.page.get_json() == {'error': 'Too many requests, please try again later.'}
assert context.exception_message == "Internal server error"

0 comments on commit 83e88c7

Please sign in to comment.