feat(marketing): register 3 new Flask blueprints (marketing, billing, legal)
- marketing_bp at root "/" - billing_bp at /checkout/* (routes added in B-2.7) - legal_bp at /legal/* (routes added in B-2.9) - Tests verify all 3 blueprints register correctly - Coexists with existing recordings_bp at "/" (resolved in B-1.3)
This commit is contained in:
13
src/app.py
13
src/app.py
@@ -585,6 +585,11 @@ from src.api.api_v1 import api_v1_bp, init_api_v1_helpers
|
||||
from src.api.audit import audit_bp
|
||||
from src.api.docs import docs_bp
|
||||
|
||||
# Marketing redesign 2026 blueprints (Phase 1: B-1.2)
|
||||
from src.marketing import marketing_bp
|
||||
from src.billing import billing_bp
|
||||
from src.legal import legal_bp
|
||||
|
||||
# Database initialization (extracted to src/init_db.py)
|
||||
from src.init_db import initialize_database
|
||||
with app.app_context():
|
||||
@@ -632,6 +637,14 @@ csrf.exempt(api_v1_bp) # API v1 uses token auth, not CSRF
|
||||
app.register_blueprint(audit_bp)
|
||||
app.register_blueprint(docs_bp)
|
||||
|
||||
# Marketing redesign 2026 blueprints (Phase 1: B-1.2)
|
||||
# - marketing_bp at "/" (placeholder; coexists with recordings_bp.index, resolved in B-1.3)
|
||||
# - billing_bp at /checkout/* (routes added in B-2.7 and B-2.8)
|
||||
# - legal_bp at /legal/* (routes added in B-2.9)
|
||||
app.register_blueprint(marketing_bp)
|
||||
app.register_blueprint(billing_bp)
|
||||
app.register_blueprint(legal_bp)
|
||||
|
||||
# File monitor and scheduler initialization functions below
|
||||
|
||||
# Startup functions (extracted to src/config/startup.py)
|
||||
|
||||
11
src/billing/__init__.py
Normal file
11
src/billing/__init__.py
Normal file
@@ -0,0 +1,11 @@
|
||||
"""Billing blueprint - Stripe Checkout, webhook, subscription management.
|
||||
|
||||
Mounted at /checkout/* prefix for the customer-facing checkout flow. The
|
||||
/webhooks/stripe route (added in B-2.8) bypasses the prefix and is also
|
||||
csrf-exempted.
|
||||
|
||||
Routes added in Tasks B-2.7 (checkout) and B-2.8 (webhook).
|
||||
"""
|
||||
from flask import Blueprint
|
||||
|
||||
billing_bp = Blueprint('billing', __name__, url_prefix='/checkout')
|
||||
11
src/legal/__init__.py
Normal file
11
src/legal/__init__.py
Normal file
@@ -0,0 +1,11 @@
|
||||
"""Legal blueprint - Conditions, Confidentialite (Loi 25), Cookies, Remboursement,
|
||||
Accessibilite, Mentions.
|
||||
|
||||
Mounted at /legal/* prefix. Content rendered from markdown files in
|
||||
src/legal/content/ (added in Task B-2.9).
|
||||
|
||||
Routes added in Task B-2.9.
|
||||
"""
|
||||
from flask import Blueprint
|
||||
|
||||
legal_bp = Blueprint('legal', __name__, url_prefix='/legal')
|
||||
11
src/marketing/__init__.py
Normal file
11
src/marketing/__init__.py
Normal file
@@ -0,0 +1,11 @@
|
||||
"""Marketing blueprint - landing pages, public content, SEO/GEO assets.
|
||||
|
||||
Mounted at root "/" (no url_prefix). Coexists with the legacy /api/* and /app/*
|
||||
blueprints. Routes added incrementally in Phase 2 (Tasks A-2.x).
|
||||
"""
|
||||
from flask import Blueprint
|
||||
|
||||
marketing_bp = Blueprint('marketing', __name__)
|
||||
|
||||
# Import routes module so it registers route handlers via decorators
|
||||
from . import routes # noqa: E402,F401
|
||||
20
src/marketing/routes.py
Normal file
20
src/marketing/routes.py
Normal file
@@ -0,0 +1,20 @@
|
||||
"""Marketing routes - minimal Phase 1 placeholder.
|
||||
|
||||
Real templates and content arrive in Tasks A-2.1 through A-2.8.
|
||||
"""
|
||||
from flask import Response
|
||||
|
||||
from . import marketing_bp
|
||||
|
||||
|
||||
@marketing_bp.route('/')
|
||||
def landing():
|
||||
"""Placeholder root route.
|
||||
|
||||
Phase 1: returns a minimal HTML response so the route exists for tests.
|
||||
Phase 2 (A-2.1): replaced with proper template render.
|
||||
"""
|
||||
return Response(
|
||||
'<!DOCTYPE html><html><body><p>DictIA marketing - Phase 1 bootstrap</p></body></html>',
|
||||
mimetype='text/html'
|
||||
)
|
||||
66
tests/test_blueprint_registration.py
Normal file
66
tests/test_blueprint_registration.py
Normal file
@@ -0,0 +1,66 @@
|
||||
"""Tests for Phase 1 blueprint registration (B-1.2).
|
||||
|
||||
Verifies that the 3 new marketing-redesign blueprints (marketing, billing,
|
||||
legal) register correctly on the global Flask app, in addition to the
|
||||
existing api/auth/recordings/etc. blueprints.
|
||||
|
||||
Pattern: no conftest.py, env vars set at module load time, then import
|
||||
src.app.app directly. Mirrors the convention used by tests/test_audit.py.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Add the parent directory to the path to import app (mirrors test_audit.py)
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
os.environ.setdefault('SQLALCHEMY_DATABASE_URI', 'sqlite:///:memory:')
|
||||
os.environ.setdefault('SECRET_KEY', 'test-secret-key-for-blueprint-registration')
|
||||
|
||||
from src.app import app # noqa: E402
|
||||
|
||||
|
||||
def test_marketing_blueprint_registered():
|
||||
assert 'marketing' in app.blueprints, (
|
||||
f"Expected marketing blueprint, found: {list(app.blueprints.keys())}"
|
||||
)
|
||||
|
||||
|
||||
def test_billing_blueprint_registered():
|
||||
assert 'billing' in app.blueprints, (
|
||||
f"Expected billing blueprint, found: {list(app.blueprints.keys())}"
|
||||
)
|
||||
|
||||
|
||||
def test_legal_blueprint_registered():
|
||||
assert 'legal' in app.blueprints, (
|
||||
f"Expected legal blueprint, found: {list(app.blueprints.keys())}"
|
||||
)
|
||||
|
||||
|
||||
def test_marketing_landing_route_exists():
|
||||
"""The marketing blueprint should expose at least a placeholder root route."""
|
||||
rules = [str(r) for r in app.url_map.iter_rules() if r.endpoint.startswith('marketing.')]
|
||||
assert any('/' in r for r in rules), (
|
||||
f"Expected marketing blueprint to have a route, found: {rules}"
|
||||
)
|
||||
|
||||
|
||||
def test_legal_blueprint_has_url_prefix():
|
||||
"""Legal blueprint should be mounted at /legal/* prefix."""
|
||||
rules = [str(r) for r in app.url_map.iter_rules() if r.endpoint.startswith('legal.')]
|
||||
assert all('/legal' in r for r in rules), (
|
||||
f"Expected /legal/ prefix on all legal routes, found: {rules}"
|
||||
)
|
||||
|
||||
|
||||
def test_billing_blueprint_has_url_prefix():
|
||||
"""Billing blueprint should be mounted at /checkout/* prefix.
|
||||
|
||||
Phase 1 minimum: blueprint is registered but may have no routes yet.
|
||||
Routes added in B-2.7 (checkout) and B-2.8 (webhook).
|
||||
"""
|
||||
rules = [str(r) for r in app.url_map.iter_rules() if r.endpoint.startswith('billing.')]
|
||||
# Allow billing routes that don't start with /checkout (e.g. /webhooks/stripe added later)
|
||||
# but at least placeholder /checkout/<plan> route should exist
|
||||
assert len(rules) >= 0 # Phase 1 minimum: blueprint registered, routes added in B-2.7
|
||||
Reference in New Issue
Block a user