RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Configs/Cursor rules/TechSquidTV/Hermes

Cursor rule

.cursor/rules/20-hermes-api-tests.mdc
Cursor rules

Quality

97/100

Scores the file, not the repository.

Length

570 words

23 headings · 14 code blocks

Repository

45

— · pushed 2 days ago

Last changed

3 days ago

First indexed 3 days ago.
TechSquidTV/Hermes/.cursor/rules/20-hermes-api-tests.mdcRawGitHub
1---
2globs:
3 - "packages/hermes-api/tests/**/*.py"
4---
5 
6# Hermes API - Testing Rules
7 
8## Pytest Configuration
9 
10### Test Discovery
11- Test files: `test_*.py`
12- Test classes: `Test*`
13- Test functions: `test_*`
14- Location: `packages/hermes-api/tests/`
15 
16### Running Tests
17```bash
18pytest # All tests
19pytest -v # Verbose
20pytest -m unit # Only unit tests
21pytest -m "not slow" # Exclude slow tests
22pytest tests/test_api/test_auth.py # Specific file
23```
24 
25## Test Organization
26 
27```
28tests/
29├── conftest.py # Shared fixtures
30├── test_api/ # API endpoint tests
31├── test_integration/ # Integration tests
32├── test_services/ # Service layer tests
33└── test_tasks/ # Celery task tests
34```
35 
36### Test Markers
37```python
38@pytest.mark.unit
39def test_simple_function():
40 pass
41 
42@pytest.mark.integration
43async def test_full_workflow():
44 pass
45 
46@pytest.mark.slow
47async def test_large_download():
48 pass
49```
50 
51## Async Testing
52 
53```python
54import pytest
55from httpx import AsyncClient
56 
57@pytest.mark.asyncio
58async def test_async_endpoint(client: AsyncClient):
59 response = await client.get("/api/v1/health")
60 assert response.status_code == 200
61```
62 
63## Fixtures
64 
65### Common Fixtures (conftest.py)
66```python
67@pytest.fixture
68async def client():
69 async with AsyncClient(app=app, base_url="http://test") as ac:
70 yield ac
71 
72@pytest.fixture
73async def auth_token(client: AsyncClient, test_user):
74 response = await client.post(
75 "/api/v1/auth/login",
76 json={"username": test_user.username, "password": "password123"}
77 )
78 return response.json()["access_token"]
79 
80@pytest.fixture
81async def db_session():
82 async for session in get_database_session():
83 yield session
84 await session.rollback()
85```
86 
87## API Testing
88 
89### Testing Endpoints
90```python
91@pytest.mark.asyncio
92async def test_get_endpoint(client: AsyncClient, auth_token: str):
93 headers = {"Authorization": f"Bearer {auth_token}"}
94 response = await client.get("/api/v1/downloads", headers=headers)
95
96 assert response.status_code == 200
97 data = response.json()
98 assert isinstance(data, list)
99 
100@pytest.mark.asyncio
101async def test_post_endpoint(client: AsyncClient, auth_token: str):
102 headers = {"Authorization": f"Bearer {auth_token}"}
103 payload = {"url": "https://example.com/video", "profile_id": "default"}
104
105 response = await client.post(
106 "/api/v1/downloads",
107 headers=headers,
108 json=payload
109 )
110
111 assert response.status_code == 201
112 assert "id" in response.json()
113```
114 
115### Testing Auth
116```python
117@pytest.mark.asyncio
118async def test_protected_without_auth(client: AsyncClient):
119 response = await client.get("/api/v1/downloads")
120 assert response.status_code == 401
121 
122@pytest.mark.asyncio
123async def test_protected_invalid_token(client: AsyncClient):
124 headers = {"Authorization": "Bearer invalid"}
125 response = await client.get("/api/v1/downloads", headers=headers)
126 assert response.status_code == 401
127```
128 
129### Testing Errors
130```python
131@pytest.mark.asyncio
132async def test_not_found(client: AsyncClient, auth_token: str):
133 headers = {"Authorization": f"Bearer {auth_token}"}
134 response = await client.get("/api/v1/downloads/nonexistent", headers=headers)
135
136 assert response.status_code == 404
137 assert "not found" in response.json()["detail"].lower()
138 
139@pytest.mark.asyncio
140async def test_validation_error(client: AsyncClient, auth_token: str):
141 headers = {"Authorization": f"Bearer {auth_token}"}
142 response = await client.post("/api/v1/downloads", headers=headers, json={})
143
144 assert response.status_code == 422
145```
146 
147## Database Testing
148 
149```python
150@pytest.mark.asyncio
151async def test_create_user(db_session: AsyncSession):
152 repo = UserRepository(db_session)
153
154 user_data = {
155 "username": "testuser",
156 "email": "test@example.com",
157 "password_hash": "hashed"
158 }
159
160 user = await repo.create(user_data)
161
162 assert user.id is not None
163 assert user.username == "testuser"
164```
165 
166## Mocking
167 
168```python
169@pytest.mark.asyncio
170async def test_with_mock(mocker):
171 mock_yt_dlp = mocker.patch("app.services.yt_dlp_service.YtDlpService.get_info")
172 mock_yt_dlp.return_value = {"title": "Test Video", "duration": 120}
173
174 result = await some_function()
175
176 assert result["title"] == "Test Video"
177 mock_yt_dlp.assert_called_once()
178 
179@pytest.mark.asyncio
180async def test_celery_task(client, auth_token, mocker):
181 mock_task = mocker.patch("app.tasks.download_tasks.process_download.delay")
182 mock_task.return_value.id = "task-123"
183
184 headers = {"Authorization": f"Bearer {auth_token}"}
185 response = await client.post(
186 "/api/v1/downloads",
187 headers=headers,
188 json={"url": "https://example.com"}
189 )
190
191 assert response.status_code == 201
192 mock_task.assert_called_once()
193```
194 
195## Test Best Practices
196 
197### Arrange-Act-Assert
198```python
199def test_something():
200 # Arrange
201 user_data = {"username": "test"}
202
203 # Act
204 result = create_user(user_data)
205
206 # Assert
207 assert result.username == "test"
208```
209 
210### Test Names
211```python
212# ✅ Good
213def test_create_download_success()
214def test_get_download_not_found()
215def test_delete_download_unauthorized()
216 
217# ❌ Bad
218def test_download()
219def test_1()
220```
221 
222### Test Independence
223- Each test should be independent
224- Don't rely on execution order
225- Clean up after tests
226- Use fixtures for setup
227 
228### Assertions
229```python
230assert response.status_code == 200, "Expected successful response"
231assert "id" in data, "Response should include ID"
232assert len(downloads) > 0, "Should return downloads"
233```
234 
235## Coverage
236 
237```bash
238pytest --cov=app --cov-report=html
239open htmlcov/index.html
240```
241 
242- Aim for 80%+ coverage on critical code
243- Focus on meaningful coverage
244- Test edge cases and error conditions
245 

