|
9 | 9 |
|
10 | 10 | - [The Standard We Hold](#-the-standard-we-hold) |
11 | 11 | - [Local Setup](#-local-setup) |
| 12 | +- [Testing Your Changes](#-testing-your-changes) |
12 | 13 | - [What to Contribute](#-what-to-contribute) |
13 | 14 | - [Automated Issue Management & Claiming](#-automated-issue-management--claiming) |
14 | 15 | - [Branch & Commit Conventions](#-branch--commit-conventions) |
@@ -88,6 +89,110 @@ http://localhost:3000/api/streak?user=YOUR_GITHUB_USERNAME |
88 | 89 |
|
89 | 90 | --- |
90 | 91 |
|
| 92 | +## 🧪 Testing Your Changes |
| 93 | + |
| 94 | +This section covers everything you need to verify your changes work correctly **before opening a PR**. There are two layers of testing: visual browser preview and the automated test suite. |
| 95 | + |
| 96 | +### 1. Visual Browser Preview |
| 97 | + |
| 98 | +With your dev server running (`npm run dev`), open your browser and visit these URLs to preview the SVG output directly: |
| 99 | + |
| 100 | +**Standard badge — valid username:** |
| 101 | + |
| 102 | +``` |
| 103 | +http://localhost:3000/api/streak?user=YOUR_GITHUB_USERNAME |
| 104 | +``` |
| 105 | + |
| 106 | +**Monthly view:** |
| 107 | + |
| 108 | +``` |
| 109 | +http://localhost:3000/api/streak?user=YOUR_GITHUB_USERNAME&view=monthly |
| 110 | +``` |
| 111 | + |
| 112 | +**Custom theme — test your color changes:** |
| 113 | + |
| 114 | +``` |
| 115 | +http://localhost:3000/api/streak?user=YOUR_GITHUB_USERNAME&theme=YOUR_THEME_NAME |
| 116 | +``` |
| 117 | + |
| 118 | +**Invalid username — must render a styled SVG error card, not raw JSON:** |
| 119 | + |
| 120 | +``` |
| 121 | +http://localhost:3000/api/streak?user=vivek%20Sangani |
| 122 | +``` |
| 123 | + |
| 124 | +**Non-existent username — must render the ghost-city not-found badge:** |
| 125 | + |
| 126 | +``` |
| 127 | +http://localhost:3000/api/streak?user=xyzabc999notreallll |
| 128 | +``` |
| 129 | + |
| 130 | +> **⚠️ Browser XML error warning:** If your browser shows an `EntityRef: expecting ';'` error instead of rendering the SVG, it means an unescaped `&` character exists somewhere in the SVG output. All `&` characters inside SVG `<style>` blocks (e.g. in Google Fonts `@import` URLs) must be written as `&`. Check `lib/svg/generator.ts` for any raw `&` in template literals. |
| 131 | +
|
| 132 | +> **💡 Tip:** For a cleaner SVG preview, open the URL in **Firefox** — it renders SVG directly in the browser with no wrapper page. Chrome wraps it in an XML viewer which can show false parse warnings. |
| 133 | +
|
| 134 | +### 2. Running the Vitest Test Suite |
| 135 | + |
| 136 | +CommitPulse uses **Vitest** for unit and integration tests. Run the full test suite with: |
| 137 | + |
| 138 | +```bash |
| 139 | +npm run test |
| 140 | +``` |
| 141 | + |
| 142 | +To run tests in watch mode while you develop (reruns on every file save): |
| 143 | + |
| 144 | +```bash |
| 145 | +npm run test -- --watch |
| 146 | +``` |
| 147 | + |
| 148 | +To run only a specific test file: |
| 149 | + |
| 150 | +```bash |
| 151 | +npm run test -- lib/calculate.test.ts |
| 152 | +``` |
| 153 | + |
| 154 | +**What a passing run looks like:** |
| 155 | + |
| 156 | +``` |
| 157 | +✓ lib/calculate.test.ts (12 tests) |
| 158 | +✓ lib/svg/generator.test.ts (8 tests) |
| 159 | +✓ app/api/streak/route.test.ts (6 tests) |
| 160 | +
|
| 161 | +Test Files 3 passed (3) |
| 162 | +Tests 26 passed (26) |
| 163 | +``` |
| 164 | + |
| 165 | +> **🚨 All tests must pass before you open a PR.** The CI pipeline runs `npm run test` automatically on every pull request and will block merging if any test fails. |
| 166 | +
|
| 167 | +### 3. Interpreting SVG Output in the Browser |
| 168 | + |
| 169 | +When you open a badge URL in your browser, here is what each response means: |
| 170 | + |
| 171 | +| What you see | What it means | |
| 172 | +| -------------------------------------------- | ---------------------------------------------------------- | |
| 173 | +| Animated isometric city renders correctly | ✅ Everything is working | |
| 174 | +| Ghost-city badge with "NOT FOUND" label | ✅ Working — the username doesn't exist on GitHub | |
| 175 | +| Styled error card with "Invalid username" | ✅ Working — the username format was invalid | |
| 176 | +| Raw JSON `{"error":"Invalid parameters"...}` | ❌ Bug — validation errors must return SVG, not JSON | |
| 177 | +| Browser XML parse error / blank white page | ❌ Bug — unescaped `&` or malformed SVG in generator | |
| 178 | +| `401 Unauthorized` in the terminal | ❌ Your `GITHUB_PAT` in `.env.local` is missing or invalid | |
| 179 | + |
| 180 | +### 4. Lint and Format |
| 181 | + |
| 182 | +Run these before every commit: |
| 183 | + |
| 184 | +```bash |
| 185 | +# Auto-format all files |
| 186 | +npm run format |
| 187 | + |
| 188 | +# Check for linting errors |
| 189 | +npm run lint |
| 190 | +``` |
| 191 | + |
| 192 | +Fix every error before pushing. CI will fail if either check reports issues. |
| 193 | + |
| 194 | +--- |
| 195 | + |
91 | 196 | ## 🤝 Contributor Onboarding |
92 | 197 |
|
93 | 198 | ### 📁 Project Structure |
|
0 commit comments