Coverage for server / routes / teacher / teacher_theme.py: 100%
19 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-10-04 09:33 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-10-04 09:33 +0000
1"""
2Teacher Theme Routes
4This module defines the API routes for teacher profile themes, allowing teachers to
5customize their profile appearance with different visual themes.
7Routes:
8- GET /v1/teacher/account/theme/fetch - Get current theme
9- POST /v1/teacher/account/theme/apply - Apply a new theme
10- PUT /v1/teacher/account/theme/update - Update theme settings
11- DELETE /v1/teacher/account/theme/delete - Delete theme and revert to default
12"""
14from fastapi import APIRouter, Body, Depends, Request, status
15from typing import Dict, Any
17# Authentication
18from server.authentication.auth0_bearer import Auth0Bearer
20# Models
21from server.models.themes import ThemeApply, ThemeResponse, ThemeUpdate
23# Services
24from server.services.teacher.teacher_theme import TeacherThemeService
26router = APIRouter()
27theme_service = TeacherThemeService()
29@router.get(
30 "/fetch",
31 dependencies=[Depends(Auth0Bearer(access_levels=["teacher"]))],
32 status_code=status.HTTP_200_OK,
33 response_model=Dict,
34 description="As a teacher, I can fetch my current profile theme information",
35 summary="Get current profile theme information",
36 responses={
37 200: {
38 "description": "Successfully retrieved theme details",
39 "content": {
40 "application/json": {
41 "example": {
42 "theme_id": "dark-mode",
43 "theme_name": "Dark Mode",
44 "colors": {
45 "primary": "#7b68ee",
46 "secondary": "#6c757d",
47 "accent": "#00c6a9",
48 "text": "#f8f9fa",
49 "background": "#212529"
50 },
51 "font": {
52 "family": "Roboto, sans-serif",
53 "size": "16px",
54 "heading_scale": 1.2
55 },
56 "layout": {
57 "spacing": "16px",
58 "border_radius": "4px",
59 "card_style": "shadow"
60 },
61 "is_default": False,
62 "created_at": "2025-02-15T12:00:00Z",
63 "updated_at": "2025-02-15T12:00:00Z"
64 }
65 }
66 }
67 },
68 401: {"description": "Invalid or missing authentication"},
69 404: {"description": "No theme found"},
70 500: {"description": "Server-side issue"}
71 }
72)
73async def fetch_theme(request: Request) -> Dict:
74 """
75 Get the current theme for the authenticated teacher.
77 Args:
78 request (Request): The HTTP request containing user authentication
80 Returns:
81 ThemeResponse: The current theme details
82 """
83 return await theme_service.get_current_theme(request)
86@router.post(
87 "/apply",
88 dependencies=[Depends(Auth0Bearer(access_levels=["teacher"]))],
89 status_code=status.HTTP_201_CREATED,
90 response_model=ThemeResponse,
91 description="As a teacher, I can apply a new theme to my profile",
92 summary="Apply a new theme to profile",
93 responses={
94 201: {
95 "description": "New theme successfully applied",
96 "content": {
97 "application/json": {
98 "example": {
99 "theme_id": "light-blue",
100 "theme_name": "Light Blue",
101 "colors": {
102 "primary": "#0d6efd",
103 "secondary": "#6c757d",
104 "accent": "#0dcaf0",
105 "text": "#212529",
106 "background": "#f8f9fa"
107 },
108 "font": {
109 "family": "Open Sans, sans-serif",
110 "size": "16px",
111 "heading_scale": 1.2
112 },
113 "layout": {
114 "spacing": "14px",
115 "border_radius": "6px",
116 "card_style": "shadow"
117 },
118 "is_default": False,
119 "created_at": "2025-01-10T10:30:00Z",
120 "updated_at": "2025-01-10T10:30:00Z"
121 }
122 }
123 }
124 },
125 400: {"description": "Invalid theme ID"},
126 401: {"description": "Invalid or missing authentication"},
127 404: {"description": "Theme not found"},
128 500: {"description": "Server-side issue"}
129 }
130)
131async def apply_theme(
132 request: Request,
133 theme_data: ThemeApply = Body(...)
134) -> ThemeResponse:
135 """
136 Apply a theme to the authenticated teacher's profile.
138 Args:
139 request (Request): The HTTP request containing user authentication
140 theme_data (ThemeApply): The theme ID to apply
142 Returns:
143 ThemeResponse: The applied theme details
144 """
145 return await theme_service.apply_theme(request, theme_data.theme_id, theme_data.color_mode)
148@router.put(
149 "/update",
150 dependencies=[Depends(Auth0Bearer(access_levels=["teacher"]))],
151 status_code=status.HTTP_200_OK,
152 response_model=ThemeResponse,
153 description="As a teacher, I can update my current theme settings",
154 summary="Update current theme settings",
155 responses={
156 200: {
157 "description": "Theme settings updated successfully",
158 },
159 400: {"description": "Invalid theme data"},
160 401: {"description": "Invalid or missing authentication"},
161 404: {"description": "No active theme found"},
162 500: {"description": "Server-side issue"}
163 }
164)
165async def update_theme(
166 request: Request,
167 theme_data: ThemeUpdate = Body(...)
168) -> ThemeResponse:
169 """
170 Update the current theme settings for the authenticated teacher.
172 Args:
173 request (Request): The HTTP request containing user authentication
174 theme_data (ThemeUpdate): Partial theme data to update
176 Returns:
177 ThemeResponse: The updated theme details
178 """
179 return await theme_service.update_theme(request, theme_data)
182@router.delete(
183 "/delete",
184 dependencies=[Depends(Auth0Bearer(access_levels=["teacher"]))],
185 status_code=status.HTTP_200_OK,
186 response_model=Dict,
187 description="As a teacher, I can delete my theme and revert to default",
188 summary="Delete theme and revert to default",
189 responses={
190 200: {
191 "description": "Theme deleted, reverted to default",
192 },
193 401: {"description": "Invalid or missing authentication"},
194 404: {"description": "No active theme found to delete"},
195 500: {"description": "Server-side issue"}
196 }
197)
198async def delete_theme(request: Request) -> Dict:
199 """
200 Delete the active theme for the authenticated teacher (soft delete).
202 Args:
203 request (Request): The HTTP request containing user authentication
205 Returns:
206 Dict: Default theme details after deletion
207 """
208 return await theme_service.delete_theme(request)