Skip to content

Commit 3e387c2

Browse files
coopernetesclaude
andcommitted
fix: align frontend permission field names with backend API and add Playwright UI tests
Backend uses `value`/`matchType` but the frontend type, API layer, and components still referenced the old `path`/`pathType` names, causing a crash when opening the permissions tab (Cannot read properties of undefined reading 'toLowerCase'). Also fixes validation step expand panel in push detail view: error/blocked message was never shown in the expanded section (only s.content was rendered, not s.errorMessage/s.blockedMessage). Adds a Playwright test covering the add-and-remove permission flow against the real backend (h2-mem), and wires it into CI as a new playwright-test job. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 7b6e67d commit 3e387c2

12 files changed

Lines changed: 208 additions & 19 deletions

File tree

.github/workflows/ci.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,48 @@ jobs:
120120
bash compose.sh -- logs git-proxy-java
121121
fi
122122
123+
playwright-test:
124+
name: Playwright UI Tests
125+
runs-on: ubuntu-latest
126+
if: >
127+
github.ref == 'refs/heads/main' ||
128+
github.event_name == 'pull_request'
129+
130+
steps:
131+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6
132+
133+
- uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # ratchet:actions/setup-java@v5
134+
with:
135+
distribution: temurin
136+
java-version: 25
137+
cache: gradle
138+
139+
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # ratchet:actions/setup-node@v6
140+
with:
141+
node-version: '24.15.0'
142+
cache: npm
143+
cache-dependency-path: git-proxy-java-dashboard/frontend/package-lock.json
144+
145+
- name: Install frontend dependencies
146+
run: npm ci
147+
working-directory: git-proxy-java-dashboard/frontend
148+
149+
- name: Install Playwright browsers
150+
run: npx playwright install --with-deps chromium
151+
working-directory: git-proxy-java-dashboard/frontend
152+
153+
- name: Run Playwright tests
154+
run: npm run test:e2e
155+
working-directory: git-proxy-java-dashboard/frontend
156+
157+
- name: Upload Playwright report
158+
if: always()
159+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # ratchet:actions/upload-artifact@v7
160+
with:
161+
name: playwright-report
162+
path: git-proxy-java-dashboard/frontend/playwright-report/
163+
retention-days: 14
164+
123165
dependency-submission:
124166
name: Dependency Submission
125167
runs-on: ubuntu-latest

git-proxy-java-dashboard/frontend/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ vite.config.ts.timestamp-*
3030
# Local env overrides
3131
*.local
3232

