import unittest import json from app import create_app, db from app.models.user import User from app.services.jwt_service import JWTService class TestJWTAndAPI(unittest.TestCase): def setUp(self): self.app = create_app() self.app.config['TESTING'] = True self.client = self.app.test_client() self.app_context = self.app.app_context() self.app_context.push() # Buscar usuario activo o crear de prueba self.test_user = User.query.filter_by(is_active=True).first() if not self.test_user: self.test_user = User( email="test_api_admin@unicaba.edu.ar", name="Test API Admin", role="ADMIN", is_active=True ) self.test_user.set_password("Test1234!") db.session.add(self.test_user) db.session.commit() def tearDown(self): db.session.rollback() self.app_context.pop() def test_jwt_generation_and_decoding(self): tokens = JWTService.generate_tokens(self.test_user) self.assertIn('access_token', tokens) self.assertIn('refresh_token', tokens) payload = JWTService.decode_token(tokens['access_token'], expected_type='access') self.assertEqual(payload['sub'], str(self.test_user.id)) self.assertEqual(payload['email'], self.test_user.email) def test_jwt_revocation(self): tokens = JWTService.generate_tokens(self.test_user) token = tokens['access_token'] # Antes de revocar: válido payload = JWTService.decode_token(token, expected_type='access') self.assertIsNotNone(payload) # Revocar revoked = JWTService.revoke_token(token) self.assertTrue(revoked) # Después de revocar: debe lanzar InvalidTokenError with self.assertRaises(Exception): JWTService.decode_token(token, expected_type='access') def test_protected_endpoints_require_token(self): # Sin token debe dar 401 res = self.client.get('/api/v1/auth/me') self.assertEqual(res.status_code, 401) res_classrooms = self.client.get('/api/v1/classrooms') self.assertEqual(res_classrooms.status_code, 401) def test_authorized_endpoint_access(self): tokens = JWTService.generate_tokens(self.test_user) headers = {'Authorization': f"Bearer {tokens['access_token']}"} res = self.client.get('/api/v1/auth/me', headers=headers) self.assertEqual(res.status_code, 200) data = res.get_json() self.assertEqual(data['email'], self.test_user.email) res_classrooms = self.client.get('/api/v1/classrooms', headers=headers) self.assertEqual(res_classrooms.status_code, 200) def test_token_refresh_flow(self): tokens = JWTService.generate_tokens(self.test_user) res = self.client.post('/api/v1/auth/refresh', json={'refresh_token': tokens['refresh_token']}) self.assertEqual(res.status_code, 200) data = res.get_json() self.assertIn('access_token', data) if __name__ == '__main__': unittest.main()