def test_invalid_user_credentials_check(): url = 'fake' username = '******' password = '******' http_client = FakeHttpClient( configs={'result': Success(data={'valid': False})}) check_creds_usecase = CheckUserCredentialsUseCase(http_client=http_client) assert isinstance( check_creds_usecase.execute(url=url, username=username, password=password), Error) http_client = FakeHttpClient( configs={'result': Error(reason='Network error? maybe? :D')}) check_creds_usecase = CheckUserCredentialsUseCase(http_client=http_client) assert isinstance( check_creds_usecase.execute(url=url, username=username, password=password), Error) assert isinstance( check_creds_usecase.execute(url='', username=username, password=password), Error) assert isinstance( check_creds_usecase.execute(url=url, username='', password=password), Error) assert isinstance( check_creds_usecase.execute(url=url, username=username, password=''), Error)
def test_valid_send_message_to_all(): http_client = FakeHttpClient( configs={'result': Success(data={'valid': True})}) online_user_persistent = InMemoryOnlineUsersPersistent() in_memory_message_broker = InMemoryMessageBroker() check_user_creds_usecase = CheckUserCredentialsUseCase( http_client=http_client) add_online_user_usecase = AddOnlineUserUseCase( online_user_persistent=online_user_persistent) remove_online_user_usecase = RemoveOnlineUserUseCase( online_user_persistent=online_user_persistent) publish_online_user_usecase = PublishOnlineUserUseCase( message_broker=in_memory_message_broker) api, io = get_io(check_user_creds_usecase=check_user_creds_usecase, add_online_user_usecase=add_online_user_usecase, remove_online_user_usecase=remove_online_user_usecase, publish_online_user_usecase=publish_online_user_usecase) client = SocketIOTestClient(app=api, socketio=io, headers={ 'username': '******', 'password': '******' }) _connected_msg = client.get_received().pop(0) client.emit('message', {'message': 'Hello there !'}) assert client.get_received().pop(0) == { 'name': 'all', 'args': [{ 'message': 'Hello there !' }], 'namespace': '/' }
def test_valid_connection(): http_client = FakeHttpClient( configs={'result': Success(data={'valid': True})}) online_user_persistent = InMemoryOnlineUsersPersistent() in_memory_message_broker = InMemoryMessageBroker() check_user_creds_usecase = CheckUserCredentialsUseCase( http_client=http_client) add_online_user_usecase = AddOnlineUserUseCase( online_user_persistent=online_user_persistent) remove_online_user_usecase = RemoveOnlineUserUseCase( online_user_persistent=online_user_persistent) publish_online_user_usecase = PublishOnlineUserUseCase( message_broker=in_memory_message_broker) api, io = get_io(check_user_creds_usecase=check_user_creds_usecase, add_online_user_usecase=add_online_user_usecase, remove_online_user_usecase=remove_online_user_usecase, publish_online_user_usecase=publish_online_user_usecase) client = SocketIOTestClient(app=api, socketio=io, headers={ 'username': '******', 'password': '******' }) assert client.is_connected() is True
def save_user(self, *, user: UserEntity) -> Union[Error, Success]: if self.__does_exist_before(user=user): return Error( reason= f'This username {user.name} does exist before, use different username please.' ) database_user = self.__models.User(name=user.name, password=bcrypt.hashpw( user.password.encode(), bcrypt.gensalt()), age=user.age, email=user.email) try: database_user.commit() dumped_database_user = database_user.dump() return Success( data=UserEntity(id=dumped_database_user['id'], name=dumped_database_user['name'], password=dumped_database_user['password'], age=dumped_database_user['age'], email=dumped_database_user['email'])) except: return Error( reason=f'Error saving user {user.name} into database.')
def id(self, *, user_id: str) -> Either[Failure, Success]: fetch_status: Maybe[ApplicationUser] = db["ids"].get(user_id) if isinstance(fetch_status, ApplicationUser): self.__inner_delete_user(user=fetch_status) return Success() return Failure( error=f"There is no user with id {user_id} to be deleted")
def __inner_delete_user( self, *, user: ApplicationUser) -> Either[Failure, Success]: del db["ids"][user.id] del db["names"][user.name] del db["emails"][user.email] return Success()
def email(self, *, user_email: str) -> Either[Failure, Success]: user_id: Maybe[str] = db["emails"].get(user_email) if user_id is not None: self.__inner_delete_user(user=db["ids"][user_id]) return Success() return Failure( error= f"There is no user with email {user_email} to be deleted")
def name(self, *, user_name: str) -> Either[Failure, Success]: user_id: Maybe[str] = db["names"].get(user_name) if user_id is not None: self.__inner_delete_user(user=db["ids"][user_id]) return Success() return Failure( error= f"There is no user with name {user_name} to be deleted")
def __validate_data(self, *, url: str, username: str, password: str) -> Union[Error, Success]: # simple validation of data and should be enhanced later ;) if url == '': return Error(reason='Invalid url') if username == '': return Error(reason='Invalid username') if password == '': return Error(reason='Invalid password') return Success(data=None)
def remove_online_user(self, *, socket_id: str) -> Union[Error, Success]: db_user = self.__db.get(socket_id, None) if db_user is not None: del self.__db[socket_id] return Success(data=None) return Error( reason= f"This username with socket_id '{socket_id}' does not exist as an online user" )
def check_user_credentials(self, *, username: str, password: str) -> Union[Error, Success]: db_user: Optional[User] = self.__db.get(username, None) if db_user is not None: db_password = db_user.password if password == db_password: return Success( data=f"This user's '{username}' credentials are valid") return Error( reason=f"This user's '{username}' credentials are not valid") return Error(reason=f"User with username '{username}' does not exist")
def _validate_user_persistent_data( self, *, user_persistent: UserPersistence) -> Union[Error, Success]: # simple validation of data for now if user_persistent: if user_persistent.username == '': return Error(reason='Invalid username') if user_persistent.socket_id == '': return Error(reason='Invalid socket_id') return Success(data=None) return Error(reason='Invalid user persistent data')
def test_valid_user_credentials_check(): url = 'fake' username = '******' password = '******' http_client = FakeHttpClient( configs={'result': Success(data={'valid': True})}) check_creds_usecase = CheckUserCredentialsUseCase(http_client=http_client) assert isinstance( check_creds_usecase.execute(url=url, username=username, password=password), Success)
def __validate_data(self, *, data: Dict[str, Any]) -> Union[Error, Success]: # simple validation, may be replaced with json validator later :) if data: if data.get('username', None) is None: return Error(reason="username is required") if data.get('username', '') == '': return Error(reason="Not valid username") if data.get('password', '') == '': return Error(reason="Not valid password") return Success(data=None) else: return Error(reason="Not valid data")
def save_user(self, *, user: User) -> Union[Error, Success]: if self.__does_exist_before(user=user): return Error( reason= f'This username {user.name} does exist before, use different username please.' ) user = User(id=uuid4().hex, name=user.name, password=user.password, age=user.age, email=user.email) self.__db[user.name] = user return Success(data=user)
def check_user_credentials(self, *, username: str, password: str) -> Union[Error, Success]: db_user = self.__models.User.find_one({"name": username}) if db_user is not None: db_password = db_user.password if bcrypt.checkpw(password.encode(), db_password.encode()): return Success( data=f"This user's '{username}' credentials are valid") return Error( reason=f"This user's '{username}' credentials are not valid") else: return Error( reason=f"User with username '{username}' does not exist")
def test_valid_delete_user(setup): api, db = setup api: TestClient db: InMemoryDatabase domain_user = generate_valid_domain_user() db.persist_user(user=domain_user) token: AccessToken = db.persist_access_token(username=domain_user.name, password=domain_user.password) # by id db.persist_user(user=domain_user) dummy_id = "0" assert api.delete(url=f"/users?id={dummy_id}", headers={ 'username': domain_user.name, 'access-token': token.token }).json() == Success().as_dict() # by name db.persist_user(user=domain_user) dummy_name = domain_user.name assert api.delete(url=f"/users?name={dummy_name}", headers={ 'username': domain_user.name, 'access-token': token.token }).json() == Success().as_dict() # by email db.persist_user(user=domain_user) dummy_email = domain_user.email assert api.delete(url=f"/users?email={dummy_email}", headers={ 'username': domain_user.name, 'access-token': token.token }).json() == Success().as_dict()
def execute(self, *, url: str, username: str, password: str) -> Union[Error, Success]: validation_result = self.__validate_data(url=url, username=username, password=password) if isinstance(validation_result, Error): return validation_result check_validation_result = self.__http_client.post( url=url, data={'username': username, 'password': password} ) if isinstance(check_validation_result, Error): return check_validation_result if check_validation_result.data is not None and check_validation_result.data.get('valid', False): return Success(data=None) return Error(reason=f'Invalid credentials for user "{username}"')
def save_online_user( self, *, user_persistence: UserPersistence) -> Union[Error, Success]: if isinstance( self._validate_user_persistent_data( user_persistent=user_persistence), Success): db_user = self.__db.get(user_persistence.socket_id, None) if db_user is not None: return Error( reason= f'This user with socket_id "{user_persistence.socket_id}" does exist already as an online user' ) self.__db[user_persistence.socket_id] = user_persistence return Success(data=None) return Error(reason='Invalid user persistent data')
def __validate_data(self, *, data: Dict[str, Any]) -> Union[Error, Success]: # simple validation, may be replaced with json validator later :) if data: if data.get('name', None) is None: return Error(reason="Not valid name") if data.get('name', '') == '': return Error(reason="Not valid name") if data.get('password', '') == '': return Error(reason="Not valid password") try: if int(data.get('age', -1)) == -1 or int(data.get( 'age', -1)) < 18: # 18 for adult :D return Error(reason="Not valid age") except ValueError: return Error(reason="Not valid age type") # maybe later should validate email as well properly, now we will take it as it is even none return Success(data=None) else: return Error(reason="Not valid data")
def publish_message(self, *, topic: str, message: Dict[str, Any]) -> Either[Error, Success]: # since this is in-memory so no need th e topic :) self.__broker.put(item=message) return Success(data=None)
def validate(self, *, schema: Dict[str, Any], data: Dict[str, Any]) -> Either[Failure, Success]: validate(schema=schema, instance=data) return Success()