#!/usr/bin/env python3 """ Test script for subscription feature flag endpoints (Gitea #239). Tests: GET /subscriptions/my, GET /subscriptions/feature-flags, GET /subscriptions/check/{key} """ import asyncio import httpx import sys BASE_URL = "http://sf_api:8000/api/v1" async def main(): async with httpx.AsyncClient(base_url=BASE_URL) as client: # ── Step 1: Login with OAuth2 form data ── print("=" * 60) print("STEP 1: Login with admin user") print("=" * 60) login_data = { "username": "admin@profibot.hu", "password": "Admin123!", "grant_type": "password", } login_resp = await client.post( "/auth/login", data=login_data, # OAuth2 form data headers={"Content-Type": "application/x-www-form-urlencoded"}, ) if login_resp.status_code != 200: print(f"❌ Login failed: {login_resp.status_code}") print(f" Response: {login_resp.text}") sys.exit(1) token_data = login_resp.json() token = token_data.get("access_token") print(f"✅ Login OK — token: {token[:50]}...") headers = {"Authorization": f"Bearer {token}"} # ── Step 2: GET /subscriptions/my ── print("\n" + "=" * 60) print("STEP 2: GET /subscriptions/my") print("=" * 60) resp = await client.get("/subscriptions/my", headers=headers) if resp.status_code == 200: data = resp.json() print(f"✅ Status: 200") print(f" Tier: {data.get('tier')}") print(f" Source: {data.get('source')}") print(f" Expires: {data.get('expires_at')}") features = data.get('features', {}) print(f" Features count: {len(features)}") # Show first 5 features for i, (k, v) in enumerate(features.items()): if i >= 5: print(f" ... and {len(features) - 5} more") break print(f" - {k}: {v}") sub = data.get('subscription') if sub: print(f" Subscription tier_name: {sub.get('tier_name')}") print(f" Subscription display_name: {sub.get('display_name')}") else: print(f"❌ Failed: {resp.status_code}") print(f" Response: {resp.text[:500]}") # ── Step 3: GET /subscriptions/feature-flags ── print("\n" + "=" * 60) print("STEP 3: GET /subscriptions/feature-flags") print("=" * 60) resp = await client.get("/subscriptions/feature-flags", headers=headers) if resp.status_code == 200: data = resp.json() print(f"✅ Status: 200") print(f" Tier: {data.get('tier')}") features = data.get('features', {}) print(f" Features count: {len(features)}") # Show all features for k, v in sorted(features.items()): print(f" - {k}: {v}") else: print(f"❌ Failed: {resp.status_code}") print(f" Response: {resp.text[:500]}") # ── Step 4: GET /subscriptions/check/{feature_key} ── print("\n" + "=" * 60) print("STEP 4: GET /subscriptions/check/analytics_tco") print("=" * 60) resp = await client.get("/subscriptions/check/analytics_tco", headers=headers) if resp.status_code == 200: data = resp.json() print(f"✅ Status: 200") print(f" feature_key: {data.get('feature_key')}") print(f" granted: {data.get('granted')}") print(f" tier: {data.get('tier')}") print(f" required_tier: {data.get('required_tier')}") else: print(f"❌ Failed: {resp.status_code}") print(f" Response: {resp.text[:500]}") # ── Step 5: GET /subscriptions/check/unknown_feature ── print("\n" + "=" * 60) print("STEP 5: GET /subscriptions/check/unknown_feature (expect 404)") print("=" * 60) resp = await client.get("/subscriptions/check/unknown_feature", headers=headers) if resp.status_code == 404: print(f"✅ Correctly returned 404 for unknown feature") else: print(f"❌ Expected 404, got {resp.status_code}") print(f" Response: {resp.text[:500]}") # ── Step 6: GET /subscriptions/public ── print("\n" + "=" * 60) print("STEP 6: GET /subscriptions/public") print("=" * 60) resp = await client.get("/subscriptions/public", headers=headers) if resp.status_code == 200: data = resp.json() print(f"✅ Status: 200") print(f" Public tiers count: {len(data)}") for tier in data[:3]: print(f" - {tier.get('name')}: {tier.get('resolved_pricing', {}).get('monthly_price', 'N/A')}") else: print(f"❌ Failed: {resp.status_code}") print(f" Response: {resp.text[:500]}") print("\n" + "=" * 60) print("✅ ALL TESTS COMPLETED") print("=" * 60) if __name__ == "__main__": asyncio.run(main())