feat: perform end to end testing of admin interfaces and bugfixes - #50
feat: perform end to end testing of admin interfaces and bugfixes#50vtotalova wants to merge 72 commits into
Conversation
…sable component to use it on main page and while onboarding
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
There was a problem hiding this comment.
Pull request overview
Adds a frontend-driven FE↔BE integration test suite that runs against the real local docker stack, and fixes several issues uncovered during end-to-end coverage (Axios error handling, Spring Security matchers, and Hibernate/Jackson serialization), plus refreshes project documentation and seeded dev/test users.
Changes:
- Add Vitest-based integration tests + Node test harness (Keycloak token helpers, Postgres helpers, fixtures) and
npm run test:integration. - Fix FE Axios error handling to preserve
AxiosError, fix BE security matcher ordering, and prevent Jackson from serializing lazy Hibernate proxies. - Update docs/Keycloak realm seed data and clean up outdated/dead repo artifacts.
Reviewed changes
Copilot reviewed 28 out of 30 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
vitest.integration.config.ts |
Adds dedicated Vitest config for sequential integration tests. |
src/test/setup.ts |
Mocks Keycloak JS for Node-based tests. |
src/test/keycloak-helpers.ts |
Adds Keycloak password-grant + admin-API bootstrap helpers for tests. |
src/test/fixtures.ts |
Provides cached tokens/IDs and axios auth helpers for integration tests. |
src/test/db-helpers.ts |
Adds direct Postgres helpers for test setup/cleanup. |
src/lib/api/client.ts |
Preserves original AxiosError while improving user-facing error messages. |
src/lib/api/__tests__/auth.integration.test.ts |
Adds auth/me integration coverage (401 + role assertions). |
src/lib/api/__tests__/admin.integration.test.ts |
Adds admin import integration coverage (JSON + file upload + RBAC). |
src/lib/api/__tests__/competencies.integration.test.ts |
Adds competencies CRUD + RBAC integration coverage. |
src/lib/api/__tests__/competency-relationships.integration.test.ts |
Adds relationships listing + voting-created relationship checks. |
src/lib/api/__tests__/competency-resource-links.integration.test.ts |
Adds competency-resource-links CRUD integration coverage. |
src/lib/api/__tests__/contributor-stats.integration.test.ts |
Adds contributor stats response-shape integration coverage. |
src/lib/api/__tests__/learning-resources.integration.test.ts |
Adds learning-resources CRUD + RBAC integration coverage. |
src/lib/api/__tests__/scheduling.integration.test.ts |
Adds scheduling/voting integration coverage (vote types + unvote). |
src/lib/api/__tests__/users.integration.test.ts |
Adds users admin-only API integration coverage + consent acceptance. |
server/src/main/java/de/tum/cit/memo/security/SecurityConfig.java |
Adjusts matcher ordering to allow authenticated access to consent + stats endpoints. |
server/src/main/java/de/tum/cit/memo/entity/CompetencyResourceLink.java |
Prevents Jackson from serializing lazy @ManyToOne proxies. |
server/src/main/resources/db/migration/V11__add_consent_ttl_tracking.sql |
Adds consent tracking columns + backfill for existing users. |
server/docker/keycloak/memo-realm.json |
Seeds e2e-user / e2e-admin for local dev and integration tests. |
server/src/test/java/de/tum/cit/memo/security/SecurityConfigIntegrationTest.java |
Expands security integration assertions (401/403/200 + CORS preflight). |
server/src/test/java/de/tum/cit/memo/security/DbRoleJwtAuthenticationConverterTest.java |
Adds unit tests for DB-driven role conversion behavior. |
server/src/test/java/de/tum/cit/memo/repository/UserRepositoryTest.java |
Fixes unique-email test to assert on the actual write/flush failure. |
server/src/test/java/de/tum/cit/memo/controller/AdminInterfaceE2ETest.java |
Adds server-side E2E tests for admin interfaces across the full stack. |
server/README.md |
Refreshes backend docs: seeded users, endpoint inventory, role gates, curl examples. |
README.md |
Refreshes root docs: ports, seeded users, endpoint highlights, integration test instructions. |
CLAUDE.md |
Updates documented stack/tools and removes references to deleted/outdated docs/agents. |
package.json |
Adds test:integration and dev deps (vitest, pg, @types/pg). |
package-lock.json |
Locks new dev dependencies (Vitest + pg + transitive deps). |
scripts/init-db.sql |
Deletes unused/incorrect DB init script. |
.claude/agents/nextjs-expert.md |
Deletes outdated Next.js-specific Claude agent definition. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| .requestMatchers("/swagger-ui/**", "/swagger-ui.html", "/api-docs/**").permitAll() | ||
| .requestMatchers("/actuator/health").permitAll() | ||
| .requestMatchers(HttpMethod.POST, "/api/users/me/accept-consent").authenticated() | ||
| .requestMatchers(HttpMethod.GET, "/api/users/*/stats").authenticated() |
| * DbRoleJwtAuthenticationConverter → Controller → Service → Repository → Database stack. | ||
| * | ||
| * <p>An admin user with id {@code e2e-admin} is pre-seeded before each test so that | ||
| * {@code jwt().jwt(j -> j.subject("e2e-admin"))} resolves to {@code ROLE_ADMIN} through | ||
| * the real {@link de.tum.cit.memo.security.DbRoleJwtAuthenticationConverter}. | ||
| * Plain {@code jwt()} (unknown subject) resolves to {@code ROLE_USER}. |
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
Description
Adds a frontend-side integration test suite (
npm run test:integration) that exercises the realfrontend axios client against the running backend stack — covering every REST module: auth,
competencies, learning resources, users, relationships, resource links, scheduling/voting,
contributor stats, and admin imports. While building it, the suite surfaced four real bugs across
the FE and BE; this PR fixes them and refreshes outdated documentation.
Type of Change
expected)
Related Issues
Changes Made
Client:
src/lib/api/__tests__/(9 files, 42 tests)driving the real
src/lib/api/*modules against the running backend.src/test/harness: Keycloak password-grant token helper with idempotent admin-API userbootstrap, direct Postgres helpers for admin promotion and test-data cleanup, cached fixtures
for
getUserToken/getAdminToken/authAs.vitest.integration.config.ts(single-fork, sequential, scoped to*.integration.test.ts).npm run test:integrationscript.src/lib/api/client.ts: response interceptor now mutateserror.messageandre-throws the original
AxiosErrorinstead of wrapping it in a plainError— restoresaxios.isAxiosError(err)so the 404→null fallbacks ingetByUrlandgetByEmailactually fire.Server:
SecurityConfig.java:POST /api/users/me/accept-consentandGET /api/users/{userId}/statswere caught by the catch-all/api/users/**ADMIN matcher andreturned 403 for regular users. Added two specific authenticated matchers ahead of the catch-all
so users can accept their own consent and view their own stats.
CompetencyResourceLink.java: added@JsonIgnoreon the three lazy@ManyToOneassociations (
competency,resource,user) —GET /api/competency-resource-links/{id}and/api/competency-resource-linkswere returning 500 "Type definition error: ByteBuddyInterceptor"because Jackson was trying to serialize the Hibernate proxies. Scalar
competencyId/resourceId/userIdfields stay in the response, so the API contract is unchanged.UserRepositoryTest.shouldEnforceUniqueEmail: with@Sqlsetting the constraintto IMMEDIATE, the conflicting
saveAndFlush(user2)throws right there — the assertion waswrapping a no-op
SET CONSTRAINTS IMMEDIATEcall instead of the actual write. MovedassertThatThrownByaroundsaveAndFlush(user2)and updated the expected type toDataIntegrityViolationException(the exception actually thrown).DbRoleJwtAuthenticationConverterTest.java(pre-existingviolation that broke
./gradlew build).Database:
Other:
e2e-user@memo.local/e2e-user(USER) ande2e-admin@memo.local/e2e-admin(ADMIN)to
server/docker/keycloak/memo-realm.json, both pre-verified.CLAUDE.md— corrected stack (Vite/React Router 7, not Next.js; Spring Boot 3.4 / Java17 / Postgres 18, not 4.0/25/16); removed references to non-existent
QUICKSTART.mdandMIGRATION_COMPLETE.mdand the deletednextjs-expertagent.README.md— fixed the frontend port (3000, not 5173), replaced the never-existingdemo/admindefault users with the actually-seedede2e-user/e2e-admin, removed the bogusPOST /api/competency-relationshipsendpoint reference, added an Integration Tests section.server/README.md— full endpoint inventory with role gates, fixed seeded users, fixedthe
curlexample, added a note on DB-driven role resolution.scripts/init-db.sql(unreferenced; comment claimed Prisma but project uses Flyway) andthe now-empty
scripts/directory..claude/agents/nextjs-expert.md(project is Vite, not Next.js).Testing
Test Cases
./gradlew buildis green; pre-existingUserRepositoryTest.shouldEnforceUniqueEmailwas failing onmainand is now fixed)against the running docker stack)
endpoints; 404→null fallbacks tested for
getByUrl/getByEmail; all four vote typestested in scheduling)
Manual Testing
cd server && ./server-manage.sh up→ stack healthynpm run test:integration→ 42/42 passing in ~3s./gradlew build→ green (spotless + tests + bootJar)npm run quality→ greene2e-usercan accept own consent and read own statse2e-useris correctly denied on admin-only endpoints (delete competency, listusers, admin import)
e2e-adminsucceeds on the same endpoints