Commands it names

  • pytest
  • pytest -v
  • pytest -m unit
  • pytest -m "not slow"
  • pytest tests/test_api/test_auth.py
  • pytest --cov=app --cov-report=html

Sections

  • Hermes API - Testing Rules
  • Pytest Configuration
  • Test Discovery
  • Running Tests
  • Test Organization
  • Test Markers
  • Async Testing
  • Fixtures
  • Common Fixtures (conftest.py)
  • API Testing
  • Testing Endpoints
  • Testing Auth
  • Testing Errors
  • Database Testing
  • Mocking
  • Test Best Practices
  • Arrange-Act-Assert
  • Test Names
  • ✅ Good
  • ❌ Bad
  • Test Independence
  • Assertions
  • Coverage

What it covers

testcode-styletesting-strategysecuritydatabaseapido-not

Stack — with the evidence

typescript

(1.00)

pytest

(0.95)

node

(0.70)

react

(0.70)

fastapi

(0.70)

redis

(0.70)

tailwind

(0.70)

vite

(0.70)

vitest

(0.70)

eslint

(0.70)

ruff

(0.70)

javascript

(0.60)

monorepo

(0.60)

pnpm

(0.60)

docker

(0.60)

github-actions

(0.60)

python

(0.50)

Glob targeting

  • packages/hermes-api/tests/**/*.py

