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

1""" 

2Teacher Theme Routes 

3 

4This module defines the API routes for teacher profile themes, allowing teachers to 

5customize their profile appearance with different visual themes. 

6 

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""" 

13 

14from fastapi import APIRouter, Body, Depends, Request, status 

15from typing import Dict, Any 

16 

17# Authentication 

18from server.authentication.auth0_bearer import Auth0Bearer 

19 

20# Models 

21from server.models.themes import ThemeApply, ThemeResponse, ThemeUpdate 

22 

23# Services 

24from server.services.teacher.teacher_theme import TeacherThemeService 

25 

26router = APIRouter() 

27theme_service = TeacherThemeService() 

28 

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. 

76  

77 Args: 

78 request (Request): The HTTP request containing user authentication 

79  

80 Returns: 

81 ThemeResponse: The current theme details 

82 """ 

83 return await theme_service.get_current_theme(request) 

84 

85 

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. 

137  

138 Args: 

139 request (Request): The HTTP request containing user authentication 

140 theme_data (ThemeApply): The theme ID to apply 

141  

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) 

146 

147 

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. 

171 

172 Args: 

173 request (Request): The HTTP request containing user authentication 

174 theme_data (ThemeUpdate): Partial theme data to update 

175 

176 Returns: 

177 ThemeResponse: The updated theme details 

178 """ 

179 return await theme_service.update_theme(request, theme_data) 

180 

181 

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). 

201 

202 Args: 

203 request (Request): The HTTP request containing user authentication 

204 

205 Returns: 

206 Dict: Default theme details after deletion 

207 """ 

208 return await theme_service.delete_theme(request)