Coverage for app/routes/user.py: 79%

121 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-05-02 02:49 +0000

1from flask import Blueprint, request 

2from app.services.user_service import get_user_by_id, create_user_section, get_user_section, update_user_section, update_user_class_status, update_user_settings, get_classes_by_user_id, get_all_users, delete_user, edit_user, get_user_class_status 

3from app.models.response import * 

4from flasgger import swag_from 

5from app.models.status_codes import StatusCodes 

6 

7 

8users_bp = Blueprint('users', __name__) 

9 

10 

11@users_bp.route('/users/<user_id>', methods=['GET']) 

12@swag_from({ 

13 'tags': ['Users'], 

14 'summary': 'TODO Get a specific user by ID', 

15 'description': 'Retrieves user details based on the provided user ID.', 

16 'parameters': [ 

17 { 

18 'name': 'user_id', 

19 'in': 'path', 

20 'required': True, 

21 'type': 'string', 

22 'example': '123' 

23 } 

24 ], 

25 'responses': { 

26 '200': { 

27 'description': 'User found successfully', 

28 'schema': { 

29 'type': 'object', 

30 'properties': { 

31 'id': {'type': 'string'}, 

32 'name': {'type': 'string'}, 

33 'email': {'type': 'string'} 

34 } 

35 } 

36 }, 

37 '404': { 

38 'description': 'User not found', 

39 'schema': { 

40 'type': 'object', 

41 'properties': { 

42 'error': {'type': 'string'} 

43 } 

44 } 

45 } 

46 } 

47}) 

48def get_user_route(user_id): 

49 try: 

50 user = get_user_by_id(user_id) 

51 

52 if not user: 

53 return success_response( 

54 f"User not found for id {user_id}", 

55 None, 

56 StatusCodes.NOT_FOUND 

57 ) 

58 

59 return success_response( 

60 f"User for id {user_id}", 

61 user.to_json(), 

62 StatusCodes.OK 

63 ) 

64 

65 except Exception as e: 

66 return error_response( 

67 f"Error fetching user {user_id}: {e}", 

68 None, 

69 StatusCodes.SERVER_ERROR 

70 ) 

71 

72@users_bp.route('/users/<user_id>/status', methods=['PUT']) 

73def update_user_status_route(user_id): 

74 try: 

75 data = request.get_json() 

76 new_status = data.get("status") 

77 user_class_id = data.get("userClassId") 

78 

79 valid_statuses = {"ACTIVE", "SUSPENDED", "LOCKED"} 

80 

81 if new_status not in valid_statuses: 

82 return error_response( 

83 f"Invalid status '{new_status}'. Must be one of {valid_statuses}.", 

84 None, 

85 StatusCodes.BAD_REQUEST 

86 ) 

87 

88 update_user_class_status(user_id, new_status, user_class_id) 

89 

90 return success_response( 

91 f"User status updated to '{new_status}' for user {user_id}", 

92 None, 

93 StatusCodes.OK 

94 ) 

95 

96 except Exception as e: 

97 return error_response( 

98 f"Error updating user status for {user_id}: {e}", 

99 None, 

100 StatusCodes.SERVER_ERROR 

101 ) 

102 

103@users_bp.route('/users/<user_id>/class-status', methods=['GET']) 

104@swag_from({ 

105 'tags': ['Users'], 

106 'summary': 'TODO Get lock status of a specific user by ID', 

107 'description': 'Retrieves lock status of a user based on the provided user ID.', 

108 'parameters': [ 

109 { 

110 'name': 'user_id', 

111 'in': 'path', 

112 'required': True, 

113 'type': 'string', 

114 'example': '123' 

115 } 

116 ], 

117 'responses': { 

118 '200': { 

119 'description': 'User lock status found successfully', 

120 'schema': { 

121 'type': 'object', 

122 'properties': { 

123 'id': {'type': 'string'}, 

124 'is_locked': {'type': 'boolean'} 

125 } 

126 } 

127 }, 

128 '404': { 

129 'description': 'User not found', 

130 'schema': { 

131 'type': 'object', 

132 'properties': { 

133 'error': {'type': 'string'} 

134 } 

135 } 

136 } 

137 } 

138}) 

139def get_user_class_status_route(user_id): 

140 try: 

