Awesome Testing

Markdown document

Podsumowanie sesji Codex

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.

Podsumowanie sesji Codex

Zakres sesji

Sesja dotyczyła przygotowania reużywalnego fixture Playwright dla testów wymagających zalogowanego użytkownika oraz JWT.

W sesji powstały:

  • plan implementacji fixture,
  • eksploracja działania JWT w live API,
  • fixture tworzący nowego użytkownika i logujący go przed testem,
  • klient UsersClient dla endpointów użytkownika,
  • typ odpowiedzi UserResponse,
  • testy GET /api/v1/users/me dla 200 i dwóch wariantów 401,
  • materiały lekcyjne bez pełnego opis_lekcji.md, bo nie ma jeszcze transkrypcji,
  • folder l6 utworzony z ukończonego stanu l5,
  • przywrócenie l5 do poprzedniego checkpointu po promocji.

Prompty użyte w Codex

Użytkownik najpierw poprosił o eksplorację JWT:

api-docs.json Explore how jwt flow works within an app using curl. Tell me if token returned by login requests indeed works for endpoints requiring security auth. Do an assessment on how jwt is implemented within app. Does it work as expected? I.e. as provided by docs

Następnie poprosił o plan:

I wish to create reusable fixture which would first register a new user and then login it. The fixture should return generated user details (see l5/generator/user-generator.ts ) and jwt token which would be required for future tests. As a start cover /users/me endpoint. Create implementation-plan.md for this feature, I wish to review it first

Po review planu użytkownik zaakceptował kierunek i doprecyzował zakres:

Ok, I like it except probably part. Check api-docs.json or explore live app for actual app behaviour. Now implement it, run it, make sure tests pass, cover 200 and 401 (both invalid and missing token) and summarise your findings

Po implementacji użytkownik zlecił refaktoryzację testu:

initialize client in beforeEach, just like l5/tests/api. Move this to separate method assertGetMeResponse const body = (await response.json()) as UserResponse;
      expect(body).toMatchObject({
        username: authenticatedUser.user.username,
        email: authenticatedUser.user.email,
        firstName: authenticatedUser.user.firstName,
        lastName: authenticatedUser.user.lastName,
        roles: ['ROLE_CLIENT'],
      });
      expect(body.id).toEqual(expect.any(Number));

Na końcu użytkownik poprosił o materiały lekcyjne i utworzenie kolejnego folderu:

$lesson-docs-pl create lesson description (do not create opis-lekcji as we have no transcript yet). Once done follow the pattern from LESSON_WORKFLOW.md and create l6

Co sprawdził Codex przed implementacją?

Codex sprawdził:

  • api-docs.json,
  • istniejące testy i klienty w l5,
  • l5/generator/user-generator.ts,
  • konfigurację Playwright,
  • live zachowanie endpointa login,
  • live zachowanie endpointów chronionych tokenem,
  • live zachowanie GET /api/v1/users/me bez tokena i z błędnym tokenem.

Potwierdzono, że login:

  • zwraca 200,
  • zwraca token i refreshToken,
  • zwraca JWT z trzema segmentami,
  • pozwala użyć Authorization: Bearer <token> dla endpointów chronionych.

Przykładowe sprawdzone endpointy chronione:

GET /api/v1/users/me
GET /api/v1/products
GET /api/v1/cart

Bez tokena endpointy zwracały 401, a z tokenem z loginu zwracały 200.

Co zaimplementował Codex?

Codex dodał:

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

authenticated-user.ts:

  • generuje użytkownika przez UserGenerator.generateUser(),
  • rejestruje go przez AuthClient.signUp(),
  • sprawdza status 201,
  • loguje go przez AuthClient.signIn(),
  • sprawdza status 200,
  • waliduje format JWT,
  • udostępnia testom authenticatedUser.user i authenticatedUser.token.

users-client.ts:

  • wywołuje GET /api/v1/users/me z poprawnym tokenem,
  • wywołuje ten sam endpoint bez autoryzacji,
  • wywołuje ten sam endpoint z niepoprawnym tokenem.

me.spec.ts pokrywa:

  • 200 dla świeżo utworzonego i zalogowanego użytkownika,
  • 401 dla braku JWT,
  • 401 dla błędnego JWT.

Jakie korekty zostały zlecone po implementacji?

Po pierwszej implementacji użytkownik poprosił o dopasowanie stylu testu do istniejących speców w l5.

Codex zmienił:

  • inicjalizację UsersClient na test.beforeEach,
  • asercje body odpowiedzi 200 na osobną funkcję assertGetMeResponse.

Dzięki temu test jest bliższy istniejącemu stylowi signin.spec.ts i signup.spec.ts.

Co wyszło w review?

W eksploracji live API wyszło, że 401 ma różne komunikaty zależnie od przyczyny:

  • brak tokena: Unauthorized,
  • niepoprawny token: Invalid or expired token.

Dlatego testy nie używają jednej wspólnej asercji dla obu przypadków, tylko sprawdzają oba komunikaty osobno.

Wynik testów

Po implementacji uruchomiono nowy spec:

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

Wynik:

3 passed

Następnie uruchomiono pełny zestaw:

cd l5
npm test

Wynik:

12 passed

Po refaktoryzacji beforeEach i assertGetMeResponse ponownie uruchomiono:

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

Wynik:

3 passed
12 passed

Podczas uruchomień pojawiał się ostrzegawczy komunikat Node o NO_COLOR i FORCE_COLOR, ale nie wpływał na wynik testów.

Finalny efekt sesji

W trakcie sesji fixture został zaimplementowany w l5, a następnie ukończony stan został promowany do l6.

Nowe testy mogą korzystać z:

authenticatedUser.user
authenticatedUser.token

Endpoint GET /api/v1/users/me ma pokryte podstawowe scenariusze:

  • poprawny JWT,
  • brak JWT,
  • niepoprawny JWT.

Po promocji l5 został przywrócony do poprzedniego checkpointu, zgodnie z LESSON_WORKFLOW.md, a kolejna lekcja startuje z aktualnego projektu w l6.