from bson.objectid import ObjectId from flask.testing import FlaskClient import json from pytest import fixture from roc_fnb.util import base64_decode from roc_fnb.website.server import app from roc_fnb.website.models.user import User from roc_fnb.website.database import Database @fixture def user() -> User: return User.create('test@t.co', 'name', 'monkey') @fixture def database() -> Database: return Database.from_env() @fixture def client(): return app.test_client() def test_login(user: User, database: Database, client: FlaskClient): database.store_user(user) try: assert user._id is not None # for mypy resp = client.post( '/login', json={ 'name': user.name, 'password': 'monkey' } ) assert resp.json is not None # for mypy assert resp.json['status'] == "OK" with client.session_transaction() as session: session_data = json.loads(session['user']) assert base64_decode(session_data['_id']) == user._id.binary assert session_data['name'] == user.name assert 'password' not in session_data.keys() assert session_data['email'] == user.email assert not session.get('admin') assert not session.get('moderator') finally: if _id := user._id: database.delete_user(_id) def test_create_user(user: User, database: Database, client: FlaskClient): user.admin = True try: database.store_user(user) assert user._id is not None # for mypy resp = client.post( '/login', json={ 'name': user.name, 'password': 'monkey' } ) assert resp.json is not None # for mypy assert resp.json['status'] == "OK" with client.session_transaction() as session: assert session.get('user') is not None session_data = json.loads(session['user']) assert session_data['admin'] resp = client.get('/invite', headers={'Accept': 'application/json'}) assert resp.status_code == 200 assert resp.json is not None invite = resp.json['invite'] with client.session_transaction() as session: del session['user'] _id = None try: resp = client.post( '/new-user', json={ 'name': 'Test 2', 'password': 'hunter2', 'invite_code': invite, 'email': None } ) assert resp.status_code == 200 assert resp.json is not None assert resp.json['status'] == 'OK' with client.session_transaction() as session: session_data = json.loads(session['user']) _id = ObjectId(base64_decode(session_data['_id'])) new_user = database.get_user_by_id(_id) assert new_user is not None assert new_user._id == _id assert new_user.name == 'Test 2' assert new_user.check_password('hunter2') assert not (new_user.admin or new_user.moderator) invitation_doc = database.db.invitations.find_one({'invite_code': base64_decode(invite)}) assert invitation_doc is not None assert invitation_doc['invited_user_id'] == _id assert invitation_doc['invited_by'] == user._id finally: if _id is not None: database.delete_user(_id) finally: if u_id := user._id: database.delete_user(u_id) def test_create_user_deny_non_admin(user: User, database: Database, client: FlaskClient): database.store_user(user) try: assert user._id is not None # for mypy resp = client.post( '/login', json={ 'name': user.name, 'password': 'monkey' } ) assert resp.json is not None # for mypy assert resp.json['status'] == "OK" with client.session_transaction() as session: assert session.get('user') is not None resp = client.get('/invite', headers={'Accept': 'application/json'}) assert resp.status_code == 401 finally: if _id := user._id: database.delete_user(_id)