141 class_id = request.args.get('class_id') 

142 

143 print(f"Class ID: {class_id}") 

144 

145 user_class_status = get_user_class_status(user_id, class_id) 

146 

147 if not user_class_status: 

148 return success_response( 

149 f"User class status found for id {user_id}", 

150 None, 

151 StatusCodes.NOT_FOUND 

152 ) 

153 

154 print(user_class_status) 

155 

156 return success_response( 

157 f"User class status for id {user_id}", 

158 { "user_class_status": user_class_status }, 

159 StatusCodes.OK 

160 ) 

161 

162 except Exception as e: 

163 return error_response( 

164 f"Error fetching user {user_id}: {e}", 

165 None, 

166 StatusCodes.SERVER_ERROR 

167 ) 

168 

169@users_bp.route('/users/<user_id>/sections', methods=['POST']) 

170def create_user_section_route(user_id): 

171 try: 

172 user_section_id = create_user_section(user_id) 

173 return success_response( 

174 f"User section created for user {user_id}", 

175 {'user_section_id': user_section_id}, 

176 StatusCodes.CREATED 

177 ) 

178 

179 except Exception as e: 

180 return error_response( 

181 f"Error creating user section for {user_id}: {e}", 

182 None, 

183 StatusCodes.SERVER_ERROR 

184 ) 

185 

186@users_bp.route('/users/<user_id>/sections', methods=['GET']) 

187def get_user_section_route(user_id): 

188 try: 

189 class_id = request.args.get('class_id') 

190 user_section_id = get_user_section(user_id, class_id) 

191 

192 return success_response( 

193 f"User section retrieved or created for user {user_id}", 

194 {'user_section_id': user_section_id}, 

195 StatusCodes.OK 

196 ) 

197 

198 except Exception as e: 

199 return error_response( 

200 f"Error retrieving or creating user section for {user_id}: {e}", 

201 None, 

202 StatusCodes.SERVER_ERROR 

203 ) 

204 

205@users_bp.route('/users/<user_id>/sections', methods=['PUT']) 

206def update_user_section_route(user_id): 

207 try: 

208 data = request.get_json() 

209 user_section_id = data.get("userSectionId") 

210 

211 if not user_section_id: 

212 return error_response( 

213 "userSectionId is required", 

214 None, 

215 StatusCodes.BAD_REQUEST 

216 ) 

217 

218 new_status = data.get("status", "").upper() 

219 

220 valid_statuses = {"COMPLETE", "NEED_REVIEW"} 

221 if new_status not in valid_statuses: 

222 return error_response( 

223 f"Invalid status '{new_status}'. Must be one of {valid_statuses}.", 

224 None, 

225 StatusCodes.BAD_REQUEST 

226 ) 

227 

228 update_user_section(new_status, user_section_id) 

229 

230 return success_response( 

231 f"User section updated for user {user_id}", 

232 None, 

233 StatusCodes.OK 

234 ) 

235 

236 except Exception as e: 

237 return error_response( 

238 f"Error updating user section for {user_id}: {e}", 

239 None, 

240 StatusCodes.SERVER_ERROR 

241 ) 

242 

243@users_bp.route('/users/<user_id>/settings', methods=['PUT']) 

244def update_user_settings_route(user_id): 

245 try: 

246 new_settings = request.get_json() 

247 

248 if not new_settings: 

249 return error_response( 

250 "Error: Missing settings", 

251 None, 

252 StatusCodes.BAD_REQUEST 

253 ) 

254 

255 update_user_settings(user_id, new_settings) 

256 

257 return success_response( 

258 f"User settings updated for id {user_id}", 

259 None, 

260 StatusCodes.OK 

261 ) 

262 

263 except Exception as e: 

264 return error_response( 

265 f"Error updating user settings {user_id}: {e}", 

266 None, 

267 StatusCodes.SERVER_ERROR 

268 ) 

269 

270@users_bp.route('/users/<user_id>/classes', methods=['GET']) 

