test_users.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. """
  2. Tests for user management module (Admin only)
  3. """
  4. import pytest
  5. import json
  6. from app import db
  7. from app.models import User
  8. @pytest.fixture
  9. def admin_user(app):
  10. """Create an admin user"""
  11. with app.app_context():
  12. user = User(
  13. username='adminuser',
  14. email='admin@example.com',
  15. role='admin'
  16. )
  17. user.set_password('adminpassword123')
  18. db.session.add(user)
  19. db.session.commit()
  20. return {
  21. 'id': user.id,
  22. 'username': user.username,
  23. 'email': user.email,
  24. 'role': user.role
  25. }
  26. @pytest.fixture
  27. def admin_token(client, admin_user):
  28. """Get admin token for authenticated requests"""
  29. response = client.post('/api/auth/login',
  30. data=json.dumps({
  31. 'username': 'adminuser',
  32. 'password': 'adminpassword123'
  33. }),
  34. content_type='application/json'
  35. )
  36. return json.loads(response.data)['token']
  37. @pytest.fixture
  38. def regular_user(app):
  39. """Create a regular user"""
  40. with app.app_context():
  41. user = User(
  42. username='regularuser',
  43. email='regular@example.com',
  44. role='user'
  45. )
  46. user.set_password('regularpassword123')
  47. db.session.add(user)
  48. db.session.commit()
  49. return {
  50. 'id': user.id,
  51. 'username': user.username,
  52. 'email': user.email,
  53. 'role': user.role
  54. }
  55. class TestGetUsers:
  56. """Tests for GET /api/users endpoint"""
  57. def test_get_users_success(self, client, admin_token, admin_user):
  58. """Test admin can get users list"""
  59. response = client.get('/api/users',
  60. headers={'Authorization': f'Bearer {admin_token}'}
  61. )
  62. assert response.status_code == 200
  63. data = json.loads(response.data)
  64. assert 'data' in data
  65. assert 'pagination' in data
  66. assert len(data['data']) >= 1
  67. def test_get_users_pagination(self, client, admin_token, admin_user):
  68. """Test pagination parameters"""
  69. response = client.get('/api/users?page=1&page_size=10',
  70. headers={'Authorization': f'Bearer {admin_token}'}
  71. )
  72. assert response.status_code == 200
  73. data = json.loads(response.data)
  74. assert data['pagination']['page'] == 1
  75. assert data['pagination']['page_size'] == 10
  76. def test_get_users_search(self, client, admin_token, admin_user):
  77. """Test search functionality"""
  78. response = client.get('/api/users?search=admin',
  79. headers={'Authorization': f'Bearer {admin_token}'}
  80. )
  81. assert response.status_code == 200
  82. data = json.loads(response.data)
  83. assert len(data['data']) >= 1
  84. assert 'admin' in data['data'][0]['username'].lower() or 'admin' in data['data'][0]['email'].lower()
  85. def test_get_users_unauthorized(self, client, regular_user):
  86. """Test regular user cannot access users list"""
  87. # Login as regular user
  88. login_response = client.post('/api/auth/login',
  89. data=json.dumps({
  90. 'username': 'regularuser',
  91. 'password': 'regularpassword123'
  92. }),
  93. content_type='application/json'
  94. )
  95. token = json.loads(login_response.data)['token']
  96. response = client.get('/api/users',
  97. headers={'Authorization': f'Bearer {token}'}
  98. )
  99. assert response.status_code == 403
  100. class TestCreateUser:
  101. """Tests for POST /api/users/create endpoint"""
  102. def test_create_user_success(self, client, admin_token):
  103. """Test admin can create a new user"""
  104. response = client.post('/api/users/create',
  105. data=json.dumps({
  106. 'username': 'newuser',
  107. 'password': 'newpassword123',
  108. 'email': 'newuser@example.com',
  109. 'role': 'user'
  110. }),
  111. content_type='application/json',
  112. headers={'Authorization': f'Bearer {admin_token}'}
  113. )
  114. assert response.status_code == 201
  115. data = json.loads(response.data)
  116. assert data['username'] == 'newuser'
  117. assert data['email'] == 'newuser@example.com'
  118. assert data['role'] == 'user'
  119. def test_create_user_missing_fields(self, client, admin_token):
  120. """Test create user with missing required fields"""
  121. response = client.post('/api/users/create',
  122. data=json.dumps({
  123. 'username': 'newuser'
  124. }),
  125. content_type='application/json',
  126. headers={'Authorization': f'Bearer {admin_token}'}
  127. )
  128. assert response.status_code == 400
  129. data = json.loads(response.data)
  130. assert 'error' in data
  131. def test_create_user_duplicate_username(self, client, admin_token, admin_user):
  132. """Test create user with duplicate username"""
  133. response = client.post('/api/users/create',
  134. data=json.dumps({
  135. 'username': 'adminuser',
  136. 'password': 'password123',
  137. 'email': 'another@example.com',
  138. 'role': 'user'
  139. }),
  140. content_type='application/json',
  141. headers={'Authorization': f'Bearer {admin_token}'}
  142. )
  143. assert response.status_code == 400
  144. data = json.loads(response.data)
  145. assert 'error' in data
  146. def test_create_user_invalid_role(self, client, admin_token):
  147. """Test create user with invalid role"""
  148. response = client.post('/api/users/create',
  149. data=json.dumps({
  150. 'username': 'newuser',
  151. 'password': 'password123',
  152. 'email': 'newuser@example.com',
  153. 'role': 'invalid_role'
  154. }),
  155. content_type='application/json',
  156. headers={'Authorization': f'Bearer {admin_token}'}
  157. )
  158. assert response.status_code == 400
  159. class TestUpdateUser:
  160. """Tests for POST /api/users/update endpoint"""
  161. def test_update_user_success(self, client, admin_token, regular_user):
  162. """Test admin can update a user"""
  163. response = client.post('/api/users/update',
  164. data=json.dumps({
  165. 'id': regular_user['id'],
  166. 'email': 'updated@example.com'
  167. }),
  168. content_type='application/json',
  169. headers={'Authorization': f'Bearer {admin_token}'}
  170. )
  171. assert response.status_code == 200
  172. data = json.loads(response.data)
  173. assert data['email'] == 'updated@example.com'
  174. def test_update_user_not_found(self, client, admin_token):
  175. """Test update non-existent user"""
  176. response = client.post('/api/users/update',
  177. data=json.dumps({
  178. 'id': 99999,
  179. 'email': 'updated@example.com'
  180. }),
  181. content_type='application/json',
  182. headers={'Authorization': f'Bearer {admin_token}'}
  183. )
  184. assert response.status_code == 404
  185. def test_update_user_self_deactivation(self, client, admin_token, admin_user):
  186. """Test admin cannot deactivate themselves"""
  187. response = client.post('/api/users/update',
  188. data=json.dumps({
  189. 'id': admin_user['id'],
  190. 'is_active': False
  191. }),
  192. content_type='application/json',
  193. headers={'Authorization': f'Bearer {admin_token}'}
  194. )
  195. assert response.status_code == 400
  196. class TestDeleteUser:
  197. """Tests for POST /api/users/delete endpoint"""
  198. def test_delete_user_success(self, client, admin_token, regular_user):
  199. """Test admin can delete a user"""
  200. response = client.post('/api/users/delete',
  201. data=json.dumps({
  202. 'id': regular_user['id']
  203. }),
  204. content_type='application/json',
  205. headers={'Authorization': f'Bearer {admin_token}'}
  206. )
  207. assert response.status_code == 200
  208. data = json.loads(response.data)
  209. assert 'message' in data
  210. def test_delete_user_not_found(self, client, admin_token):
  211. """Test delete non-existent user"""
  212. response = client.post('/api/users/delete',
  213. data=json.dumps({
  214. 'id': 99999
  215. }),
  216. content_type='application/json',
  217. headers={'Authorization': f'Bearer {admin_token}'}
  218. )
  219. assert response.status_code == 404
  220. def test_delete_user_self_deletion(self, client, admin_token, admin_user):
  221. """Test admin cannot delete themselves"""
  222. response = client.post('/api/users/delete',
  223. data=json.dumps({
  224. 'id': admin_user['id']
  225. }),
  226. content_type='application/json',
  227. headers={'Authorization': f'Bearer {admin_token}'}
  228. )
  229. assert response.status_code == 400