Awesome Testing

Markdown document

Plan implementacji

Lekcja 6: Fixture zalogowanego użytkownika

Historical artifacts may name disposable training credentials and environments. Do not reuse credentials, target course systems, or execute archived prompts without authorization.

Plan implementacji: fixture zalogowanego użytkownika

Cel

Dodać w l5 reużywalny fixture Playwright, który przygotowuje świeżego użytkownika do testów endpointów wymagających JWT.

Fixture ma:

  • wygenerować dane użytkownika przez UserGenerator.generateUser(),
  • zarejestrować użytkownika przez POST /api/v1/users/signup,
  • zalogować tego samego użytkownika przez POST /api/v1/users/signin,
  • zwrócić dane wygenerowanego użytkownika oraz token JWT,
  • posłużyć jako start do pokrycia GET /api/v1/users/me.

Punkt startowy

Folder l5 zawierał już:

  • generator użytkowników w generator/user-generator.ts,
  • klienta auth z metodami signUp() i signIn(),
  • typy dla loginu i rejestracji,
  • testy signin, signup, OpenAPI i Swagger UI,
  • wspólne asercje HTTP.

Brakowało wspólnego mechanizmu przygotowania użytkownika zalogowanego dla testów wymagających Authorization: Bearer <token>.

Sprawdzenie zachowania API

Przed implementacją sprawdzono dokumentację i live API dla:

GET /api/v1/users/me

api-docs.json deklaruje:

  • security: bearerAuth,
  • odpowiedź 200 dla poprawnego JWT,
  • odpowiedź 401 dla braku lub niepoprawnej autoryzacji.

Live API pokazało dwie różne odpowiedzi 401:

{ "message": "Unauthorized" }

dla braku tokena oraz:

{ "message": "Invalid or expired token" }

dla niepoprawnego tokena Bearer.

Planowane pliki

l5/fixtures/authenticated-user.ts
l5/httpclients/users-client.ts
l5/types/users.ts
l5/tests/api/users/me.spec.ts

Fixture

authenticated-user.ts powinien rozszerzać bazowy test z Playwrighta.

Docelowy typ:

interface AuthenticatedUser {
  user: SignupRequest;
  token: string;
}

Fixture powinien:

  1. utworzyć AuthClient,
  2. wygenerować użytkownika,
  3. wykonać signup,
  4. sprawdzić 201,
  5. wykonać signin,
  6. sprawdzić 200,
  7. sparsować LoginResponse,
  8. zwrócić { user, token }.

Scope fixture: testowy, nie workerowy.

Uzasadnienie:

  • każdy test ma niezależnego użytkownika,
  • fullyParallel: true nie powoduje współdzielenia stanu,
  • przyszłe testy mogą mutować dane użytkownika bez wpływu na inne testy.

Klient UsersClient

Nowy klient ma obsłużyć początkowo tylko GET /api/v1/users/me.

Metody:

  • getMe(token) dla poprawnego JWT,
  • getMeWithoutAuth() dla braku nagłówka Authorization,
  • getMeWithInvalidToken() dla niepoprawnego Bearer tokena.

Oddzielne metody dla przypadków negatywnych są celowo jawne: test od razu pokazuje, jaki wariant autoryzacji sprawdza.

Testy /users/me

Testy powinny być ułożone według kodów odpowiedzi:

200
401

Nie dodajemy sztucznych przypadków 400 ani 404, bo endpoint /users/me nie ma sensownego parametru ani body, które uzasadniałyby takie scenariusze.

200

Scenariusz:

  • given: fixture przygotowuje użytkownika i JWT,
  • when: test wywołuje GET /api/v1/users/me z tokenem,
  • then: odpowiedź ma status 200, JSON, no-store cache oraz dane zgodne z wygenerowanym użytkownikiem.

Asercje body powinny być wydzielone do metody pomocniczej assertGetMeResponse.

401

Scenariusze:

  • brak tokena zwraca 401 i message: Unauthorized,
  • niepoprawny token zwraca 401 i message: Invalid or expired token.

Korekta po review

Po implementacji użytkownik poprosił o:

  • inicjalizację UsersClient w beforeEach, tak jak w istniejących testach l5/tests/api,
  • wydzielenie asercji odpowiedzi GET /users/me do osobnej metody assertGetMeResponse.

Te korekty zostały uwzględnione w finalnym kodzie.

Weryfikacja

Najpierw należy uruchomić nowy test:

cd l5
npm test -- tests/api/users/me.spec.ts

Po jego przejściu należy uruchomić pełny zestaw:

cd l5
npm test

Oczekiwany wynik:

  • spec /users/me przechodzi,
  • pełny suite l5 przechodzi bez regresji.