fix(loyalty): fix wallet service test fixtures and mock paths
Some checks failed
Some checks failed
- Add customer_id to card fixtures (NOT NULL constraint) - Use test_customer shared fixture instead of inline Customer creation - Fix mock path to target source module for lazy imports Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -17,32 +17,19 @@ import pytest
|
|||||||
from app.modules.loyalty.models import LoyaltyCard, LoyaltyProgram
|
from app.modules.loyalty.models import LoyaltyCard, LoyaltyProgram
|
||||||
from app.modules.loyalty.models.loyalty_program import LoyaltyType
|
from app.modules.loyalty.models.loyalty_program import LoyaltyType
|
||||||
from app.modules.loyalty.services.wallet_service import WalletService
|
from app.modules.loyalty.services.wallet_service import WalletService
|
||||||
from app.modules.tenancy.models import Merchant
|
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# Fixtures
|
# Fixtures
|
||||||
|
# Uses test_merchant and test_customer from shared fixtures (store_fixtures,
|
||||||
|
# customer_fixtures) which handle owner_user_id and other required fields.
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def wt_merchant(db):
|
def wt_program(db, test_merchant):
|
||||||
"""Create a merchant for wallet tests."""
|
|
||||||
merchant = Merchant(
|
|
||||||
name=f"Wallet Test Merchant {uuid.uuid4().hex[:8]}",
|
|
||||||
contact_email=f"wallet_{uuid.uuid4().hex[:8]}@test.com",
|
|
||||||
is_active=True,
|
|
||||||
)
|
|
||||||
db.add(merchant)
|
|
||||||
db.commit()
|
|
||||||
db.refresh(merchant)
|
|
||||||
return merchant
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def wt_program(db, wt_merchant):
|
|
||||||
"""Create a loyalty program for wallet tests."""
|
"""Create a loyalty program for wallet tests."""
|
||||||
program = LoyaltyProgram(
|
program = LoyaltyProgram(
|
||||||
merchant_id=wt_merchant.id,
|
merchant_id=test_merchant.id,
|
||||||
loyalty_type=LoyaltyType.POINTS.value,
|
loyalty_type=LoyaltyType.POINTS.value,
|
||||||
points_per_euro=10,
|
points_per_euro=10,
|
||||||
welcome_bonus_points=0,
|
welcome_bonus_points=0,
|
||||||
@@ -61,10 +48,10 @@ def wt_program(db, wt_merchant):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def wt_program_with_apple(db, wt_merchant):
|
def wt_program_with_apple(db, test_merchant):
|
||||||
"""Create a loyalty program with Apple Wallet configured."""
|
"""Create a loyalty program with Apple Wallet configured."""
|
||||||
program = LoyaltyProgram(
|
program = LoyaltyProgram(
|
||||||
merchant_id=wt_merchant.id,
|
merchant_id=test_merchant.id,
|
||||||
loyalty_type=LoyaltyType.POINTS.value,
|
loyalty_type=LoyaltyType.POINTS.value,
|
||||||
points_per_euro=10,
|
points_per_euro=10,
|
||||||
welcome_bonus_points=0,
|
welcome_bonus_points=0,
|
||||||
@@ -84,12 +71,12 @@ def wt_program_with_apple(db, wt_merchant):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def wt_card(db, wt_program):
|
def wt_card(db, wt_program, test_customer):
|
||||||
"""Create a loyalty card for wallet tests."""
|
"""Create a loyalty card for wallet tests."""
|
||||||
card = LoyaltyCard(
|
card = LoyaltyCard(
|
||||||
merchant_id=wt_program.merchant_id,
|
merchant_id=wt_program.merchant_id,
|
||||||
program_id=wt_program.id,
|
program_id=wt_program.id,
|
||||||
customer_id=None,
|
customer_id=test_customer.id,
|
||||||
card_number=f"WT-{uuid.uuid4().hex[:8].upper()}",
|
card_number=f"WT-{uuid.uuid4().hex[:8].upper()}",
|
||||||
is_active=True,
|
is_active=True,
|
||||||
)
|
)
|
||||||
@@ -100,12 +87,12 @@ def wt_card(db, wt_program):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def wt_card_apple(db, wt_program_with_apple):
|
def wt_card_apple(db, wt_program_with_apple, test_customer):
|
||||||
"""Create a loyalty card for Apple Wallet tests."""
|
"""Create a loyalty card for Apple Wallet tests."""
|
||||||
card = LoyaltyCard(
|
card = LoyaltyCard(
|
||||||
merchant_id=wt_program_with_apple.merchant_id,
|
merchant_id=wt_program_with_apple.merchant_id,
|
||||||
program_id=wt_program_with_apple.id,
|
program_id=wt_program_with_apple.id,
|
||||||
customer_id=None,
|
customer_id=test_customer.id,
|
||||||
card_number=f"WTA-{uuid.uuid4().hex[:8].upper()}",
|
card_number=f"WTA-{uuid.uuid4().hex[:8].upper()}",
|
||||||
is_active=True,
|
is_active=True,
|
||||||
)
|
)
|
||||||
@@ -143,7 +130,7 @@ class TestWalletService:
|
|||||||
class TestCreateWalletObjectsGoogle:
|
class TestCreateWalletObjectsGoogle:
|
||||||
"""Tests for Google Wallet object creation during enrollment."""
|
"""Tests for Google Wallet object creation during enrollment."""
|
||||||
|
|
||||||
@patch("app.modules.loyalty.services.wallet_service.google_wallet_service")
|
@patch("app.modules.loyalty.services.google_wallet_service.google_wallet_service")
|
||||||
def test_google_wallet_object_created_when_configured(
|
def test_google_wallet_object_created_when_configured(
|
||||||
self, mock_gw, db, wt_card
|
self, mock_gw, db, wt_card
|
||||||
):
|
):
|
||||||
@@ -157,7 +144,7 @@ class TestCreateWalletObjectsGoogle:
|
|||||||
assert results["google_wallet"] is True
|
assert results["google_wallet"] is True
|
||||||
mock_gw.create_object.assert_called_once_with(db, wt_card)
|
mock_gw.create_object.assert_called_once_with(db, wt_card)
|
||||||
|
|
||||||
@patch("app.modules.loyalty.services.wallet_service.google_wallet_service")
|
@patch("app.modules.loyalty.services.google_wallet_service.google_wallet_service")
|
||||||
def test_google_wallet_skipped_when_not_configured(
|
def test_google_wallet_skipped_when_not_configured(
|
||||||
self, mock_gw, db, wt_card
|
self, mock_gw, db, wt_card
|
||||||
):
|
):
|
||||||
@@ -170,7 +157,7 @@ class TestCreateWalletObjectsGoogle:
|
|||||||
assert results["google_wallet"] is False
|
assert results["google_wallet"] is False
|
||||||
mock_gw.create_object.assert_not_called()
|
mock_gw.create_object.assert_not_called()
|
||||||
|
|
||||||
@patch("app.modules.loyalty.services.wallet_service.google_wallet_service")
|
@patch("app.modules.loyalty.services.google_wallet_service.google_wallet_service")
|
||||||
def test_google_wallet_failure_does_not_crash(
|
def test_google_wallet_failure_does_not_crash(
|
||||||
self, mock_gw, db, wt_card
|
self, mock_gw, db, wt_card
|
||||||
):
|
):
|
||||||
@@ -203,7 +190,7 @@ class TestCreateWalletObjectsApple:
|
|||||||
|
|
||||||
service = WalletService()
|
service = WalletService()
|
||||||
with patch(
|
with patch(
|
||||||
"app.modules.loyalty.services.wallet_service.google_wallet_service"
|
"app.modules.loyalty.services.google_wallet_service.google_wallet_service"
|
||||||
) as mock_gw:
|
) as mock_gw:
|
||||||
mock_gw.is_configured = False
|
mock_gw.is_configured = False
|
||||||
results = service.create_wallet_objects(db, wt_card_apple)
|
results = service.create_wallet_objects(db, wt_card_apple)
|
||||||
@@ -217,7 +204,7 @@ class TestCreateWalletObjectsApple:
|
|||||||
"""Apple serial number not set when program lacks apple_pass_type_id."""
|
"""Apple serial number not set when program lacks apple_pass_type_id."""
|
||||||
service = WalletService()
|
service = WalletService()
|
||||||
with patch(
|
with patch(
|
||||||
"app.modules.loyalty.services.wallet_service.google_wallet_service"
|
"app.modules.loyalty.services.google_wallet_service.google_wallet_service"
|
||||||
) as mock_gw:
|
) as mock_gw:
|
||||||
mock_gw.is_configured = False
|
mock_gw.is_configured = False
|
||||||
results = service.create_wallet_objects(db, wt_card)
|
results = service.create_wallet_objects(db, wt_card)
|
||||||
@@ -337,7 +324,7 @@ class TestEnrollmentWalletCreation:
|
|||||||
|
|
||||||
@patch("app.modules.loyalty.services.google_wallet_service.settings")
|
@patch("app.modules.loyalty.services.google_wallet_service.settings")
|
||||||
def test_enrollment_creates_google_wallet_object(
|
def test_enrollment_creates_google_wallet_object(
|
||||||
self, mock_settings, db, wt_program, wt_merchant
|
self, mock_settings, db, wt_program, test_merchant, test_customer
|
||||||
):
|
):
|
||||||
"""Full enrollment flow creates Google Wallet class + object in DB."""
|
"""Full enrollment flow creates Google Wallet class + object in DB."""
|
||||||
from app.modules.loyalty.services.google_wallet_service import (
|
from app.modules.loyalty.services.google_wallet_service import (
|
||||||
@@ -355,20 +342,9 @@ class TestEnrollmentWalletCreation:
|
|||||||
google_wallet_service._http_client = mock_http
|
google_wallet_service._http_client = mock_http
|
||||||
google_wallet_service._credentials = MagicMock()
|
google_wallet_service._credentials = MagicMock()
|
||||||
|
|
||||||
# Create a test customer
|
|
||||||
from app.modules.customers.models import Customer
|
|
||||||
customer = Customer(
|
|
||||||
email=f"wallet_test_{uuid.uuid4().hex[:8]}@test.com",
|
|
||||||
first_name="Wallet",
|
|
||||||
last_name="Test",
|
|
||||||
is_active=True,
|
|
||||||
)
|
|
||||||
db.add(customer)
|
|
||||||
db.commit()
|
|
||||||
|
|
||||||
# Enroll via card_service
|
# Enroll via card_service
|
||||||
from app.modules.loyalty.services.card_service import card_service
|
from app.modules.loyalty.services.card_service import card_service
|
||||||
card = card_service.enroll_customer(db, customer.id, wt_merchant.id)
|
card = card_service.enroll_customer(db, test_customer.id, test_merchant.id)
|
||||||
|
|
||||||
# Verify wallet DB fields are populated
|
# Verify wallet DB fields are populated
|
||||||
db.refresh(card)
|
db.refresh(card)
|
||||||
@@ -384,20 +360,12 @@ class TestEnrollmentWalletCreation:
|
|||||||
google_wallet_service._http_client = None
|
google_wallet_service._http_client = None
|
||||||
google_wallet_service._credentials = None
|
google_wallet_service._credentials = None
|
||||||
|
|
||||||
def test_enrollment_succeeds_without_wallet_config(self, db, wt_program, wt_merchant):
|
def test_enrollment_succeeds_without_wallet_config(
|
||||||
|
self, db, wt_program, test_merchant, test_customer
|
||||||
|
):
|
||||||
"""Enrollment works even when Google Wallet is not configured."""
|
"""Enrollment works even when Google Wallet is not configured."""
|
||||||
from app.modules.customers.models import Customer
|
|
||||||
customer = Customer(
|
|
||||||
email=f"no_wallet_{uuid.uuid4().hex[:8]}@test.com",
|
|
||||||
first_name="No",
|
|
||||||
last_name="Wallet",
|
|
||||||
is_active=True,
|
|
||||||
)
|
|
||||||
db.add(customer)
|
|
||||||
db.commit()
|
|
||||||
|
|
||||||
from app.modules.loyalty.services.card_service import card_service
|
from app.modules.loyalty.services.card_service import card_service
|
||||||
card = card_service.enroll_customer(db, customer.id, wt_merchant.id)
|
card = card_service.enroll_customer(db, test_customer.id, test_merchant.id)
|
||||||
|
|
||||||
db.refresh(card)
|
db.refresh(card)
|
||||||
assert card.id is not None
|
assert card.id is not None
|
||||||
@@ -407,25 +375,15 @@ class TestEnrollmentWalletCreation:
|
|||||||
|
|
||||||
@patch("app.modules.loyalty.services.google_wallet_service.settings")
|
@patch("app.modules.loyalty.services.google_wallet_service.settings")
|
||||||
def test_enrollment_with_apple_wallet_sets_serial(
|
def test_enrollment_with_apple_wallet_sets_serial(
|
||||||
self, mock_settings, db, wt_program_with_apple
|
self, mock_settings, db, wt_program_with_apple, test_customer
|
||||||
):
|
):
|
||||||
"""Enrollment sets apple_serial_number when program has apple_pass_type_id."""
|
"""Enrollment sets apple_serial_number when program has apple_pass_type_id."""
|
||||||
mock_settings.loyalty_google_issuer_id = None
|
mock_settings.loyalty_google_issuer_id = None
|
||||||
mock_settings.loyalty_google_service_account_json = None
|
mock_settings.loyalty_google_service_account_json = None
|
||||||
|
|
||||||
from app.modules.customers.models import Customer
|
|
||||||
customer = Customer(
|
|
||||||
email=f"apple_test_{uuid.uuid4().hex[:8]}@test.com",
|
|
||||||
first_name="Apple",
|
|
||||||
last_name="Test",
|
|
||||||
is_active=True,
|
|
||||||
)
|
|
||||||
db.add(customer)
|
|
||||||
db.commit()
|
|
||||||
|
|
||||||
from app.modules.loyalty.services.card_service import card_service
|
from app.modules.loyalty.services.card_service import card_service
|
||||||
card = card_service.enroll_customer(
|
card = card_service.enroll_customer(
|
||||||
db, customer.id, wt_program_with_apple.merchant_id
|
db, test_customer.id, wt_program_with_apple.merchant_id
|
||||||
)
|
)
|
||||||
|
|
||||||
db.refresh(card)
|
db.refresh(card)
|
||||||
|
|||||||
Reference in New Issue
Block a user