test(backend): add OpenAPI spec assertions + regenerate frontend API client

- Add acceptance criteria assertions to OpenApiGeneratorTest:
  - Verify /api/community/admin/memberships path exists
  - Verify /api/admin/users path exists
  - Verify getAllUsers operation exists
- Regenerate frontend API client from OpenAPI spec
- Fix frontend type error: remove unnecessary userId parameter
  from deleteUserTariff call (backend uses @CurrentUserId from JWT)
This commit is contained in:
Bernhard Müller 2026-07-24 07:30:26 +02:00
parent 3e336ca3c9
commit e46b21c8ca
3 changed files with 63 additions and 55 deletions

View File

@ -11,6 +11,7 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -34,5 +35,13 @@ class OpenApiGeneratorTest {
Files.writeString(outputPath, openApiYaml, StandardCharsets.UTF_8); Files.writeString(outputPath, openApiYaml, StandardCharsets.UTF_8);
System.out.println("OpenAPI YAML erfolgreich nach " + outputPath.toAbsolutePath() + " exportiert."); System.out.println("OpenAPI YAML erfolgreich nach " + outputPath.toAbsolutePath() + " exportiert.");
// Verify acceptance criteria
assertTrue(openApiYaml.contains("/api/community/admin/memberships"),
"OpenAPI Spec muss /api/community/admin/memberships enthalten");
assertTrue(openApiYaml.contains("/api/admin/users"),
"OpenAPI Spec muss /api/admin/users enthalten");
assertTrue(openApiYaml.contains("getAllUsers"),
"OpenAPI Spec muss getAllUsers Operation enthalten");
} }
} }

View File

@ -91,6 +91,59 @@ export class AdminIAMService extends BaseService {
); );
} }
/**
* Lädt alle User
* Zeigt alle registrierten Benutzer sortiert nach Erstellungsdatum (neueste zuerst).
* @endpoint get /api/admin/users
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
* @param options additional options
*/
public getAllUsers(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<Array<UserProfileResponse>>;
public getAllUsers(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpResponse<Array<UserProfileResponse>>>;
public getAllUsers(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpEvent<Array<UserProfileResponse>>>;
public getAllUsers(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<any> {
let localVarHeaders = this.defaultHeaders;
const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
'application/json'
]);
if (localVarHttpHeaderAcceptSelected !== undefined) {
localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
}
const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
const localVarTransferCache: boolean = options?.transferCache ?? true;
let responseType_: 'text' | 'json' | 'blob' = 'json';
if (localVarHttpHeaderAcceptSelected) {
if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
responseType_ = 'text';
} else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
responseType_ = 'json';
} else {
responseType_ = 'blob';
}
}
let localVarPath = `/api/admin/users`;
const { basePath, withCredentials } = this.configuration;
return this.httpClient.request<Array<UserProfileResponse>>('get', `${basePath}${localVarPath}`,
{
context: localVarHttpContext,
responseType: <any>responseType_,
...(withCredentials ? { withCredentials } : {}),
headers: localVarHeaders,
observe: observe,
...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
reportProgress: reportProgress
}
);
}
/** /**
* Lädt alle wartenden User * Lädt alle wartenden User
* Zeigt User im Status PENDING inkl. der Ergebnisse des EDA-Netz-Checks. * Zeigt User im Status PENDING inkl. der Ergebnisse des EDA-Netz-Checks.
@ -144,58 +197,6 @@ export class AdminIAMService extends BaseService {
); );
} }
/**
* Lädt alle User
* Zeigt alle registrierten Benutzer.
* @endpoint get /api/admin/users
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
* @param options additional options
*/
public getAllUsers(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<Array<UserProfileResponse>>;
public getAllUsers(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpResponse<Array<UserProfileResponse>>>;
public getAllUsers(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpEvent<Array<UserProfileResponse>>>;
public getAllUsers(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<any> {
let localVarHeaders = this.defaultHeaders;
const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
'application/json'
]);
if (localVarHttpHeaderAcceptSelected !== undefined) {
localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
}
const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
const localVarTransferCache: boolean = options?.transferCache ?? true;
let responseType_: 'text' | 'json' | 'blob' = 'json';
if (localVarHttpHeaderAcceptSelected) {
if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
responseType_ = 'text';
} else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
responseType_ = 'json';
} else {
responseType_ = 'blob';
}
}
let localVarPath = `/api/admin/users`;
const { basePath, withCredentials } = this.configuration;
return this.httpClient.request<Array<UserProfileResponse>>('get', `${basePath}${localVarPath}`,
{
context: localVarHttpContext,
responseType: <any>responseType_,
...(withCredentials ? { withCredentials } : {}),
headers: localVarHeaders,
observe: observe,
...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
reportProgress: reportProgress
}
);
}
/** /**
* User ablehnen * User ablehnen
* Lehnt den Antrag ab (z.B. weil Zählpunkt nicht ins Netz passt). * Lehnt den Antrag ab (z.B. weil Zählpunkt nicht ins Netz passt).

View File

@ -189,9 +189,7 @@ export class UserTariffComponent implements OnInit, OnDestroy {
onDelete(tariff: UserTariffResponse) { onDelete(tariff: UserTariffResponse) {
if (!confirm('Möchtest du diesen Tarif wirklich löschen?')) return; if (!confirm('Möchtest du diesen Tarif wirklich löschen?')) return;
const userId = this.authService.getCurrentUserId(); this.userTariffService.deleteUserTariff(tariff.id!).subscribe({
if (!userId) return;
this.userTariffService.deleteUserTariff(tariff.id!, userId).subscribe({
next: () => { next: () => {
this.toastService.success('Tarif erfolgreich gelöscht.'); this.toastService.success('Tarif erfolgreich gelöscht.');
this.loadUserTariffs(this.selectedCommunityId()); this.loadUserTariffs(this.selectedCommunityId());