import json from random import randbytes from bson.objectid import ObjectId from pytest import fixture from roc_fnb.util.base64 import base64_decode from roc_fnb.website.database import Database from roc_fnb.website.models.user import User @fixture def user() -> User: return User.create('test@t.co', 'name', 'monkey') @fixture def database() -> Database: return Database.from_env() def test_user_and_check_password(user): assert user.name == 'name' assert user.email == 'test@t.co' assert user._id is None assert user.check_password('monkey') def test_jwt(user): user._id = (_id := ObjectId(randbytes(12))) token = user.jwt header, payload, sig = (base64_decode(part.replace('.', '')) for part in token.split('.')) header = json.loads(header) payload = json.loads(payload) assert header['alg'] == 'RS256' assert header['typ'] == 'JWT' assert set(header.keys()) == {'alg', 'typ'} # Note that JWT contents are visible to the user: this can be useful but # must be done with caution assert payload['email'] == user.email assert payload['name'] == user.name assert ObjectId(base64_decode(payload['_id'])) == user._id == _id assert set(payload.keys()) == {'email', 'name', '_id', 'admin', 'moderator'} result = user.verify_jwt(token) assert result.email == user.email assert result.name == user.name assert result._id == user._id == _id assert not result.admin assert not result.moderator def test_store_and_retreive(user: User, database: Database): try: database.store_user(user) assert user._id is not None retreived = database.get_user_by_email(user.email) assert retreived is not None assert retreived._id == user._id assert retreived == user finally: if id := user._id: database.delete_user(id) def test_store_and_retreive_by_id(user: User, database: Database): try: database.store_user(user) assert user._id is not None retreived = database.get_user_by_id(user._id) assert retreived == user finally: if id := user._id: database.delete_user(id) def test_store_and_retreive_by_jwt(user: User, database: Database): try: token = database.store_user(user).jwt assert user._id is not None retreived = database.get_user_from_token(token) assert retreived == user finally: if id := user._id: database.delete_user(id)