""" Unit tests for Slack OAuth state generation and verification. Tests: - generate_oauth_state produces a base64-encoded string containing tenant_id - verify_oauth_state returns the correct tenant_id for a valid state - verify_oauth_state raises ValueError for a tampered state - verify_oauth_state raises ValueError for a state signed with wrong secret """ from __future__ import annotations import pytest from shared.api.channels import generate_oauth_state, verify_oauth_state _SECRET = "test-hmac-secret-do-not-use-in-production" _TENANT_ID = "550e8400-e29b-41d4-a716-446655440000" def test_generate_oauth_state_is_string() -> None: """generate_oauth_state returns a non-empty string.""" state = generate_oauth_state(tenant_id=_TENANT_ID, secret=_SECRET) assert isinstance(state, str) assert len(state) > 0 def test_generate_oauth_state_contains_tenant_id() -> None: """ generate_oauth_state embeds the tenant_id in the state payload. Verifying the state should return the original tenant_id. """ state = generate_oauth_state(tenant_id=_TENANT_ID, secret=_SECRET) recovered = verify_oauth_state(state=state, secret=_SECRET) assert recovered == _TENANT_ID def test_verify_oauth_state_valid() -> None: """verify_oauth_state returns correct tenant_id for a freshly generated state.""" state = generate_oauth_state(tenant_id=_TENANT_ID, secret=_SECRET) result = verify_oauth_state(state=state, secret=_SECRET) assert result == _TENANT_ID def test_verify_oauth_state_tampered() -> None: """verify_oauth_state raises ValueError if the state payload is tampered.""" state = generate_oauth_state(tenant_id=_TENANT_ID, secret=_SECRET) # Tamper: append garbage to the state string tampered = state + "TAMPERED" with pytest.raises(ValueError): verify_oauth_state(state=tampered, secret=_SECRET) def test_verify_oauth_state_wrong_secret() -> None: """verify_oauth_state raises ValueError if verified with the wrong secret.""" state = generate_oauth_state(tenant_id=_TENANT_ID, secret=_SECRET) with pytest.raises(ValueError): verify_oauth_state(state=state, secret="wrong-secret") def test_generate_oauth_state_nonce_differs() -> None: """Two calls to generate_oauth_state produce different states (random nonce).""" state1 = generate_oauth_state(tenant_id=_TENANT_ID, secret=_SECRET) state2 = generate_oauth_state(tenant_id=_TENANT_ID, secret=_SECRET) # Different nonce means different state tokens assert state1 != state2 # Both must still verify correctly assert verify_oauth_state(state=state1, secret=_SECRET) == _TENANT_ID assert verify_oauth_state(state=state2, secret=_SECRET) == _TENANT_ID