from unittest import mock import pytest from aiodynamo.expressions import UpdateExpression from aiodynamo.models import BatchWriteRequest, BatchWriteResult from dirty_equals import IsInstance from url_shortener.config import Settings from url_shortener.exceptions import DynamodbBatchWriteError, PathDoesNotExistsError from url_shortener.repositories import PathsRepository async def test_repository_process_unprocessed_items( repository: PathsRepository, dynamodb_client_mock: mock.AsyncMock, settings: Settings, ) -> None: dynamodb_client_mock.batch_write.side_effect = [ { settings.dynamodb_tablename: BatchWriteResult( undeleted_keys=[], unput_items=[{"key_1": "value_1"}] ) }, {}, ] await repository._write_data( items_to_put=[{"key_1": "value_1"}, {"key_2": "value_2"}] ) dynamodb_client_mock.batch_write.assert_has_calls( [ mock.call( { settings.dynamodb_tablename: BatchWriteRequest( items_to_put=[{"key_1": "value_1"}, {"key_2": "value_2"}], ) } ), mock.call( { settings.dynamodb_tablename: BatchWriteRequest( items_to_put=[{"key_1": "value_1"}], ) } ), ], any_order=False, ) async def test_repository_batch_write_max_tries_count( repository: PathsRepository, dynamodb_client_mock: mock.AsyncMock, settings: Settings, ) -> None: repository.dynamodb_max_write_retry_count = 3 dynamodb_client_mock.batch_write.return_value = { settings.dynamodb_tablename: BatchWriteResult( undeleted_keys=[], unput_items=[{"key_1": "value_1"}] ) } with pytest.raises(DynamodbBatchWriteError): await repository._write_data( items_to_put=[{"key_1": "value_1"}, {"key_2": "value_2"}] ) dynamodb_client_mock.batch_write.assert_has_calls( [ mock.call( { settings.dynamodb_tablename: BatchWriteRequest( items_to_put=[{"key_1": "value_1"}, {"key_2": "value_2"}], ) } ), mock.call( { settings.dynamodb_tablename: BatchWriteRequest( items_to_put=[{"key_1": "value_1"}], ) } ), mock.call( { settings.dynamodb_tablename: BatchWriteRequest( items_to_put=[{"key_1": "value_1"}], ) } ), ], any_order=False, ) async def test_repository_update_path_success( repository: PathsRepository, dynamodb_client_mock: mock.AsyncMock, settings: Settings, ) -> None: dynamodb_client_mock.get_item.return_value = {"path": "test-path"} dynamodb_client_mock.update_item.return_value = None await repository.update_path("test-path", {"url": "https://example.com"}) dynamodb_client_mock.get_item.assert_called_with( settings.dynamodb_tablename, {"path": "test-path"}, ) dynamodb_client_mock.update_item.assert_called_with( key={"path": "test-path"}, table=settings.dynamodb_tablename, update_expression=IsInstance(UpdateExpression), ) async def test_repository_update_path_not_found( repository: PathsRepository, dynamodb_client_mock: mock.AsyncMock, settings: Settings, ) -> None: dynamodb_client_mock.get_item.return_value = None dynamodb_client_mock.update_item.return_value = None with pytest.raises(PathDoesNotExistsError): await repository.update_path("test-path", {"url": "https://example.com"}) dynamodb_client_mock.get_item.assert_called_with( settings.dynamodb_tablename, {"path": "test-path"}, ) dynamodb_client_mock.update_item.assert_not_called()