app.bettersight.io/backend/tests/services/test_licence_service.py

66 lines
2.4 KiB
Python

"""
Licence validation is a 100%-coverage path per CLAUDE.md §18 — every
branch of services.licence_service.validate_email() is exercised here.
"""
from services import licence_service
from repositories.tenant_repository import tenant_repository
from repositories.seat_repository import seat_repository
def _make_tenant(status='active', max_seats=5):
return tenant_repository.create({
'name': 'G Adventures', 'email': 'pm@gadventures.com', 'domain': 'gadventures.com',
'tier': 'analyse', 'status': status, 'max_seats': max_seats,
})
def test_invalid_email_format_rejected():
result = licence_service.validate_email('not-an-email')
assert result == {'valid': False, 'reason': 'Invalid email address'}
def test_unregistered_domain_rejected():
result = licence_service.validate_email('pm@unknown-domain.com')
assert result['valid'] is False
assert result['reason'] == 'Domain not registered'
def test_inactive_tenant_rejected():
_make_tenant(status='inactive')
result = licence_service.validate_email('pm@gadventures.com')
assert result == {'valid': False, 'reason': 'Subscription inactive'}
def test_trial_tenant_is_valid_status():
_make_tenant(status='trial')
result = licence_service.validate_email('newuser@gadventures.com')
assert result['valid'] is True
assert result['tier'] == 'analyse'
def test_new_seat_registered_when_under_limit():
tenant = _make_tenant(max_seats=5)
result = licence_service.validate_email('newuser@gadventures.com')
assert result == {'valid': True, 'tier': 'analyse'}
assert seat_repository.count_active(tenant['id']) == 1
def test_existing_seat_refreshes_last_accessed_without_creating_duplicate():
tenant = _make_tenant(max_seats=5)
seat_repository.create({'tenant_id': tenant['id'], 'email': 'pm@gadventures.com', 'active': True})
result = licence_service.validate_email('pm@gadventures.com')
assert result == {'valid': True, 'tier': 'analyse'}
assert seat_repository.count_active(tenant['id']) == 1
def test_seat_limit_reached_rejects_new_seat():
tenant = _make_tenant(max_seats=1)
seat_repository.create({'tenant_id': tenant['id'], 'email': 'first@gadventures.com', 'active': True})
result = licence_service.validate_email('second@gadventures.com')
assert result == {'valid': False, 'reason': 'Seat limit reached'}
assert seat_repository.count_active(tenant['id']) == 1