271@swag_from({ 

272 'tags': ['Users'], 

273 'summary': 'Get classes for a specific user', 

274 'description': 'Retrieves all classes associated with the given user ID.', 

275 'parameters': [ 

276 { 

277 'name': 'user_id', 

278 'in': 'path', 

279 'required': True, 

280 'type': 'string', 

281 'example': '123' 

282 } 

283 ], 

284 'responses': { 

285 '200': { 

286 'description': 'Classes found successfully', 

287 'schema': { 

288 'type': 'array', 

289 'items': { 

290 'type': 'object', 

291 'properties': { 

292 'id': {'type': 'string'}, 

293 'class_title': {'type': 'string'}, 

294 'class_code': {'type': 'string'}, 

295 'class_hex_color': {'type': 'string'}, 

296 'class_image_cover': {'type': 'string'}, 

297 } 

298 } 

299 } 

300 }, 

301 '404': { 

302 'description': 'No classes found for the user', 

303 'schema': { 

304 'type': 'object', 

305 'properties': { 

306 'error': {'type': 'string'} 

307 } 

308 } 

309 } 

310 } 

311}) 

312def get_user_classes_route(user_id): 

313 try: 

314 user_classes = get_classes_by_user_id(user_id) 

315 

316 if not user_classes: 

317 return success_response( 

318 f"No classes found for user id {user_id}", 

319 [], 

320 StatusCodes.NOT_FOUND 

321 ) 

322 

323 return success_response( 

324 f"Classes for user id {user_id}", 

325 user_classes, 

326 StatusCodes.OK 

327 ) 

328 except Exception as e: 

329 return error_response( 

330 f"Error fetching classes for user {user_id}: {e}", 

331 None, 

332 StatusCodes.SERVER_ERROR 

333 ) 

334 

335 

336@users_bp.route('/users', methods=['GET']) 

337@swag_from({ 

338 'tags': ['Users'], 

339 'summary': 'Get all users', 

340 'description': 'Retrieves all users in the system.', 

341 'responses': { 

342 '200': { 

343 'description': 'Users found successfully', 

344 'schema': { 

345 'type': 'array', 

346 'items': { 

347 'type': 'object', 

348 'properties': { 

349 'id': {'type': 'string'}, 

350 'name': {'type': 'string'}, 

351 'email': {'type': 'string'} 

352 } 

353 } 

354 } 

355 }, 

356 '404': { 

357 'description': 'No users found', 

358 'schema': { 

359 'type': 'object', 

360 'properties': { 

361 'error': {'type': 'string'} 

362 } 

363 } 

364 } 

365 } 

366}) 

367def get_all_users_route(): 

368 try: 

369 users = get_all_users() 

370 

371 if not users: 

372 return success_response( 

373 "No users found", 

374 [], 

375 StatusCodes.NOT_FOUND 

376 ) 

377 

378 return success_response( 

379 "All users", 

380 users, 

381 StatusCodes.OK 

382 ) 

383 

384 except Exception as e: 

385 return error_response( 

386 f"Error fetching all users: {e}", 

387 None, 

388 StatusCodes.SERVER_ERROR 

389 ) 

390 

391@users_bp.route('/users/<user_id>', methods=['DELETE']) 

392def delete_user_route(user_id): 

393 try: 

394 

395 if not user_id: 

396 return error_response( 

397 "Error: Missing user ID", 

398 False, 

399 StatusCodes.BAD_REQUEST 

400 ) 

401 

402 delete_user(user_id) 

403 

404 return success_response( 

405 f"User with ID {user_id} deleted successfully", 

406 True, 

407 StatusCodes.OK 

408 ) 

409 

410 except Exception as e: 

411 return error_response( 

412 f"Error deleting user {user_id}: {e}", 

413 False, 

414 StatusCodes.SERVER_ERROR 

415 ) 

416 

417@users_bp.route('/users/<user_id>', methods=['PUT']) 

418def update_user_route(user_id): 

419 try: 

420 data = request.get_json() 

421 

422 if not data: 

423 return error_response( 

424 "Error: Missing user data", 

425 None, 

426 StatusCodes.BAD_REQUEST 

427 ) 

428 

429 updated_user = edit_user(user_id, data) 

430 

431 return success_response( 

432 f"User updated successfully for id {user_id}", 

433 None, 

434 StatusCodes.OK 

435 ) 

436 

437 except Exception as e: 

438 return error_response( 

439 f"Error updating user {user_id}: {e}", 

440 None, 

441 StatusCodes.SERVER_ERROR 

442 )