test: add comprehensive integration test suite for IAM platform

Add 162 integration tests covering authentication flows, TOTP MFA,
SSH key/certificate management, organization workflows, multi-org
access, self-service features, admin operations, authorization,
security edge cases, department/principal management, CA management,
policy compliance, WebAuthn passkeys, and ZeroTier network access.

Includes:
- Reusable API client library with session management
- Test fixtures for users, organizations, memberships, and CAs
- Helper functions for SSH key generation and verification
- Documentation for running and writing tests

Also update test configuration to disable conflicting maas plugins
and configure WebAuthn/session settings for localhost testing.
This commit is contained in:
2026-04-23 15:41:37 +09:30
parent eb2fc6c8b3
commit 015c622016
36 changed files with 5446 additions and 1 deletions
+143
View File
@@ -0,0 +1,143 @@
import pytest
from datetime import datetime, timezone
from gatehouse_app.extensions import db
from gatehouse_app.models.user.user import User
from gatehouse_app.models.organization.organization import Organization
from gatehouse_app.models.organization.organization_member import OrganizationMember
from gatehouse_app.models.ssh_ca.ca import CA, CaType, KeyType
from gatehouse_app.api.v1.ssh._helpers import _get_org_ca_for_user
from gatehouse_app.utils.constants import OrganizationRole
class TestCASoftDelete:
"""Test CA soft delete handling."""
def test_active_ca_is_returned(self, app, test_user, test_org, test_ca, test_membership):
"""Active CA should be returned."""
with app.app_context():
user = db.session.get(User, test_user)
ca = _get_org_ca_for_user(user, ca_type='user')
assert ca is not None
assert ca.id == test_ca
def test_deleted_ca_is_not_returned(self, app, test_user, test_org, test_membership):
"""Deleted CA should not be returned."""
with app.app_context():
ca = CA(
organization_id=test_org,
name='Deleted CA',
ca_type=CaType.USER,
key_type=KeyType.ED25519,
private_key='key',
public_key='pubkey',
fingerprint='sha256:deleted123',
is_active=True,
deleted_at=datetime.now(timezone.utc)
)
db.session.add(ca)
db.session.commit()
user = db.session.get(User, test_user)
result = _get_org_ca_for_user(user, ca_type='user')
assert result is None
def test_deleted_membership_no_access(self, app, test_org, test_ca):
"""User with deleted membership should not access CA."""
with app.app_context():
user = User(email='deleted_member@test.com', full_name='Deleted Member')
db.session.add(user)
db.session.commit()
membership = OrganizationMember(
user_id=user.id,
organization_id=test_org,
role=OrganizationRole.MEMBER,
deleted_at=datetime.now(timezone.utc)
)
db.session.add(membership)
db.session.commit()
result = _get_org_ca_for_user(user, ca_type='user')
assert result is None
def test_deleted_org_no_access(self, app):
"""User in deleted org should not access CA."""
with app.app_context():
org = Organization(
name='Deleted Org',
slug='deleted-org',
deleted_at=datetime.now(timezone.utc)
)
db.session.add(org)
db.session.commit()
user = User(email='user@deleted.org', full_name='User')
db.session.add(user)
db.session.commit()
membership = OrganizationMember(
user_id=user.id,
organization_id=org.id,
role=OrganizationRole.MEMBER
)
db.session.add(membership)
ca = CA(
organization_id=org.id,
name='CA in Deleted Org',
ca_type=CaType.USER,
key_type=KeyType.ED25519,
private_key='key',
public_key='pubkey',
fingerprint='sha256:deletedorg123',
is_active=True
)
db.session.add(ca)
db.session.commit()
result = _get_org_ca_for_user(user, ca_type='user')
assert result is None
def test_get_active_memberships_excludes_deleted(self, app, test_user, test_org, test_membership):
"""User.get_active_memberships() should exclude deleted memberships."""
with app.app_context():
user = db.session.get(User, test_user)
org2 = Organization(name='Org 2', slug='org-2')
db.session.add(org2)
db.session.commit()
membership2 = OrganizationMember(
user_id=test_user,
organization_id=org2.id,
role=OrganizationRole.MEMBER,
deleted_at=datetime.now(timezone.utc)
)
db.session.add(membership2)
db.session.commit()
active = user.get_active_memberships()
assert len(active) == 1
assert active[0].organization_id == test_org
def test_get_organizations_excludes_deleted(self, app, test_user, test_org, test_membership):
"""User.get_organizations() should exclude deleted memberships/orgs."""
with app.app_context():
user = db.session.get(User, test_user)
org2 = Organization(name='Deleted Org', slug='deleted-org-2')
db.session.add(org2)
db.session.commit()
membership2 = OrganizationMember(
user_id=test_user,
organization_id=org2.id,
role=OrganizationRole.MEMBER,
deleted_at=datetime.now(timezone.utc)
)
db.session.add(membership2)
db.session.commit()
orgs = user.get_organizations()
assert len(orgs) == 1
assert orgs[0].id == test_org