Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/handler/stock.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import proto.stock_pb2 as stock_pb2
import proto.stock_pb2_grpc as stock_pb2_grpc

from usecase.stock.base import AbstractStockUsecase
from usecase.base import AbstractStockUsecase
from domain.stock import CreateStock, ActionType, ACTION_MAP


Expand Down
2 changes: 1 addition & 1 deletion src/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from dotenv import load_dotenv
from handler.stock import StockService
from adapters.stock import StockRepository
from usecase.stock.stock import StockUsecase
from usecase.stock import StockUsecase


load_dotenv()
Expand Down
2 changes: 1 addition & 1 deletion src/tests/test_stock_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from domain.stock import CreateStock, ActionType
from handler.stock import StockService
from usecase.stock.base import AbstractStockUsecase
from usecase.base import AbstractStockUsecase


class TestStockServiceCreate:
Expand Down
61 changes: 56 additions & 5 deletions src/tests/test_stock_usecase.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import pytest
from datetime import datetime
from datetime import datetime, timezone
from unittest.mock import Mock
from usecase.stock.stock import StockUsecase
from domain.stock import CreateStock, ActionType
from usecase.stock import StockUsecase
from domain.stock import CreateStock, ActionType, Stock


@pytest.fixture
Expand All @@ -22,7 +22,7 @@ def test_create(self, stock_usecase):
price=150.25,
quantity=100,
action_type=ActionType.BUY,
created_at=datetime.utcnow(),
created_at=datetime.now(timezone.utc),
)

# Define the expected return value from the mock repository
Expand All @@ -45,7 +45,7 @@ def test_create_handles_repository_error(self, stock_usecase):
price=150.25,
quantity=100,
action_type=ActionType.BUY,
created_at=datetime.utcnow(),
created_at=datetime.now(timezone.utc),
)

# Simulate an exception from the repository
Expand All @@ -55,3 +55,54 @@ def test_create_handles_repository_error(self, stock_usecase):
with pytest.raises(Exception, match="Repository error"):
usecase.create(mock_stock)
mock_repo.create.assert_called_once_with(mock_stock)

def test_list(self, stock_usecase):
# Arrange
usecase, mock_repo = stock_usecase
user_id = 1
created_at = datetime.now(timezone.utc)
mock_stocks = [
Stock(
id="stock_123",
user_id=1,
symbol="AAPL",
price=150.25,
quantity=100,
action_type=ActionType.BUY,
created_at=created_at,
updated_at=created_at,
),
Stock(
id="stock_124",
user_id=1,
symbol="GOOGL",
price=2800.50,
quantity=10,
action_type=ActionType.BUY,
created_at=created_at,
updated_at=created_at,
),
]
mock_repo.list.return_value = mock_stocks

# Act
result = usecase.list(user_id)

# Assert
mock_repo.list.assert_called_once_with(user_id)
assert result == mock_stocks
assert len(result) == 2
assert all(isinstance(stock, Stock) for stock in result)
assert result[0].symbol == "AAPL"
assert result[1].symbol == "GOOGL"

def test_list_handles_repository_error(self, stock_usecase):
# Arrange
usecase, mock_repo = stock_usecase
user_id = 1
mock_repo.list.side_effect = Exception("Repository error")

# Act/Assert
with pytest.raises(Exception, match="Repository error"):
usecase.list(user_id)
mock_repo.list.assert_called_once_with(user_id)
7 changes: 6 additions & 1 deletion src/usecase/stock/base.py → src/usecase/base.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
from typing import List
from abc import ABC, abstractmethod
from domain.stock import CreateStock

from domain.stock import CreateStock, Stock


class AbstractStockUsecase(ABC):
@abstractmethod
def create(self, stock: CreateStock) -> str:
"""Create a new stock entry."""

def list(self, user_id: int) -> List[Stock]:
"""List all stock by user id"""
7 changes: 6 additions & 1 deletion src/usecase/stock/stock.py → src/usecase/stock.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from domain.stock import CreateStock
from typing import List

from domain.stock import CreateStock, Stock
from adapters.base import AbstractStockRepository
from .base import AbstractStockUsecase

Expand All @@ -9,3 +11,6 @@ def __init__(self, stock_repo: AbstractStockRepository):

def create(self, stock: CreateStock):
return self.stock_repo.create(stock)

def list(self, user_id: int) -> List[Stock]:
return self.stock_repo.list(user_id)