66 lines
2.4 KiB
Python
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
|