33+
# Playwright
34+
/test-results/
35+
/playwright-report/
36+
/tests/.auth/
37+
3338
# Editor directories and files
3439
.vscode/*
3540
!.vscode/extensions.json

git-proxy-java-dashboard/frontend/package-lock.json

Lines changed: 64 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

git-proxy-java-dashboard/frontend/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"lint": "eslint .",
1010
"format": "prettier --write src",
1111
"format:check": "prettier --check src",
12-
"preview": "vite preview"
12+
"preview": "vite preview",
13+
"test:e2e": "playwright test"
1314
},
1415
"dependencies": {
1516
"diff2html": "^3.4.56",
@@ -32,6 +33,7 @@
3233
"typescript": "~5.9.3",
3334
"typescript-eslint": "^8.57.0",
3435
"vite": "^8.0.1",
35-
"prettier": "^3.5.3"
36+
"prettier": "^3.5.3",
37+
"@playwright/test": "^1.49.0"
3638
}
3739
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { defineConfig, devices } from '@playwright/test'
2+
3+
export default defineConfig({
4+
testDir: './tests',
5+
use: {
6+
baseURL: 'http://localhost:8080',
7+
trace: 'on-first-retry',
8+
},
9+
webServer: {
10+
command: 'GITPROXY_DATABASE_TYPE=h2-mem ../../gradlew :git-proxy-java-dashboard:run',
11+
url: 'http://localhost:8080/api/health',
12+
timeout: 120_000,
13+
reuseExistingServer: !process.env.CI,
14+
},
15+
projects: [
16+
{
17+
name: 'setup',
18+
testMatch: /auth\.setup\.ts/,
19+
},
20+
{
21+
name: 'chromium',
22+
use: {
23+
...devices['Desktop Chrome'],
24+
storageState: 'tests/.auth/admin.json',
25+
},
26+
dependencies: ['setup'],
27+
},
28+
],
29+
})

git-proxy-java-dashboard/frontend/src/api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ export async function fetchUserPermissions(username: string) {
237237

238238
export async function addUserPermission(
239239
username: string,
240-
data: { provider: string; path: string; pathType: string; operations: string },
240+
data: { provider: string; value: string; matchType: string; operations: string },
241241
) {
242242
const res = await apiFetch(`/api/users/${encodeURIComponent(username)}/permissions`, {
243243
method: 'POST',

git-proxy-java-dashboard/frontend/src/components/PermissionBadges.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import type { RepoPermission } from '../types'
22

3-
export function PathTypeBadge({ pathType }: { pathType: RepoPermission['pathType'] }) {
3+
export function PathTypeBadge({ matchType }: { matchType: RepoPermission['matchType'] }) {
44
const styles = {
55
LITERAL: 'bg-gray-100 text-gray-600',
66
GLOB: 'bg-purple-50 text-purple-700',
77
REGEX: 'bg-orange-50 text-orange-700',
88
}
99
return (
1010
<span
11-
className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${styles[pathType]}`}
11+
className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${styles[matchType]}`}
1212
>
13-
{pathType.toLowerCase()}
13+
{matchType.toLowerCase()}
1414
</span>
1515
)
1616
}

git-proxy-java-dashboard/frontend/src/pages/PushDetail.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -804,15 +804,18 @@ export function PushDetail({ currentUser }: PushDetailProps) {
804804
<span className="text-gray-500 text-xs truncate flex-1">
805805
{s.errorMessage ?? s.blockedMessage ?? (isSkipped ? 'skipped' : '')}
806806
</span>
807-
{(isFailed || isSkipped) && s.content && (
808-
<span className="text-xs text-gray-400 shrink-0">
809-
{isOpen ? '▲ hide' : '▼ details'}
810-
</span>
811-
)}
807+
{(isFailed || isSkipped) &&
808+
(s.content || s.errorMessage || s.blockedMessage) && (
809+
<span className="text-xs text-gray-400 shrink-0">
810+
{isOpen ? '▲ hide' : '▼ details'}
811+
</span>
812+
)}
812813
</div>
813-
{isOpen && s.content && (
814+
{isOpen && (s.content || s.errorMessage || s.blockedMessage) && (
814815
<pre className="mt-2 ml-6 text-xs bg-gray-50 border border-gray-200 rounded p-3 whitespace-pre-wrap font-mono text-gray-800 overflow-x-auto">
815-
{stripAnsi(s.content)}
816+
{[s.errorMessage ?? s.blockedMessage, s.content]
817+
.filter(Boolean)
818+
.join('\n\n')}
816819
</pre>
817820
)}
818821
</div>

git-proxy-java-dashboard/frontend/src/pages/UserDetail.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -626,8 +626,8 @@ function AddPermissionModal({
626626
try {
627627
await addUserPermission(username, {
628628
provider: provider.trim(),
629-
path: path.trim(),
630-
pathType,
629+
value: path.trim(),
630+
matchType: pathType,
631631
operations,
632632
})
633633
onAdded()
@@ -790,9 +790,9 @@ function PermissionsTab({ username, isAdmin }: { username: string; isAdmin: bool
790790
</span>
791791
</td>
792792
<td className="px-4 py-3">
793-
<PathTypeBadge pathType={p.pathType} />
793+
<PathTypeBadge matchType={p.matchType} />
794794
</td>
795-
<td className="px-4 py-3 font-mono text-gray-700 text-xs">{p.path}</td>
795+
<td className="px-4 py-3 font-mono text-gray-700 text-xs">{p.value}</td>
796796
<td className="px-4 py-3">
797797
<OperationsBadge operations={p.operations} />
798798
</td>

git-proxy-java-dashboard/frontend/src/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ export interface RepoPermission {
128128
id: string
129129
username: string
130130
provider: string
131-
path: string
132-
pathType: 'LITERAL' | 'GLOB' | 'REGEX'
131+
value: string
132+
matchType: 'LITERAL' | 'GLOB' | 'REGEX'
133133
operations: 'PUSH' | 'REVIEW' | 'PUSH_AND_REVIEW' | 'SELF_CERTIFY'
134134
source: 'CONFIG' | 'DB'
135135
}

0 commit comments

Comments
 (0)