from datetime import UTC, datetime, timedelta import allure import pytest from fastapi import HTTPException from jose import jwt from service.auth.auth import CurrentUser from src.models.configs_read.env import env_settings from src.service.auth.jwt import Hashes, Jwt @pytest.mark.unit class TestJwt: @pytest.mark.parametrize("data", [ ({"sub": "123"}), ({"sub":""}), ({"":""}) ]) def test_access_create_positive(self, jwt_service:Jwt, data:dict)->None: with allure.step("create correct access token"): token = jwt_service.create_access_token(data) parts=token.split(".") assert isinstance(token, str) assert len(parts)==3 @pytest.mark.parametrize("data",[ ("") ]) def test_access_create_negative(self, jwt_service:Jwt, data:dict)->None: with allure.step("create invalid access token"),pytest.raises(AttributeError): jwt_service.create_access_token(data) @pytest.mark.parametrize("data", [ ({"sub": "123"}), ({"sub":""}), ({"":""}) ]) def test_refresh_create_positive(self, jwt_service:Jwt, data:dict)->None: with allure.step("create correct access token"): token = jwt_service.create_refresh_token(data) parts=token[0].split(".") assert isinstance(token[0], str) assert isinstance(token[1], str) assert len(parts)==3 @pytest.mark.parametrize("data",[ ("") ]) def test_refresh_create_negative(self, jwt_service:Jwt, data)->None: with allure.step("create invalid access token"), pytest.raises(AttributeError): jwt_service.create_refresh_token(data) @pytest.mark.parametrize("data", [ ({"sub": "123", "exp":datetime.now(UTC)+timedelta(minutes=15), "token_type":"access"}), ]) def test_jwt_decode_positive(self, data:dict, monkeypatch, jwt_service:Jwt)->None: with allure.step("patch a create token function"): def fake_create_access_token(data:dict)->str: return jwt.encode(data, env_settings.SECRET_KEY, env_settings.ALGORITHM) monkeypatch.setattr(jwt_service, "create_access_token", fake_create_access_token) with allure.step("create and decode correct token"): fake_token = jwt_service.create_access_token(data) payload=jwt_service.jwt_decode(fake_token) assert payload.get("sub") assert payload.get("exp") assert payload.get("token_type") @pytest.mark.parametrize("data, expected_exception", [ ({"sub": "123", "exp":datetime.now(UTC)-timedelta(minutes=15), "token_type":"access"}, HTTPException), ({"sub": "123", "exp":datetime.now(UTC)+timedelta(minutes=15)}, HTTPException), ({"sub": "123", "token_type":"access"}, HTTPException), ({}, HTTPException), ("", AttributeError) ]) def test_jwt_decode_invalid(self,jwt_service:Jwt, expected_exception, data, monkeypatch)->None: with allure.step("patch a create token function"): def fake_create_access_token(data:dict)->str: return jwt.encode(data, env_settings.SECRET_KEY, env_settings.ALGORITHM) monkeypatch.setattr(jwt_service, "create_access_token", fake_create_access_token) with allure.step("create and decode invalid token"), pytest.raises(expected_exception): fake_token=jwt_service.create_access_token(data) jwt_service.jwt_decode(fake_token) @pytest.mark.parametrize("time, key, algorithm", [ (15, "wrong_key", "HS256"), (-15, "correct_key", "HS256"), (15, "correct_key", "HS512"), ]) def test_jwt_decode_wrong_env(self, monkeypatch, time:int, key:str, algorithm:str, jwt_service)->None: with allure.step("patch a create token function"): def fake_create_access_token(data:dict, key:str, algorithm:str)->str: data.update({"exp":datetime.now(UTC)+timedelta(minutes=time)}) return jwt.encode(data, key, algorithm) monkeypatch.setattr(jwt_service, "create_access_token", fake_create_access_token) with allure.step("create and decode token with wrong data inside"), pytest.raises(HTTPException): fake_token=jwt_service.create_access_token({"sub": "123", "token_type":"access"}, key, algorithm) jwt_service.jwt_decode(fake_token) @pytest.mark.parametrize("password",[ ("plain_password") ]) def test_hash_and_veryfy_positive(self, password:str, hash_service:Hashes)->None: with allure.step("encode password"): encoded_password=hash_service.plain_to_hash(password) assert isinstance(encoded_password, str) assert encoded_password!=password with allure.step("decode password"): assert hash_service.verify_password(password, encoded_password) is True def test_verify_wrong_password(self, hash_service:Hashes)->None: with allure.step("encode password"): encoded_password=hash_service.plain_to_hash("plain_password") with allure.step("decode password"): assert hash_service.verify_password("wrong_password", encoded_password) is False def test_token_to_hash_determistic(self, hash_service:Hashes)->None: assert hash_service.token_to_hash("abc")==hash_service.token_to_hash("abc") def test_token_to_hash_different_input(self, hash_service:Hashes)->None: assert hash_service.token_to_hash("abc")!=hash_service.token_to_hash("xyz")