Some checks failed
System Monitoring / Health Checks (push) Has been cancelled
System Monitoring / Performance Monitoring (push) Has been cancelled
System Monitoring / Database Monitoring (push) Has been cancelled
System Monitoring / Cache Monitoring (push) Has been cancelled
System Monitoring / Log Monitoring (push) Has been cancelled
System Monitoring / Resource Monitoring (push) Has been cancelled
System Monitoring / Uptime Monitoring (push) Has been cancelled
System Monitoring / Backup Monitoring (push) Has been cancelled
System Monitoring / Security Monitoring (push) Has been cancelled
System Monitoring / Monitoring Dashboard (push) Has been cancelled
System Monitoring / Alerting (push) Has been cancelled
Security Scanning / Dependency Scanning (push) Has been cancelled
Security Scanning / Code Security Scanning (push) Has been cancelled
Security Scanning / Secrets Scanning (push) Has been cancelled
Security Scanning / Container Security Scanning (push) Has been cancelled
Security Scanning / Compliance Checking (push) Has been cancelled
Security Scanning / Security Dashboard (push) Has been cancelled
Security Scanning / Security Remediation (push) Has been cancelled
322 lines
12 KiB
Python
322 lines
12 KiB
Python
"""
|
|
Integration test for tenant registration flow.
|
|
This test MUST fail before implementation.
|
|
"""
|
|
|
|
import pytest
|
|
from django.test import TestCase
|
|
from django.urls import reverse
|
|
from rest_framework.test import APIClient
|
|
from rest_framework import status
|
|
import json
|
|
|
|
|
|
class TenantRegistrationIntegrationTest(TestCase):
|
|
def setUp(self):
|
|
self.client = APIClient()
|
|
|
|
# Super admin authentication header
|
|
self.admin_auth = {'HTTP_AUTHORIZATION': 'Bearer super_admin_token'}
|
|
|
|
# Test tenant data
|
|
self.tenant_data = {
|
|
'name': 'Test Healthcare Sdn Bhd',
|
|
'email': 'info@testhealthcare.com',
|
|
'phone': '+60312345678',
|
|
'address': {
|
|
'street': '123 Medical Street',
|
|
'city': 'Kuala Lumpur',
|
|
'state': 'Wilayah Persekutuan',
|
|
'postal_code': '50400',
|
|
'country': 'Malaysia'
|
|
},
|
|
'business_type': 'HEALTHCARE',
|
|
'subscription_plan': 'GROWTH',
|
|
'pricing_model': 'SUBSCRIPTION',
|
|
'admin_user': {
|
|
'name': 'Dr. Sarah Johnson',
|
|
'email': 'sarah.johnson@testhealthcare.com',
|
|
'password': 'SecurePassword123!',
|
|
'role': 'TENANT_ADMIN',
|
|
'phone': '+60123456789'
|
|
}
|
|
}
|
|
|
|
def test_complete_tenant_registration_flow(self):
|
|
"""Test complete tenant registration from creation to admin setup."""
|
|
# Step 1: Create tenant (should fail before implementation)
|
|
tenant_response = self.client.post(
|
|
'/api/v1/tenants/',
|
|
data=json.dumps(self.tenant_data),
|
|
content_type='application/json',
|
|
**self.admin_auth
|
|
)
|
|
|
|
assert tenant_response.status_code == status.HTTP_201_CREATED
|
|
tenant_data = tenant_response.json()
|
|
|
|
# Verify tenant structure
|
|
assert 'id' in tenant_data
|
|
assert tenant_data['name'] == self.tenant_data['name']
|
|
assert tenant_data['email'] == self.tenant_data['email']
|
|
assert tenant_data['business_type'] == self.tenant_data['business_type']
|
|
assert tenant_data['status'] == 'PENDING'
|
|
|
|
# Step 2: Verify tenant admin user was created
|
|
# First, authenticate as super admin to get user list
|
|
users_response = self.client.get(
|
|
'/api/v1/users/',
|
|
**self.admin_auth
|
|
)
|
|
|
|
assert users_response.status_code == status.HTTP_200_OK
|
|
users_data = users_response.json()
|
|
|
|
# Find the newly created admin user
|
|
admin_user = None
|
|
for user in users_data['users']:
|
|
if user['email'] == self.tenant_data['admin_user']['email']:
|
|
admin_user = user
|
|
break
|
|
|
|
assert admin_user is not None
|
|
assert admin_user['name'] == self.tenant_data['admin_user']['name']
|
|
assert admin_user['role'] == 'TENANT_ADMIN'
|
|
assert admin_user['tenant_id'] == tenant_data['id']
|
|
|
|
# Step 3: Verify subscription was created for tenant
|
|
subscription_response = self.client.get(
|
|
'/api/v1/subscriptions/',
|
|
data={'tenant_id': tenant_data['id']},
|
|
**self.admin_auth
|
|
)
|
|
|
|
assert subscription_response.status_code == status.HTTP_200_OK
|
|
subscriptions_data = subscription_response.json()
|
|
|
|
assert len(subscriptions_data['subscriptions']) == 1
|
|
subscription = subscriptions_data['subscriptions'][0]
|
|
assert subscription['tenant_id'] == tenant_data['id']
|
|
assert subscription['plan'] == self.tenant_data['subscription_plan']
|
|
assert subscription['status'] == 'TRIAL'
|
|
|
|
# Step 4: Test tenant admin authentication
|
|
# Login as tenant admin
|
|
login_data = {
|
|
'email': self.tenant_data['admin_user']['email'],
|
|
'password': self.tenant_data['admin_user']['password']
|
|
}
|
|
|
|
auth_response = self.client.post(
|
|
'/api/v1/auth/login/',
|
|
data=json.dumps(login_data),
|
|
content_type='application/json'
|
|
)
|
|
|
|
assert auth_response.status_code == status.HTTP_200_OK
|
|
auth_data = auth_response.json()
|
|
|
|
assert 'access_token' in auth_data
|
|
assert 'refresh_token' in auth_data
|
|
assert 'user' in auth_data
|
|
|
|
# Verify user info in token
|
|
user_info = auth_data['user']
|
|
assert user_info['email'] == self.tenant_data['admin_user']['email']
|
|
assert user_info['tenant_id'] == tenant_data['id']
|
|
|
|
# Step 5: Test tenant admin can access their tenant data
|
|
tenant_admin_auth = {'HTTP_AUTHORIZATION': f'Bearer {auth_data["access_token"]}'}
|
|
|
|
tenant_own_response = self.client.get(
|
|
'/api/v1/tenants/',
|
|
**tenant_admin_auth
|
|
)
|
|
|
|
assert tenant_own_response.status_code == status.HTTP_200_OK
|
|
tenant_own_data = tenant_own_response.json()
|
|
|
|
# Should only see their own tenant
|
|
assert len(tenant_own_data['tenants']) == 1
|
|
assert tenant_own_data['tenants'][0]['id'] == tenant_data['id']
|
|
|
|
# Step 6: Test tenant isolation - cannot see other tenants
|
|
# Create another tenant as super admin
|
|
other_tenant_data = self.tenant_data.copy()
|
|
other_tenant_data['name'] = 'Other Healthcare Sdn Bhd'
|
|
other_tenant_data['email'] = 'info@otherhealthcare.com'
|
|
other_tenant_data['admin_user']['email'] = 'admin@otherhealthcare.com'
|
|
|
|
other_tenant_response = self.client.post(
|
|
'/api/v1/tenants/',
|
|
data=json.dumps(other_tenant_data),
|
|
content_type='application/json',
|
|
**self.admin_auth
|
|
)
|
|
|
|
assert other_tenant_response.status_code == status.HTTP_201_CREATED
|
|
|
|
# First tenant admin should still only see their own tenant
|
|
tenant_still_own_response = self.client.get(
|
|
'/api/v1/tenants/',
|
|
**tenant_admin_auth
|
|
)
|
|
|
|
assert tenant_still_own_response.status_code == status.HTTP_200_OK
|
|
tenant_still_own_data = tenant_still_own_response.json()
|
|
|
|
# Should still only see their own tenant
|
|
assert len(tenant_still_own_data['tenants']) == 1
|
|
assert tenant_still_own_data['tenants'][0]['id'] == tenant_data['id']
|
|
|
|
def test_tenant_registration_invalid_business_type(self):
|
|
"""Test tenant registration with invalid business type."""
|
|
invalid_data = self.tenant_data.copy()
|
|
invalid_data['business_type'] = 'INVALID_TYPE'
|
|
|
|
response = self.client.post(
|
|
'/api/v1/tenants/',
|
|
data=json.dumps(invalid_data),
|
|
content_type='application/json',
|
|
**self.admin_auth
|
|
)
|
|
|
|
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
|
|
|
def test_tenant_registration_missing_admin_user(self):
|
|
"""Test tenant registration without admin user data."""
|
|
invalid_data = self.tenant_data.copy()
|
|
del invalid_data['admin_user']
|
|
|
|
response = self.client.post(
|
|
'/api/v1/tenants/',
|
|
data=json.dumps(invalid_data),
|
|
content_type='application/json',
|
|
**self.admin_auth
|
|
)
|
|
|
|
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
|
|
|
def test_tenant_registration_duplicate_email(self):
|
|
"""Test tenant registration with duplicate email."""
|
|
# Create first tenant
|
|
first_response = self.client.post(
|
|
'/api/v1/tenants/',
|
|
data=json.dumps(self.tenant_data),
|
|
content_type='application/json',
|
|
**self.admin_auth
|
|
)
|
|
|
|
assert first_response.status_code == status.HTTP_201_CREATED
|
|
|
|
# Try to create second tenant with same email
|
|
second_response = self.client.post(
|
|
'/api/v1/tenants/',
|
|
data=json.dumps(self.tenant_data),
|
|
content_type='application/json',
|
|
**self.admin_auth
|
|
)
|
|
|
|
assert second_response.status_code == status.HTTP_400_BAD_REQUEST
|
|
|
|
def test_tenant_registration_unauthorized(self):
|
|
"""Test tenant registration without admin authentication."""
|
|
response = self.client.post(
|
|
'/api/v1/tenants/',
|
|
data=json.dumps(self.tenant_data),
|
|
content_type='application/json'
|
|
)
|
|
|
|
assert response.status_code == status.HTTP_401_UNAUTHORIZED
|
|
|
|
def test_tenant_registration_weak_admin_password(self):
|
|
"""Test tenant registration with weak admin password."""
|
|
invalid_data = self.tenant_data.copy()
|
|
invalid_data['admin_user']['password'] = '123'
|
|
|
|
response = self.client.post(
|
|
'/api/v1/tenants/',
|
|
data=json.dumps(invalid_data),
|
|
content_type='application/json',
|
|
**self.admin_auth
|
|
)
|
|
|
|
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
|
|
|
def test_tenant_registration_with_modules_configuration(self):
|
|
"""Test tenant registration with specific modules configuration."""
|
|
modules_data = self.tenant_data.copy()
|
|
modules_data['modules'] = ['healthcare', 'appointments', 'billing']
|
|
modules_data['modules_config'] = {
|
|
'healthcare': {
|
|
'features': ['patient_management', 'appointment_scheduling', 'medical_records'],
|
|
'settings': {
|
|
'enable_telemedicine': True,
|
|
'appointment_reminders': True
|
|
}
|
|
}
|
|
}
|
|
|
|
response = self.client.post(
|
|
'/api/v1/tenants/',
|
|
data=json.dumps(modules_data),
|
|
content_type='application/json',
|
|
**self.admin_auth
|
|
)
|
|
|
|
if response.status_code == status.HTTP_201_CREATED:
|
|
tenant_data = response.json()
|
|
# Should have modules configuration
|
|
assert 'modules' in tenant_data
|
|
assert 'modules_config' in tenant_data
|
|
|
|
def test_tenant_registration_with_branding(self):
|
|
"""Test tenant registration with branding information."""
|
|
branding_data = self.tenant_data.copy()
|
|
branding_data['branding'] = {
|
|
'logo_url': 'https://example.com/logo.png',
|
|
'primary_color': '#2563eb',
|
|
'secondary_color': '#64748b',
|
|
'company_website': 'https://testhealthcare.com',
|
|
'social_media': {
|
|
'facebook': 'testhealthcare',
|
|
'instagram': 'testhealthcare_my'
|
|
}
|
|
}
|
|
|
|
response = self.client.post(
|
|
'/api/v1/tenants/',
|
|
data=json.dumps(branding_data),
|
|
content_type='application/json',
|
|
**self.admin_auth
|
|
)
|
|
|
|
if response.status_code == status.HTTP_201_CREATED:
|
|
tenant_data = response.json()
|
|
# Should have branding information
|
|
assert 'branding' in tenant_data
|
|
assert tenant_data['branding']['primary_color'] == '#2563eb'
|
|
|
|
def test_tenant_registration_domain_setup(self):
|
|
"""Test tenant registration with custom domain setup."""
|
|
domain_data = self.tenant_data.copy()
|
|
domain_data['domain'] = 'portal.testhealthcare.com'
|
|
domain_data['settings'] = {
|
|
'custom_domain_enabled': True,
|
|
'ssl_enabled': True,
|
|
'email_domain': 'testhealthcare.com'
|
|
}
|
|
|
|
response = self.client.post(
|
|
'/api/v1/tenants/',
|
|
data=json.dumps(domain_data),
|
|
content_type='application/json',
|
|
**self.admin_auth
|
|
)
|
|
|
|
if response.status_code == status.HTTP_201_CREATED:
|
|
tenant_data = response.json()
|
|
# Should have domain configuration
|
|
assert 'domain' in tenant_data
|
|
assert 'settings' in tenant_data
|
|
assert tenant_data['domain'] == 'portal.testhealthcare.com' |