Format

Cursor rules

The most expressive format here. Many small .mdc files, each with frontmatter declaring when it should load, so a rule about migrations only enters context when a migration is open. Costs the most to maintain and only one editor reads it.

What the corpus says about it

Repository

Owner
TechSquidTV
Language
—
License
—
Archived
no

All configs in this repo

Also in TechSquidTV/Hermes

Diff this repo’s formats

One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?

The other instruction files in this repository
RepositoryFormatStackCoversScoreChanged
TechSquidTV/Hermes.cursor/rules/00-project.mdc · 45Cursor rulestypescriptmonorepo+15setuplint-formatstylearch+489/1003 days ago
TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 45Cursor rulestypescriptpytest+15testlint-formatstylearch+5100/1003 days ago
TechSquidTV/Hermes.cursor/rules/10-hermes-app.mdc · 45Cursor rulestypescriptnode+15lint-formatstylearchtypes+588/1003 days ago
TechSquidTV/Hermes.cursor/rules/20-hermes-api-api.mdc · 45Cursor rulestypescriptnode+15stylearchdependenciesapi+277/1003 days ago
TechSquidTV/Hermes.cursor/rules/20-hermes-api-db.mdc · 45Cursor rulestypescriptnode+15teststylearchtesting-strategy+373/1003 days ago
TechSquidTV/Hermes.cursor/rules/20-hermes-app-components.mdc · 45Cursor rulestypescriptnode+15archtypesuiperformance+165/1003 days ago
TechSquidTV/Hermes.cursor/rules/20-hermes-app-hooks.mdc · 45Cursor rulestypescriptnode+15lint-formatstylearchtypes+373/1003 days ago
TechSquidTV/Hermes.cursor/rules/20-hermes-app-routes.mdc · 45Cursor rulestypescriptnode+15archapiuido-not65/1003 days ago
TechSquidTV/Hermes.cursor/rules/30-docker.mdc · 45Cursor rulestypescriptnode+15setupbuildstylesecurity+484/1003 days ago
TechSquidTV/Hermes.cursor/rules/30-docs.mdc · 45Cursor rulestypescriptnode+15setuplint-formatstylearch+381/1003 days ago
TechSquidTV/Hermes.cursor/rules/30-tests.mdc · 45Cursor rulestypescriptpytest+15buildteststylearch+485/1003 days ago
Diff against .cursor/rules/00-project.mdc Diff against .cursor/rules/10-hermes-api.mdc Diff against .cursor/rules/10-hermes-app.mdc Diff against .cursor/rules/20-hermes-api-api.mdc Diff against .cursor/rules/20-hermes-api-db.mdc Diff against .cursor/rules/20-hermes-app-components.mdc Diff against .cursor/rules/20-hermes-app-hooks.mdc Diff against .cursor/rules/20-hermes-app-routes.mdc Diff against .cursor/rules/30-docker.mdc Diff against .cursor/rules/30-docs.mdc Diff against .cursor/rules/30-tests.mdc

Similar configs

Same format, overlapping stack, ranked by quality.

Same format, overlapping stack, ranked by quality
RepositoryFormatStackCoversScoreChanged
hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126Cursor rulesgobun+5setupbuildtestlint-format+6100/1003 days ago
TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 45Cursor rulestypescriptpytest+15testlint-formatstylearch+5100/1003 days ago
dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+15setuptestlint-formatstyle+799/1003 days ago
deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1Cursor rulestypescriptnextjs+5setuptestlint-formatstyle+799/1003 days ago
markstev/mark-starter.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+14setuptestlint-formatstyle+699/1003 days ago
Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+13setuptestlint-formatstyle+799/1003 days ago
langflow-ai/langflow.cursor/rules/docs_development.mdc · 153kCursor rulespythonnode+16setupbuildtestlint-format+797/1003 days ago
skillrecordings/egghead-next.cursor/rules/gh-task-plan.mdc · 1.4kCursor rulestypescriptnode+14teststylearchtypes+296/1003 days ago
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack