claude-code-templates 1.16.0 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/bin/create-claude-config.js +17 -8
- package/package.json +2 -3
- package/src/analytics/core/AgentAnalyzer.js +17 -3
- package/src/analytics/core/ProcessDetector.js +23 -7
- package/src/analytics/core/StateCalculator.js +102 -33
- package/src/analytics/data/DataCache.js +7 -7
- package/src/analytics-web/chats_mobile.html +2590 -0
- package/src/analytics-web/components/App.js +10 -10
- package/src/analytics-web/components/SessionTimer.js +1 -1
- package/src/analytics-web/components/Sidebar.js +5 -14
- package/src/analytics-web/index.html +932 -78
- package/src/analytics.js +263 -5
- package/src/chats-mobile.js +682 -0
- package/src/claude-api-proxy.js +460 -0
- package/src/file-operations.js +239 -36
- package/src/health-check.js +310 -0
- package/src/index.js +1252 -56
- package/src/tracking-service.js +31 -34
- package/components/agents/api-security-audit.md +0 -92
- package/components/agents/database-optimization.md +0 -94
- package/components/agents/react-performance-optimization.md +0 -64
- package/components/commands/check-file.md +0 -53
- package/components/commands/generate-tests.md +0 -68
- package/components/mcps/deepgraph-nextjs.json +0 -12
- package/components/mcps/deepgraph-react.json +0 -12
- package/components/mcps/deepgraph-typescript.json +0 -12
- package/components/mcps/deepgraph-vue.json +0 -12
- package/components/mcps/filesystem-access.json +0 -12
- package/components/mcps/github-integration.json +0 -11
- package/components/mcps/memory-integration.json +0 -8
- package/components/mcps/mysql-integration.json +0 -11
- package/components/mcps/postgresql-integration.json +0 -11
- package/components/mcps/web-fetch.json +0 -8
- package/src/analytics-web/components/AgentsPage.js +0 -4761
- package/templates/common/.claude/commands/git-workflow.md +0 -239
- package/templates/common/.claude/commands/project-setup.md +0 -316
- package/templates/common/.mcp.json +0 -41
- package/templates/common/CLAUDE.md +0 -109
- package/templates/common/README.md +0 -96
- package/templates/go/.mcp.json +0 -78
- package/templates/go/README.md +0 -25
- package/templates/javascript-typescript/.claude/commands/api-endpoint.md +0 -51
- package/templates/javascript-typescript/.claude/commands/debug.md +0 -52
- package/templates/javascript-typescript/.claude/commands/lint.md +0 -48
- package/templates/javascript-typescript/.claude/commands/npm-scripts.md +0 -48
- package/templates/javascript-typescript/.claude/commands/refactor.md +0 -55
- package/templates/javascript-typescript/.claude/commands/test.md +0 -61
- package/templates/javascript-typescript/.claude/commands/typescript-migrate.md +0 -51
- package/templates/javascript-typescript/.claude/settings.json +0 -142
- package/templates/javascript-typescript/.mcp.json +0 -80
- package/templates/javascript-typescript/CLAUDE.md +0 -185
- package/templates/javascript-typescript/README.md +0 -259
- package/templates/javascript-typescript/examples/angular-app/.claude/commands/components.md +0 -63
- package/templates/javascript-typescript/examples/angular-app/.claude/commands/services.md +0 -62
- package/templates/javascript-typescript/examples/node-api/.claude/commands/api-endpoint.md +0 -46
- package/templates/javascript-typescript/examples/node-api/.claude/commands/database.md +0 -56
- package/templates/javascript-typescript/examples/node-api/.claude/commands/middleware.md +0 -61
- package/templates/javascript-typescript/examples/node-api/.claude/commands/route.md +0 -57
- package/templates/javascript-typescript/examples/node-api/CLAUDE.md +0 -102
- package/templates/javascript-typescript/examples/react-app/.claude/commands/component.md +0 -29
- package/templates/javascript-typescript/examples/react-app/.claude/commands/hooks.md +0 -44
- package/templates/javascript-typescript/examples/react-app/.claude/commands/state-management.md +0 -45
- package/templates/javascript-typescript/examples/react-app/CLAUDE.md +0 -81
- package/templates/javascript-typescript/examples/react-app/agents/react-performance-optimization.md +0 -530
- package/templates/javascript-typescript/examples/react-app/agents/react-state-management.md +0 -295
- package/templates/javascript-typescript/examples/vue-app/.claude/commands/components.md +0 -46
- package/templates/javascript-typescript/examples/vue-app/.claude/commands/composables.md +0 -51
- package/templates/python/.claude/commands/lint.md +0 -111
- package/templates/python/.claude/commands/test.md +0 -73
- package/templates/python/.claude/settings.json +0 -153
- package/templates/python/.mcp.json +0 -78
- package/templates/python/CLAUDE.md +0 -276
- package/templates/python/examples/django-app/.claude/commands/admin.md +0 -264
- package/templates/python/examples/django-app/.claude/commands/django-model.md +0 -124
- package/templates/python/examples/django-app/.claude/commands/views.md +0 -222
- package/templates/python/examples/django-app/CLAUDE.md +0 -313
- package/templates/python/examples/django-app/agents/django-api-security.md +0 -642
- package/templates/python/examples/django-app/agents/django-database-optimization.md +0 -752
- package/templates/python/examples/fastapi-app/.claude/commands/api-endpoints.md +0 -513
- package/templates/python/examples/fastapi-app/.claude/commands/auth.md +0 -775
- package/templates/python/examples/fastapi-app/.claude/commands/database.md +0 -657
- package/templates/python/examples/fastapi-app/.claude/commands/deployment.md +0 -160
- package/templates/python/examples/fastapi-app/.claude/commands/testing.md +0 -927
- package/templates/python/examples/fastapi-app/CLAUDE.md +0 -229
- package/templates/python/examples/flask-app/.claude/commands/app-factory.md +0 -384
- package/templates/python/examples/flask-app/.claude/commands/blueprint.md +0 -243
- package/templates/python/examples/flask-app/.claude/commands/database.md +0 -410
- package/templates/python/examples/flask-app/.claude/commands/deployment.md +0 -620
- package/templates/python/examples/flask-app/.claude/commands/flask-route.md +0 -217
- package/templates/python/examples/flask-app/.claude/commands/testing.md +0 -559
- package/templates/python/examples/flask-app/CLAUDE.md +0 -391
- package/templates/ruby/.claude/commands/model.md +0 -360
- package/templates/ruby/.claude/commands/test.md +0 -480
- package/templates/ruby/.claude/settings.json +0 -146
- package/templates/ruby/.mcp.json +0 -83
- package/templates/ruby/CLAUDE.md +0 -284
- package/templates/ruby/examples/rails-app/.claude/commands/authentication.md +0 -490
- package/templates/ruby/examples/rails-app/CLAUDE.md +0 -376
- package/templates/rust/.mcp.json +0 -78
- package/templates/rust/README.md +0 -26
|
@@ -1,559 +0,0 @@
|
|
|
1
|
-
# Flask Testing Suite
|
|
2
|
-
|
|
3
|
-
Comprehensive testing setup for Flask applications with pytest.
|
|
4
|
-
|
|
5
|
-
## Usage
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
# Run all tests
|
|
9
|
-
pytest
|
|
10
|
-
|
|
11
|
-
# Run with coverage
|
|
12
|
-
pytest --cov=app --cov-report=html
|
|
13
|
-
|
|
14
|
-
# Run specific test file
|
|
15
|
-
pytest tests/test_models.py
|
|
16
|
-
|
|
17
|
-
# Run with verbose output
|
|
18
|
-
pytest -v
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## Test Configuration
|
|
22
|
-
|
|
23
|
-
```python
|
|
24
|
-
# pytest.ini
|
|
25
|
-
[tool:pytest]
|
|
26
|
-
testpaths = tests
|
|
27
|
-
python_files = test_*.py
|
|
28
|
-
python_classes = Test*
|
|
29
|
-
python_functions = test_*
|
|
30
|
-
addopts =
|
|
31
|
-
--cov=app
|
|
32
|
-
--cov-report=term-missing
|
|
33
|
-
--cov-report=html:htmlcov
|
|
34
|
-
--strict-markers
|
|
35
|
-
--disable-warnings
|
|
36
|
-
markers =
|
|
37
|
-
unit: Unit tests
|
|
38
|
-
integration: Integration tests
|
|
39
|
-
slow: Slow running tests
|
|
40
|
-
auth: Authentication tests
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## Test Fixtures
|
|
44
|
-
|
|
45
|
-
```python
|
|
46
|
-
# tests/conftest.py
|
|
47
|
-
import pytest
|
|
48
|
-
import tempfile
|
|
49
|
-
import os
|
|
50
|
-
from app import create_app
|
|
51
|
-
from app.extensions import db
|
|
52
|
-
from app.models import User, Post, Category
|
|
53
|
-
from flask_login import login_user
|
|
54
|
-
|
|
55
|
-
@pytest.fixture(scope='session')
|
|
56
|
-
def app():
|
|
57
|
-
"""Create test application."""
|
|
58
|
-
# Create temporary database
|
|
59
|
-
db_fd, db_path = tempfile.mkstemp()
|
|
60
|
-
|
|
61
|
-
app = create_app({
|
|
62
|
-
'TESTING': True,
|
|
63
|
-
'SQLALCHEMY_DATABASE_URI': f'sqlite:///{db_path}',
|
|
64
|
-
'WTF_CSRF_ENABLED': False,
|
|
65
|
-
'SECRET_KEY': 'test-secret-key'
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
with app.app_context():
|
|
69
|
-
db.create_all()
|
|
70
|
-
yield app
|
|
71
|
-
|
|
72
|
-
# Cleanup
|
|
73
|
-
os.close(db_fd)
|
|
74
|
-
os.unlink(db_path)
|
|
75
|
-
|
|
76
|
-
@pytest.fixture
|
|
77
|
-
def client(app):
|
|
78
|
-
"""Create test client."""
|
|
79
|
-
return app.test_client()
|
|
80
|
-
|
|
81
|
-
@pytest.fixture
|
|
82
|
-
def runner(app):
|
|
83
|
-
"""Create test CLI runner."""
|
|
84
|
-
return app.test_cli_runner()
|
|
85
|
-
|
|
86
|
-
@pytest.fixture
|
|
87
|
-
def db_session(app):
|
|
88
|
-
"""Create database session for testing."""
|
|
89
|
-
with app.app_context():
|
|
90
|
-
connection = db.engine.connect()
|
|
91
|
-
transaction = connection.begin()
|
|
92
|
-
|
|
93
|
-
# Configure session to use the connection
|
|
94
|
-
db.session.configure(bind=connection)
|
|
95
|
-
|
|
96
|
-
yield db.session
|
|
97
|
-
|
|
98
|
-
# Rollback transaction
|
|
99
|
-
transaction.rollback()
|
|
100
|
-
connection.close()
|
|
101
|
-
db.session.remove()
|
|
102
|
-
|
|
103
|
-
@pytest.fixture
|
|
104
|
-
def user(db_session):
|
|
105
|
-
"""Create test user."""
|
|
106
|
-
user = User(
|
|
107
|
-
username='testuser',
|
|
108
|
-
email='test@example.com',
|
|
109
|
-
first_name='Test',
|
|
110
|
-
last_name='User'
|
|
111
|
-
)
|
|
112
|
-
user.set_password('testpass123')
|
|
113
|
-
user.save()
|
|
114
|
-
return user
|
|
115
|
-
|
|
116
|
-
@pytest.fixture
|
|
117
|
-
def admin_user(db_session):
|
|
118
|
-
"""Create admin user."""
|
|
119
|
-
admin = User(
|
|
120
|
-
username='admin',
|
|
121
|
-
email='admin@example.com',
|
|
122
|
-
first_name='Admin',
|
|
123
|
-
last_name='User',
|
|
124
|
-
is_admin=True
|
|
125
|
-
)
|
|
126
|
-
admin.set_password('adminpass123')
|
|
127
|
-
admin.save()
|
|
128
|
-
return admin
|
|
129
|
-
|
|
130
|
-
@pytest.fixture
|
|
131
|
-
def category(db_session):
|
|
132
|
-
"""Create test category."""
|
|
133
|
-
category = Category(
|
|
134
|
-
name='Test Category',
|
|
135
|
-
description='A test category'
|
|
136
|
-
)
|
|
137
|
-
category.save()
|
|
138
|
-
return category
|
|
139
|
-
|
|
140
|
-
@pytest.fixture
|
|
141
|
-
def post(db_session, user, category):
|
|
142
|
-
"""Create test post."""
|
|
143
|
-
post = Post(
|
|
144
|
-
title='Test Post',
|
|
145
|
-
content='This is a test post content.',
|
|
146
|
-
slug='test-post',
|
|
147
|
-
status='published',
|
|
148
|
-
user_id=user.id,
|
|
149
|
-
category_id=category.id
|
|
150
|
-
)
|
|
151
|
-
post.save()
|
|
152
|
-
return post
|
|
153
|
-
|
|
154
|
-
@pytest.fixture
|
|
155
|
-
def auth_headers(user):
|
|
156
|
-
"""Create authentication headers."""
|
|
157
|
-
# For API testing
|
|
158
|
-
token = user.generate_auth_token()
|
|
159
|
-
return {'Authorization': f'Bearer {token}'}
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
## Model Testing
|
|
163
|
-
|
|
164
|
-
```python
|
|
165
|
-
# tests/test_models.py
|
|
166
|
-
import pytest
|
|
167
|
-
from datetime import datetime
|
|
168
|
-
from app.models import User, Post, Category
|
|
169
|
-
from werkzeug.security import check_password_hash
|
|
170
|
-
|
|
171
|
-
class TestUser:
|
|
172
|
-
"""Test User model."""
|
|
173
|
-
|
|
174
|
-
def test_user_creation(self, db_session):
|
|
175
|
-
"""Test user creation."""
|
|
176
|
-
user = User(
|
|
177
|
-
username='newuser',
|
|
178
|
-
email='new@example.com',
|
|
179
|
-
first_name='New',
|
|
180
|
-
last_name='User'
|
|
181
|
-
)
|
|
182
|
-
user.set_password('password123')
|
|
183
|
-
user.save()
|
|
184
|
-
|
|
185
|
-
assert user.id is not None
|
|
186
|
-
assert user.username == 'newuser'
|
|
187
|
-
assert user.email == 'new@example.com'
|
|
188
|
-
assert user.full_name == 'New User'
|
|
189
|
-
assert user.is_active is True
|
|
190
|
-
assert user.is_admin is False
|
|
191
|
-
assert user.created_at is not None
|
|
192
|
-
|
|
193
|
-
def test_password_hashing(self, user):
|
|
194
|
-
"""Test password hashing."""
|
|
195
|
-
user.set_password('newpassword')
|
|
196
|
-
assert user.password_hash != 'newpassword'
|
|
197
|
-
assert check_password_hash(user.password_hash, 'newpassword')
|
|
198
|
-
assert user.check_password('newpassword')
|
|
199
|
-
assert not user.check_password('wrongpassword')
|
|
200
|
-
|
|
201
|
-
def test_user_repr(self, user):
|
|
202
|
-
"""Test user string representation."""
|
|
203
|
-
assert repr(user) == '<User testuser>'
|
|
204
|
-
|
|
205
|
-
def test_user_to_dict(self, user):
|
|
206
|
-
"""Test user dictionary conversion."""
|
|
207
|
-
user_dict = user.to_dict()
|
|
208
|
-
assert 'username' in user_dict
|
|
209
|
-
assert 'email' in user_dict
|
|
210
|
-
assert 'password_hash' not in user_dict # Should be excluded
|
|
211
|
-
|
|
212
|
-
def test_user_relationships(self, user, post):
|
|
213
|
-
"""Test user relationships."""
|
|
214
|
-
assert post in user.posts
|
|
215
|
-
assert user.posts.count() == 1
|
|
216
|
-
|
|
217
|
-
class TestPost:
|
|
218
|
-
"""Test Post model."""
|
|
219
|
-
|
|
220
|
-
def test_post_creation(self, db_session, user, category):
|
|
221
|
-
"""Test post creation."""
|
|
222
|
-
post = Post(
|
|
223
|
-
title='New Post',
|
|
224
|
-
content='New post content',
|
|
225
|
-
slug='new-post',
|
|
226
|
-
status='draft',
|
|
227
|
-
user_id=user.id,
|
|
228
|
-
category_id=category.id
|
|
229
|
-
)
|
|
230
|
-
post.save()
|
|
231
|
-
|
|
232
|
-
assert post.id is not None
|
|
233
|
-
assert post.title == 'New Post'
|
|
234
|
-
assert post.author == user
|
|
235
|
-
assert post.category == category
|
|
236
|
-
assert not post.is_published
|
|
237
|
-
|
|
238
|
-
def test_published_status(self, post):
|
|
239
|
-
"""Test post published status."""
|
|
240
|
-
assert post.is_published # Published with published_at
|
|
241
|
-
|
|
242
|
-
post.status = 'draft'
|
|
243
|
-
assert not post.is_published
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
## View Testing
|
|
247
|
-
|
|
248
|
-
```python
|
|
249
|
-
# tests/test_views.py
|
|
250
|
-
import pytest
|
|
251
|
-
from flask import url_for
|
|
252
|
-
from app.models import User
|
|
253
|
-
|
|
254
|
-
class TestMainViews:
|
|
255
|
-
"""Test main application views."""
|
|
256
|
-
|
|
257
|
-
def test_home_page(self, client):
|
|
258
|
-
"""Test home page."""
|
|
259
|
-
response = client.get('/')
|
|
260
|
-
assert response.status_code == 200
|
|
261
|
-
assert b'Welcome' in response.data
|
|
262
|
-
|
|
263
|
-
def test_about_page(self, client):
|
|
264
|
-
"""Test about page."""
|
|
265
|
-
response = client.get('/about')
|
|
266
|
-
assert response.status_code == 200
|
|
267
|
-
|
|
268
|
-
class TestUserViews:
|
|
269
|
-
"""Test user-related views."""
|
|
270
|
-
|
|
271
|
-
def test_user_list(self, client, user):
|
|
272
|
-
"""Test user list page."""
|
|
273
|
-
response = client.get('/users/')
|
|
274
|
-
assert response.status_code == 200
|
|
275
|
-
assert user.username.encode() in response.data
|
|
276
|
-
|
|
277
|
-
def test_user_detail(self, client, user):
|
|
278
|
-
"""Test user detail page."""
|
|
279
|
-
response = client.get(f'/users/{user.id}')
|
|
280
|
-
assert response.status_code == 200
|
|
281
|
-
assert user.username.encode() in response.data
|
|
282
|
-
|
|
283
|
-
def test_user_create_get(self, client):
|
|
284
|
-
"""Test user creation form."""
|
|
285
|
-
response = client.get('/users/create')
|
|
286
|
-
assert response.status_code == 200
|
|
287
|
-
assert b'Create User' in response.data
|
|
288
|
-
|
|
289
|
-
def test_user_create_post(self, client, db_session):
|
|
290
|
-
"""Test user creation submission."""
|
|
291
|
-
data = {
|
|
292
|
-
'username': 'newuser',
|
|
293
|
-
'email': 'new@example.com',
|
|
294
|
-
'first_name': 'New',
|
|
295
|
-
'last_name': 'User',
|
|
296
|
-
'password': 'password123',
|
|
297
|
-
'confirm_password': 'password123'
|
|
298
|
-
}
|
|
299
|
-
response = client.post('/users/create', data=data, follow_redirects=True)
|
|
300
|
-
assert response.status_code == 200
|
|
301
|
-
|
|
302
|
-
# Check user was created
|
|
303
|
-
user = User.query.filter_by(username='newuser').first()
|
|
304
|
-
assert user is not None
|
|
305
|
-
assert user.email == 'new@example.com'
|
|
306
|
-
|
|
307
|
-
def test_user_edit(self, client, user):
|
|
308
|
-
"""Test user editing."""
|
|
309
|
-
data = {
|
|
310
|
-
'username': user.username,
|
|
311
|
-
'email': 'updated@example.com',
|
|
312
|
-
'first_name': 'Updated',
|
|
313
|
-
'last_name': 'User'
|
|
314
|
-
}
|
|
315
|
-
response = client.post(f'/users/{user.id}/edit', data=data, follow_redirects=True)
|
|
316
|
-
assert response.status_code == 200
|
|
317
|
-
|
|
318
|
-
# Refresh user from database
|
|
319
|
-
db_session.refresh(user)
|
|
320
|
-
assert user.email == 'updated@example.com'
|
|
321
|
-
assert user.first_name == 'Updated'
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
## Authentication Testing
|
|
325
|
-
|
|
326
|
-
```python
|
|
327
|
-
# tests/test_auth.py
|
|
328
|
-
import pytest
|
|
329
|
-
from flask import url_for
|
|
330
|
-
from app.models import User
|
|
331
|
-
|
|
332
|
-
class TestAuthentication:
|
|
333
|
-
"""Test authentication functionality."""
|
|
334
|
-
|
|
335
|
-
def test_login_page(self, client):
|
|
336
|
-
"""Test login page access."""
|
|
337
|
-
response = client.get('/auth/login')
|
|
338
|
-
assert response.status_code == 200
|
|
339
|
-
assert b'Login' in response.data
|
|
340
|
-
|
|
341
|
-
def test_valid_login(self, client, user):
|
|
342
|
-
"""Test valid user login."""
|
|
343
|
-
data = {
|
|
344
|
-
'username': user.username,
|
|
345
|
-
'password': 'testpass123'
|
|
346
|
-
}
|
|
347
|
-
response = client.post('/auth/login', data=data, follow_redirects=True)
|
|
348
|
-
assert response.status_code == 200
|
|
349
|
-
assert b'Welcome' in response.data
|
|
350
|
-
|
|
351
|
-
def test_invalid_login(self, client, user):
|
|
352
|
-
"""Test invalid login credentials."""
|
|
353
|
-
data = {
|
|
354
|
-
'username': user.username,
|
|
355
|
-
'password': 'wrongpassword'
|
|
356
|
-
}
|
|
357
|
-
response = client.post('/auth/login', data=data)
|
|
358
|
-
assert response.status_code == 200
|
|
359
|
-
assert b'Invalid' in response.data
|
|
360
|
-
|
|
361
|
-
def test_logout(self, client, user):
|
|
362
|
-
"""Test user logout."""
|
|
363
|
-
# Login first
|
|
364
|
-
with client.session_transaction() as sess:
|
|
365
|
-
sess['_user_id'] = str(user.id)
|
|
366
|
-
|
|
367
|
-
response = client.get('/auth/logout', follow_redirects=True)
|
|
368
|
-
assert response.status_code == 200
|
|
369
|
-
|
|
370
|
-
def test_register_page(self, client):
|
|
371
|
-
"""Test registration page."""
|
|
372
|
-
response = client.get('/auth/register')
|
|
373
|
-
assert response.status_code == 200
|
|
374
|
-
assert b'Register' in response.data
|
|
375
|
-
|
|
376
|
-
def test_valid_registration(self, client, db_session):
|
|
377
|
-
"""Test valid user registration."""
|
|
378
|
-
data = {
|
|
379
|
-
'username': 'newuser',
|
|
380
|
-
'email': 'new@example.com',
|
|
381
|
-
'first_name': 'New',
|
|
382
|
-
'last_name': 'User',
|
|
383
|
-
'password': 'password123',
|
|
384
|
-
'confirm_password': 'password123'
|
|
385
|
-
}
|
|
386
|
-
response = client.post('/auth/register', data=data, follow_redirects=True)
|
|
387
|
-
assert response.status_code == 200
|
|
388
|
-
|
|
389
|
-
# Check user was created
|
|
390
|
-
user = User.query.filter_by(username='newuser').first()
|
|
391
|
-
assert user is not None
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
## API Testing
|
|
395
|
-
|
|
396
|
-
```python
|
|
397
|
-
# tests/test_api.py
|
|
398
|
-
import pytest
|
|
399
|
-
import json
|
|
400
|
-
from flask import url_for
|
|
401
|
-
|
|
402
|
-
class TestUserAPI:
|
|
403
|
-
"""Test User API endpoints."""
|
|
404
|
-
|
|
405
|
-
def test_get_users(self, client, user):
|
|
406
|
-
"""Test GET /api/users."""
|
|
407
|
-
response = client.get('/api/users')
|
|
408
|
-
assert response.status_code == 200
|
|
409
|
-
|
|
410
|
-
data = json.loads(response.data)
|
|
411
|
-
assert 'users' in data
|
|
412
|
-
assert len(data['users']) >= 1
|
|
413
|
-
|
|
414
|
-
def test_get_user(self, client, user):
|
|
415
|
-
"""Test GET /api/users/<id>."""
|
|
416
|
-
response = client.get(f'/api/users/{user.id}')
|
|
417
|
-
assert response.status_code == 200
|
|
418
|
-
|
|
419
|
-
data = json.loads(response.data)
|
|
420
|
-
assert data['username'] == user.username
|
|
421
|
-
assert data['email'] == user.email
|
|
422
|
-
|
|
423
|
-
def test_create_user(self, client, db_session):
|
|
424
|
-
"""Test POST /api/users."""
|
|
425
|
-
user_data = {
|
|
426
|
-
'username': 'apiuser',
|
|
427
|
-
'email': 'api@example.com',
|
|
428
|
-
'first_name': 'API',
|
|
429
|
-
'last_name': 'User',
|
|
430
|
-
'password': 'password123'
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
response = client.post(
|
|
434
|
-
'/api/users',
|
|
435
|
-
data=json.dumps(user_data),
|
|
436
|
-
content_type='application/json'
|
|
437
|
-
)
|
|
438
|
-
|
|
439
|
-
assert response.status_code == 201
|
|
440
|
-
data = json.loads(response.data)
|
|
441
|
-
assert data['username'] == 'apiuser'
|
|
442
|
-
|
|
443
|
-
def test_update_user(self, client, user, auth_headers):
|
|
444
|
-
"""Test PUT /api/users/<id>."""
|
|
445
|
-
update_data = {
|
|
446
|
-
'email': 'updated@example.com',
|
|
447
|
-
'first_name': 'Updated'
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
response = client.put(
|
|
451
|
-
f'/api/users/{user.id}',
|
|
452
|
-
data=json.dumps(update_data),
|
|
453
|
-
content_type='application/json',
|
|
454
|
-
headers=auth_headers
|
|
455
|
-
)
|
|
456
|
-
|
|
457
|
-
assert response.status_code == 200
|
|
458
|
-
data = json.loads(response.data)
|
|
459
|
-
assert data['email'] == 'updated@example.com'
|
|
460
|
-
|
|
461
|
-
def test_delete_user(self, client, user, auth_headers):
|
|
462
|
-
"""Test DELETE /api/users/<id>."""
|
|
463
|
-
response = client.delete(
|
|
464
|
-
f'/api/users/{user.id}',
|
|
465
|
-
headers=auth_headers
|
|
466
|
-
)
|
|
467
|
-
|
|
468
|
-
assert response.status_code == 204
|
|
469
|
-
```
|
|
470
|
-
|
|
471
|
-
## Test Utilities
|
|
472
|
-
|
|
473
|
-
```python
|
|
474
|
-
# tests/utils.py
|
|
475
|
-
import json
|
|
476
|
-
from flask import url_for
|
|
477
|
-
|
|
478
|
-
def login_user(client, username, password):
|
|
479
|
-
"""Helper to login user in tests."""
|
|
480
|
-
return client.post('/auth/login', data={
|
|
481
|
-
'username': username,
|
|
482
|
-
'password': password
|
|
483
|
-
}, follow_redirects=True)
|
|
484
|
-
|
|
485
|
-
def logout_user(client):
|
|
486
|
-
"""Helper to logout user in tests."""
|
|
487
|
-
return client.get('/auth/logout', follow_redirects=True)
|
|
488
|
-
|
|
489
|
-
def assert_json_response(response, expected_status=200):
|
|
490
|
-
"""Assert JSON response format and status."""
|
|
491
|
-
assert response.status_code == expected_status
|
|
492
|
-
assert response.content_type == 'application/json'
|
|
493
|
-
return json.loads(response.data)
|
|
494
|
-
|
|
495
|
-
def create_test_data(db_session):
|
|
496
|
-
"""Create common test data."""
|
|
497
|
-
from app.models import User, Category, Post
|
|
498
|
-
|
|
499
|
-
# Create test users
|
|
500
|
-
users = []
|
|
501
|
-
for i in range(3):
|
|
502
|
-
user = User(
|
|
503
|
-
username=f'user{i}',
|
|
504
|
-
email=f'user{i}@example.com',
|
|
505
|
-
first_name=f'User{i}',
|
|
506
|
-
last_name='Test'
|
|
507
|
-
)
|
|
508
|
-
user.set_password('password123')
|
|
509
|
-
user.save()
|
|
510
|
-
users.append(user)
|
|
511
|
-
|
|
512
|
-
return {'users': users}
|
|
513
|
-
```
|
|
514
|
-
|
|
515
|
-
## Performance Testing
|
|
516
|
-
|
|
517
|
-
```python
|
|
518
|
-
# tests/test_performance.py
|
|
519
|
-
import pytest
|
|
520
|
-
import time
|
|
521
|
-
from app.models import User
|
|
522
|
-
|
|
523
|
-
@pytest.mark.slow
|
|
524
|
-
class TestPerformance:
|
|
525
|
-
"""Test application performance."""
|
|
526
|
-
|
|
527
|
-
def test_user_query_performance(self, db_session):
|
|
528
|
-
"""Test user query performance."""
|
|
529
|
-
# Create multiple users
|
|
530
|
-
users = []
|
|
531
|
-
for i in range(100):
|
|
532
|
-
user = User(
|
|
533
|
-
username=f'perfuser{i}',
|
|
534
|
-
email=f'perf{i}@example.com',
|
|
535
|
-
first_name=f'Perf{i}',
|
|
536
|
-
last_name='User'
|
|
537
|
-
)
|
|
538
|
-
users.append(user)
|
|
539
|
-
|
|
540
|
-
db_session.bulk_save_objects(users)
|
|
541
|
-
db_session.commit()
|
|
542
|
-
|
|
543
|
-
# Test query performance
|
|
544
|
-
start_time = time.time()
|
|
545
|
-
result = User.query.all()
|
|
546
|
-
end_time = time.time()
|
|
547
|
-
|
|
548
|
-
assert len(result) >= 100
|
|
549
|
-
assert (end_time - start_time) < 0.1 # Should complete in under 100ms
|
|
550
|
-
|
|
551
|
-
def test_endpoint_response_time(self, client):
|
|
552
|
-
"""Test endpoint response time."""
|
|
553
|
-
start_time = time.time()
|
|
554
|
-
response = client.get('/')
|
|
555
|
-
end_time = time.time()
|
|
556
|
-
|
|
557
|
-
assert response.status_code == 200
|
|
558
|
-
assert (end_time - start_time) < 0.5 # Should respond in under 500ms
|
|
559
|
-
```
|