Skip to content

Équipe 3 – Phase 2: Timeout, Response Time Validation & Gherkin Editor Fixes - #56

Merged
Valeeeu merged 8 commits into
devfrom
feature/Timeout
Mar 13, 2026
Merged

Équipe 3 – Phase 2: Timeout, Response Time Validation & Gherkin Editor Fixes#56
Valeeeu merged 8 commits into
devfrom
feature/Timeout

Conversation

@michelzzw

@michelzzw michelzzw commented Mar 11, 2026

Copy link
Copy Markdown

Équipe 3 – Phase 2: Timeout, Response Time Validation & Gherkin Editor Fixes

Summary

This PR delivers the Phase 2 milestone for Équipe 3 – Gestion du Timeout, validation du temps de réponse, corrections de l'éditeur Gherkin et optimisation Docker. The objective was to implement end-to-end timeout handling for API tests, activate response time validation (previously disabled), fix editor display bugs, and optimize the Docker build pipeline.

When we started this work, the testapi microservice had no timeout configuration – Rest-Assured requests to target APIs could hang indefinitely with no error message. The backend proxy silently dropped the responseTime and expectedHeaders fields during JSON deserialization, so response time validation never triggered (testapi always received responseTime=0). The Gherkin editor had a cursor misalignment bug on the last line, and the Docker build context was 1.2 GB due to a missing .dockerignore.

After our changes, the system handles timeouts at two levels (backend→estapi proxy: 30s, testapi→arget API: 10s) with explicit error messages instead of crashes, response time validation works end-to-end, the Gherkin editor cursor is fixed, the Docker image context is down to 50 MB, and backend test coverage reaches 98% line coverage (433/438) across 24 team-owned classes with 87 tests, 0 failures.

Problems Found & Changes Made

1. No timeout on testapi microservice – RestAssured hangs indefinitely

Problem: When the target API being tested was slow or unreachable, the testapi microservice's Rest-Assured requests would block indefinitely. There was no connection timeout, socket timeout, or connection manager timeout configured. Users would see an infinite spinner with no feedback.

Changes (Testapi – TimeoutConfig.java):

  • Created TimeoutConfig (org.config.TimeoutConfig) – Spring @Configuration class that configures Rest-Assured timeouts on @PostConstruct:
    • http.connection.timeout = 10 000 ms (default, configurable via timeout.connection)
    • http.socket.timeout = 10 000 ms (default, configurable via timeout.socket)
    • http.connection-manager.timeout = 10 000 ms (default, configurable via timeout.connectionManager)
  • Modified TestManager.java – added scanBasePackages = {"org.requests", "org.config"} to @SpringBootApplication so Spring discovers TimeoutConfig at startup

Changes (Testapi – RequestController.java):

  • Added try/catch for SocketTimeoutException – returns JSON error message "❌Temps de réponse dépassé.." instead of crashing
  • Response time is now captured via System.currentTimeMillis() around the Rest-Assured call and stored in Answer.actualResponseTime

2. /slow test endpoint – missing for timeout verification

Problem: There was no way to test timeout behavior without relying on an external slow API. Developers needed a controllable endpoint to verify timeout handling.

Changes (Testapi – TestApiController.java):

  • Created GET /microservice/testapi/slow?delay=N – sleeps for delay ms (default 15 000) and returns elapsed time, Thread.currentThread().isInterrupted() status, and timestamp
  • Uses @RequestParam with defaultValue for safe invocation

3. Backend proxy drops responseTime and expectedHeaders – response time validation never triggers

Problem: The backend proxy's TestApiRequest DTO was missing the responseTime (int) and expectedHeaders (Map<String,String>) fields. When the frontend sent a test request with responseTime: 1000, Jackson silently dropped the unknown field during deserialization. The testapi microservice received responseTime=0, and checkResponseTime() returned true (skip check when 0). Users could set any response time threshold and it would always pass.

Changes (Backend – TestApiRequest.java):

  • Added private int responseTime field with getter/setter
  • Added private Map<String, String> expectedHeaders field with getter/setter
  • Jackson now correctly deserializes both fields and forwards them to testapi

Changes (Backend – application.yml):

  • Added taf.app.testAPI_timeout: 30000 – configurable timeout for the HttpClient proxy call to testapi

Changes (Backend – TestApiController.java):

  • Added @Value("${taf.app.testAPI_timeout:30000}") int testApiTimeout
  • HttpClient now uses connectTimeout(Duration.ofMillis(testApiTimeout)) and timeout(Duration.ofMillis(testApiTimeout)) on the request

4. Gherkin editor cursor misalignment on last line

Problem: When clicking on the last line of the Gherkin editor, the cursor display became chaotic – text appeared misaligned between the textarea and the highlight overlay. Root cause: the <pre> element with white-space: pre-wrap collapses trailing newlines, making the highlight layer one line shorter than the textarea. Additionally, overflow: hidden on the highlight layer prevented scroll synchronization.

Changes (Frontend – gherkin-editor.component.ts):

  • getHighlightedHtml() now appends '\n' to the output, preventing <pre> from collapsing the last line
  • Returns '\n' instead of empty string when text is empty
  • Added highlightedHtml: string cached field – HTML is recomputed only on onTextChange() instead of every Angular change detection cycle

Changes (Frontend – gherkin-editor.component.html):

  • Changed [innerHTML]="getHighlightedHtml()" to [innerHTML]="highlightedHtml" (performance: avoids method call on every CD cycle)

Changes (Frontend – gherkin-editor.component.css):

  • Changed .highlight-layer from overflow: hidden to overflow: auto – both layers now have matching scroll behavior

5. Gherkin parser rejects empty body in And the input is ''

Problem: The Gherkin parser regex for input and expected output used (.+) which required at least one character. Writing And the input is '' (empty body) resulted in an unrecognized step instead of parsing as empty string.

Changes (Frontend – gherkin-parser.service.ts):

  • Changed regex from (.+) to (.*) for both input and expectedOutput patterns
  • Empty body '' is now correctly parsed as an empty string

6. Frontend: display actualResponseTime and split TDR columns

Problem: The testapi microservice now returns actualResponseTime in the response, but the frontend model and display didn't include it.

Changes (Frontend):

  • Modified testResponseModel.ts – added actualResponseTime: number field
  • Modified testmodel2.ts – added responseTime: number and expectedHeaders: Map<string, string> fields
  • Modified test-api.component.html – displays actual response time next to test results
  • Modified add-test-dialog.component.ts – includes responseTime and expectedHeaders in the form model
图片

7. Docker build context 1.2 GB – missing .dockerignore

Problem: The Docker build context for testapi-Service was 1.2 GB because there was no .dockerignore file. Every docker compose build sent the entire workspace (including node_modules, target/, .git/) to the Docker daemon.

Changes (testapi-Service/.dockerignore):

  • Added exclusions for **/target/, **/node_modules/, **/.git/, **/dist/, build output, IDE files
  • Docker build context reduced from 1.2 GB to ~50 MB

8. Frontend persistence: HTTP-backed test definitions

Problem: The frontend TestApiService stored test definitions only in memory (BehaviorSubject). The MongoDB persistence layer was added in feature/MongoDB, but the service needed updated methods for the new persistence fields.

Changes (Frontend – test-api.service.ts):

  • Updated loadDefinitions(), addDefinition(), updateDefinition(), deleteDefinition() to call backend REST API
  • Added HttpTestingController-based tests for all HTTP operations

Changes (Frontend – test-api.service.spec.ts):

  • Added 116 lines of new test code covering load, add, update, delete with HttpTestingController

Testing & Validation

Backend Test Results

[INFO] Tests run: 87, Failures: 0, Errors: 0, Skipped: 1
[INFO] BUILD SUCCESS

87 tests (86 passing + 1 skipped contextLoads). 24 team-owned classes at 98% line coverage.

Frontend Test Results

TOTAL: 88 SUCCESS

88 specs across all frontend test suites. 0 failures.

JaCoCo Coverage Summary (Team Classes)

Class Instructions Branches Lines
AuthController 100% 100% 100%
TestApiController 100% 100% 100%
ApiTestDefinitionController 100% 100% 100%
OAuth2Controller 100% n/a 100%
WebSecurityConfig 100% 100% 100%
JwtUtils 100% 100% 100%
AuthTokenFilter 100% 100% 100%
AuthEntryPointJwt 100% 100% 100%
OAuth2LoginSuccessHandler 100% 100% 100%
UserDetailsImpl 100% 100% 100%
UserDetailsServiceImpl 100% 100% 100%
MvcConfiguration 100% n/a 100%
User 100% 100% 100%
Role 100% n/a 100%
ERole (enum) 100% n/a 100%
ApiTestDefinition 100% n/a 100%
JwtResponse 100% n/a 100%
MessageResponse 100% n/a 100%
SignupRequest 100% n/a 100%
LoginRequest 100% n/a 100%
RefreshTokenRequest 100% n/a 100%
TestApiRequest 100% n/a 100%
TestAutomationFrameworkApplication 60% n/a 60%
MvcConfiguration (inner PathResourceResolver) 25% 0% 25%
Total (24 classes) 98% 96% 98%

The 2% gap comes from TestAutomationFrameworkApplication.main() (requires real MongoDB) and MvcConfiguration's inner PathResourceResolver (anonymous class only triggered by Spring MVC routing).

Timeout Validation (Docker Integration)

Test Action Expected Actual
Normal API call GET https://jsonplaceholder.typicode.com/posts/1 200, pass Pass
Response time check (pass) responseTime=5000, delay=100ms API answer=true Pass
Response time check (fail) responseTime=1000, delay=3000ms API answer=false, message "Temps de réponse trop long : 3026 ms (max: 1000 ms)" Pass
Socket timeout Target API sleeps 15s, socket timeout 10s SocketTimeoutException caught, error message returned Pass
/slow endpoint GET /slow?delay=1000 Returns after ~1000ms with elapsed time Pass

Gherkin Editor Validation

Test Action Expected Actual
Cursor on last line Click last line of editor Cursor aligned correctly Pass
Empty body And the input is '' Parsed as empty string Pass
Scroll sync Scroll past visible area Both layers scroll together Pass
Performance Type rapidly No lag (cached highlightedHtml) Pass

Pre-push Hook

=== Pre-push hook: Running testapi-Service backend tests ===
[INFO] Tests run: 87, Failures: 0, Errors: 0, Skipped: 1
[INFO] BUILD SUCCESS
=== All tests passed  – pushing ===

System Health

Service Status Port
mongodb healthy 27017
mongo-express running 8881
registry healthy 8761
backend-team2 healthy 8084
testapi-team2 healthy 8086
frontend-team2 running 4300

Files Modified

New Files

File Description
testapi/src/main/java/org/config/TimeoutConfig.java RestAssured timeout configuration (connection/socket/connectionManager)

Modified Files (Backend)

File Type of Change
backend/src/main/java/.../controller/TestApiController.java Added testApiTimeout @value, HttpClient connectTimeout + request timeout
backend/src/main/java/.../payload/request/TestApiRequest.java Added responseTime (int) and expectedHeaders (Map) fields
backend/src/main/resources/application.yml Added taf.app.testAPI_timeout: 30000
backend/src/test/.../controller/TestApiControllerTest.java +3 tests (4 – ): timeout field, HttpClient timeout, slow server timeout

Modified Files (Testapi Microservice)

File Type of Change
testapi/src/main/java/org/requests/TestApiController.java Added /slow?delay=N endpoint with delay validation (0–2000 ms, 400 on invalid)
testapi/src/main/java/org/requests/RequestController.java SocketTimeoutException handling, actualResponseTime capture, checkResponseTime() activation
testapi/src/main/java/org/requests/TestManager.java Added scanBasePackages = {"org.requests", "org.config"}
testapi/src/main/java/org/requests/payload/request/Answer.java Added actualResponseTime field
testapi/src/main/resources/application.yml Added timeout.connection, timeout.socket, timeout.connectionManager defaults

Modified Files (Frontend – Feature)

File Type of Change
frontend/src/app/_services/gherkin-parser.service.ts Regex .+.* for empty body support
frontend/src/app/_services/test-api.service.ts HTTP persistence methods (load/add/update/delete definitions)
frontend/src/app/_services/test-api.service.spec.ts +116 lines: HttpTestingController tests
frontend/src/app/app.module.ts Updated provider imports
frontend/src/app/interface-test-api/gherkin-editor/gherkin-editor.component.ts Cached highlightedHtml, trailing \n fix
frontend/src/app/interface-test-api/gherkin-editor/gherkin-editor.component.html [innerHTML] bound to cached field
frontend/src/app/interface-test-api/gherkin-editor/gherkin-editor.component.css overflow: hiddenoverflow: auto
frontend/src/app/interface-test-api/gherkin-editor/gherkin-editor.component.spec.ts Updated assertion for trailing newline
frontend/src/app/interface-test-api/test-api/test-api.component.ts Load definitions on init, response time display
frontend/src/app/interface-test-api/test-api/test-api.component.html Display actualResponseTime in results
frontend/src/app/interface-test-api/test-api/test-api.component.spec.ts +35 lines: new component tests
frontend/src/app/interface-test-api/test-api/add-test-dialog/add-test-dialog.component.ts Added responseTime and expectedHeaders to form
frontend/src/app/models/testResponseModel.ts Added actualResponseTime field
frontend/src/app/models/testmodel2.ts Added responseTime, expectedHeaders fields

Modified Files (Infrastructure)

File Type of Change
.dockerignore Added target/, node_modules/, .git/, IDE files (1.2GB →50MB)

Modified Files (Code Review Fixes –commits 3–)

File Type of Change
frontend/src/app/interface-test-api/test-api/add-test-dialog/add-test-dialog.component.ts Fix ReDoS in URL validation regex (CodeQL high severity)
user/src/main/java/.../services/UserService.java Remove dead null-check after orElseThrow()
frontend/src/app/_services/gherkin-parser.service.ts toGherkin(): use != null instead of truthy to preserve empty strings
frontend/src/app/oauth2-callback/oauth2-callback.component.ts Restore base64url padding before atob() decode
frontend/src/app/_helpers/auth.interceptor.ts Exclude /auth/api/ and /oauth2/ paths from 401 refresh guard
frontend/src/app/_services/test-api.service.ts Fix mongoId race condition in addTestOnList() POST callback
frontend/src/app/interface-test-api/test-api/test-api.component.ts Fix deleteTest parameter type stringnumber

Modified Files (TDR Column Split – commit 6)

File Type of Change
frontend/.../test-api.component.html Split TDR column into TDR attendu (ms) + TDR (ms) with green/red coloring
frontend/.../test-api.component.ts Add actualResponseTime to displayedColumns
frontend/.../add-test-dialog.component.html Rename label “Temps de réponse” → “Temps de réponse attendu (ms)”
README.md Update form field description and add TDR column documentation

Modified Files (Documentation)

File Type of Change
README.md Updated test count (87), coverage (98%), timeout docs, responseTime/expectedHeaders fields
TEST-REPORT.md Updated branch, test count, coverage, added Timeout section (§)

Commit History

# Commit Description
1 91dc856 feat: add timeout handling, response time validation, and Gherkin editor fixes – 27 files
2 be5163e test: cover TestApiRequest responseTime/expectedHeaders getters (98% line coverage) –3 files
3 20b2bb3 fix: prevent ReDoS in URL validation regex (CodeQL high severity) –1 file
4 8c4c2ab fix: validate /slow delay parameter to prevent DoS and IllegalArgumentException –1 file
5 d394a12 fix: address 6 Copilot code review findings on PR #56 –6 files
6 15642a4 feat: split TDR column into expected/actual and rename form label –4 files

Architecture Notes

Timeout Flow

Frontend (4300)          Backend Proxy (8084)              Testapi (8086)              Target API
      |                        |                               |                         |
      +-- POST /checkApi ----->|                               |                         |
      |   {responseTime:1000}  |                               |                         |
      |                        +-- HttpClient (30s timeout) -->|                         |
      |                        |   {responseTime:1000}         |                         |
      |                        |                               +-- RestAssured (10s) --->|
      |                        |                               |   socket timeout         |
      |                        |                               |<-- Response (3026ms) ---|
      |                        |                               |                         |
      |                        |                               +-- checkResponseTime()   |
      |                        |                               |   3026ms > 1000ms       |
      |                        |                               |    – answer=false        |
      |                        |<-- JSON response -------------|                         |
      |<-- {answer:false, messages:["❌Temps de réponse..."]} |                         |

Configuration Hierarchy

# Backend (application.yml)
taf.app.testAPI_timeout: 30000   # Backend  – Testapi proxy timeout

# Testapi (application.yml)
timeout:
  connection: 10000               # Testapi  – Target API connection timeout
  socket: 10000                   # Testapi  – Target API socket read timeout
  connectionManager: 10000        # Testapi  – Target API connection pool timeout

…tor fixes

Backend:
- Add configurable testApiTimeout (default 30s) for HttpClient proxy
- Forward responseTime and expectedHeaders fields to testapi microservice
- Add 3 timeout unit tests (87 total, 0 failures)

Testapi:
- Add TimeoutConfig: RestAssured connection/socket/connectionManager timeout
- Add /slow?delay=N endpoint for timeout testing
- Handle SocketTimeoutException with explicit error message
- Enable checkResponseTime() validation (was disabled)

Frontend:
- Fix Gherkin editor cursor misalignment on last line (trailing newline)
- Cache highlightedHtml to avoid recompute on every Angular CD cycle
- Fix overflow: hidden -> auto on highlight layer for scroll sync
- Change Gherkin parser regex .+ to .* to accept empty body
- Display actualResponseTime in test results

Other:
- Optimize .dockerignore (1.2GB -> 50MB image context)
- Update README and TEST-REPORT with timeout docs and 87 tests
Copilot AI review requested due to automatic review settings March 11, 2026 18:23
Replace nested quantifiers ([a-z\d]([a-z\d\-.]*[a-z\d])*) with
atomic pattern ([a-z\d]+(?:[\-.][a-z\d]+)*) to eliminate
exponential backtracking on malicious input.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements Équipe 3 Phase 4 milestone across the testapi microservice, backend proxy, and Angular frontend: end-to-end timeout handling, response-time validation, Gherkin editor fixes, OAuth2/refresh-token support, persistence for API test definitions, and Docker/build optimizations.

Changes:

  • Added timeout configuration on both backend→testapi proxy and testapi→target API calls, with response-time capture/validation and clearer error reporting.
  • Added/updated frontend features: Gherkin editor (cursor/scroll/perf fixes), progressive test execution UI, persisted test definitions via backend CRUD, and Google OAuth2 callback + refresh-token handling.
  • Build/test/infra updates: .dockerignore, Maven/Docker tweaks, expanded test suite + docs.

Reviewed changes

Copilot reviewed 113 out of 115 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
user/src/main/java/ca/etsmtl/taf/user/services/UserService.java Adjusts update behavior and adds id null validation.
user/src/main/java/ca/etsmtl/taf/user/services/JwtService.java Removes unused imports/field wiring.
user/src/main/java/ca/etsmtl/taf/user/repository/UserRepository.java Adds @NonNull on existsById.
user/src/main/java/ca/etsmtl/taf/user/payload/request/PasswordRequest.java Removes unused import.
user/src/main/java/ca/etsmtl/taf/user/jwt/JwtUtil.java Removes unused token helpers.
user/src/main/java/ca/etsmtl/taf/user/jwt/JwtAuthenticationFilter.java Adds @NonNull annotations to filter parameters.
user/src/main/java/ca/etsmtl/taf/user/controller/UserController.java Removes unused auth-related wiring.
user/src/main/java/ca/etsmtl/taf/user/AuthGatewayApplication.java Removes unused imports.
testapi-Service/testapi/src/main/resources/application.yml Adds timeout configuration properties and fixes YAML formatting.
testapi-Service/testapi/src/main/java/org/requests/payload/request/TestApiRequest.java Migrates validation import to jakarta.
testapi-Service/testapi/src/main/java/org/requests/payload/request/Answer.java Adds actualResponseTime field to responses.
testapi-Service/testapi/src/main/java/org/requests/TestManager.java Expands Spring scan packages to include new config package.
testapi-Service/testapi/src/main/java/org/requests/TestApiController.java Adds /slow endpoint for timeout verification.
testapi-Service/testapi/src/main/java/org/requests/RequestController.java Adds timeout handling, response time capture, header/body null-guards, and re-enables response-time validation.
testapi-Service/testapi/src/main/java/org/config/TimeoutConfig.java New Rest-Assured timeout configuration via Spring @Configuration.
testapi-Service/testapi/Dockerfile Skips tests in Docker build and runs Maven in batch mode.
testapi-Service/selenium/src/test/java/ca/etsmtl/selenium/SeleniumApplicationTests.java Removes unused import.
testapi-Service/selenium/src/main/java/ca/etsmtl/selenium/requests/UseSelenium.java Updates Selenium timeout API usage and attribute retrieval.
testapi-Service/selenium/src/main/java/ca/etsmtl/selenium/config/DevCorsConfiguration.java Adds @NonNull to CORS registry parameter.
testapi-Service/run-tests-testapi.ps1 Adds a one-command backend test runner.
testapi-Service/pom.xml Sets UTF-8 encodings for build/reporting.
testapi-Service/frontend/src/environments/environment.ts Adds oauth2BackendUrl for local dev.
testapi-Service/frontend/src/environments/environment.prod.ts Adds oauth2BackendUrl for prod config.
testapi-Service/frontend/src/app/register/register.component.spec.ts Updates unit test module setup (schemas/imports).
testapi-Service/frontend/src/app/project/project.component.spec.ts Updates unit test module setup (schemas/imports).
testapi-Service/frontend/src/app/profile/profile.component.spec.ts Adds token-storage mock and NO_ERRORS_SCHEMA.
testapi-Service/frontend/src/app/performance-test-api/gatling-api/gatling-api.component.spec.ts Updates unit test module setup (schemas/imports).
testapi-Service/frontend/src/app/oauth2-callback/oauth2-callback.component.ts New OAuth2 callback handler storing tokens and user info.
testapi-Service/frontend/src/app/oauth2-callback/oauth2-callback.component.html New OAuth2 callback UI.
testapi-Service/frontend/src/app/oauth2-callback/oauth2-callback.component.css New OAuth2 callback styling.
testapi-Service/frontend/src/app/models/testmodel2.ts Adds mongo id, actual response time, and pending state support.
testapi-Service/frontend/src/app/models/testResponseModel.ts Adds actualResponseTime to response model.
testapi-Service/frontend/src/app/login/login.component.ts Supports refresh token storage and adds Google login redirect.
testapi-Service/frontend/src/app/login/login.component.spec.ts Updates unit test module setup (schemas/imports).
testapi-Service/frontend/src/app/login/login.component.html Adds Google login button UI.
testapi-Service/frontend/src/app/login/login.component.css Adds Google button styling and tweaks existing styles.
testapi-Service/frontend/src/app/interface-test-api/test-api/test-api.component.ts Adds Gherkin mode, progressive execution, loadDefinitions-on-login.
testapi-Service/frontend/src/app/interface-test-api/test-api/test-api.component.spec.ts Adds unit tests for Gherkin mode, editing, and response time UI.
testapi-Service/frontend/src/app/interface-test-api/test-api/test-api.component.html Adds Gherkin editor toggle, tooltip/spinner UI, and edit action.
testapi-Service/frontend/src/app/interface-test-api/test-api/add-test-dialog/add-test-dialog.component.ts Adds edit mode, input body field, header mapping improvements, update calls.
testapi-Service/frontend/src/app/interface-test-api/test-api/add-test-dialog/add-test-dialog.component.html Adds edit-mode titles/buttons and input textarea.
testapi-Service/frontend/src/app/interface-test-api/gherkin-editor/gherkin-editor.component.ts New Gherkin editor with overlay highlighting + scroll sync.
testapi-Service/frontend/src/app/interface-test-api/gherkin-editor/gherkin-editor.component.spec.ts New unit tests for editor parsing/highlighting and events.
testapi-Service/frontend/src/app/interface-test-api/gherkin-editor/gherkin-editor.component.html New editor template + preview + toolbar/help.
testapi-Service/frontend/src/app/interface-test-api/gherkin-editor/gherkin-editor.component.css New editor styling including overlay highlighting behavior.
testapi-Service/frontend/src/app/home/home.component.spec.ts Updates unit test module setup (schemas/imports).
testapi-Service/frontend/src/app/gatling/gatling.component.spec.ts Updates unit test module setup (schemas/imports).
testapi-Service/frontend/src/app/board-user/board-user.component.spec.ts Updates unit test module setup (schemas/imports).
testapi-Service/frontend/src/app/board-admin/board-admin.component.spec.ts Updates unit test module setup (schemas/imports).
testapi-Service/frontend/src/app/app.module.ts Registers OAuth2 callback + Gherkin editor and Material modules.
testapi-Service/frontend/src/app/app.component.ts Changes logout behavior to redirect to /login.
testapi-Service/frontend/src/app/app.component.spec.ts Adjusts test setup and removes obsolete title assertions.
testapi-Service/frontend/src/app/app-routing.module.ts Adds OAuth2 callback route.
testapi-Service/frontend/src/app/_services/user.service.spec.ts Adds HttpClientTestingModule to service test setup.
testapi-Service/frontend/src/app/_services/token-storage.service.ts Adds refresh token storage helpers.
testapi-Service/frontend/src/app/_services/test-api.service.ts Adds HTTP-backed persistence, progressive execution, pending-state helpers.
testapi-Service/frontend/src/app/_services/test-api.service.spec.ts Adds HttpTestingController coverage for persistence + progressive execution.
testapi-Service/frontend/src/app/_services/performance-test-api.service.spec.ts Adds HttpClientTestingModule to test setup.
testapi-Service/frontend/src/app/_services/gherkin-parser.service.ts New lightweight Gherkin parser + serializer.
testapi-Service/frontend/src/app/_services/auth.service.ts Adds refresh-token call to backend auth API.
testapi-Service/frontend/src/app/_services/auth.service.spec.ts Adds HttpClientTestingModule to test setup.
testapi-Service/frontend/src/app/_helpers/auth.interceptor.ts Switches to Authorization header + implements refresh-token retry logic.
testapi-Service/frontend/package.json Formatting-only change.
testapi-Service/frontend/angular.json Increases bundle/style budget thresholds.
testapi-Service/documentation/CONVENTIONS.md Documents backend testing conventions and commands.
testapi-Service/backend/src/test/resources/application.yml Adds test-only Spring config disabling Mongo/Eureka auto-config.
testapi-Service/backend/src/test/java/ca/etsmtl/taf/security/services/UserDetailsServiceImplTest.java Adds unit tests for user details loading.
testapi-Service/backend/src/test/java/ca/etsmtl/taf/security/services/UserDetailsImplTest.java Adds unit tests for UserDetails wrapper behavior.
testapi-Service/backend/src/test/java/ca/etsmtl/taf/security/oauth2/OAuth2LoginSuccessHandlerTest.java Adds unit tests for Google OAuth2 success flow and edge cases.
testapi-Service/backend/src/test/java/ca/etsmtl/taf/security/jwt/JwtUtilsTest.java Adds extensive JWT/refresh-token unit tests.
testapi-Service/backend/src/test/java/ca/etsmtl/taf/security/jwt/AuthTokenFilterTest.java Adds unit tests for JWT filter behavior.
testapi-Service/backend/src/test/java/ca/etsmtl/taf/security/jwt/AuthEntryPointJwtTest.java Adds unit tests for 401 JSON response shape.
testapi-Service/backend/src/test/java/ca/etsmtl/taf/security/WebSecurityConfigTest.java Adds security integration tests for public/protected routes.
testapi-Service/backend/src/test/java/ca/etsmtl/taf/payload/response/MessageResponseTest.java Adds DTO tests for message response.
testapi-Service/backend/src/test/java/ca/etsmtl/taf/payload/response/JwtResponseTest.java Adds DTO tests including refresh token field.
testapi-Service/backend/src/test/java/ca/etsmtl/taf/entity/UserEntityTest.java Adds entity tests including OAuth2 user constructor.
testapi-Service/backend/src/test/java/ca/etsmtl/taf/entity/RoleTest.java Adds role entity tests.
testapi-Service/backend/src/test/java/ca/etsmtl/taf/controller/TestApiControllerTest.java Adds proxy timeout + DTO forwarding tests.
testapi-Service/backend/src/test/java/ca/etsmtl/taf/controller/OAuth2ControllerTest.java Adds tests for OAuth2 helper endpoint.
testapi-Service/backend/src/test/java/ca/etsmtl/taf/controller/AuthControllerTest.java Adds tests for signin/signup/refresh-token endpoints.
testapi-Service/backend/src/test/java/ca/etsmtl/taf/controller/ApiTestDefinitionControllerTest.java Adds CRUD tests for persisted definitions.
testapi-Service/backend/src/test/java/ca/etsmtl/taf/TestAutomationFrameworkApplicationTests.java Disables full-context test requiring MongoDB.
testapi-Service/backend/src/main/resources/application.yml Adds OAuth2 config, refresh expiry, proxy timeout, redirect URL config.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/security/oauth2/OAuth2LoginSuccessHandler.java New OAuth2 success handler creating/linking users and redirecting with tokens.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/security/jwt/JwtUtils.java Adds refresh token + username-from-expired-token helpers.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/security/WebSecurityConfig.java Adds OAuth2 login support and updates security rules/session policy.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/repository/UserRepository.java Adds finders for email/googleId.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/repository/ApiTestDefinitionRepository.java New repository for persisted API test definitions.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/payload/response/JwtResponse.java Adds refresh token to auth response model.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/payload/request/TestApiRequest.java Adds responseTime + expectedHeaders to proxy DTO.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/payload/request/RefreshTokenRequest.java New request DTO for refresh-token endpoint.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/entity/User.java Adds OAuth2 provider/googleId support and adjusts username size.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/entity/ApiTestDefinition.java New persisted API test definition entity.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/controller/TestController.java Removes obsolete controller.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/controller/TestApiController.java Adds configurable HttpClient timeout for proxy requests.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/controller/OAuth2Controller.java Adds helper endpoint returning OAuth2 login URL metadata.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/controller/AuthController.java Adds refresh-token endpoint and returns refresh token on signin.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/controller/ApiTestDefinitionController.java New CRUD controller for per-user persisted definitions.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/config/OpenApiConfig.java Updates OpenAPI description for JWT + OAuth2 flows.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/config/MongoAuditingConfig.java Moves @EnableMongoAuditing into separate config for test slices.
testapi-Service/backend/src/main/java/ca/etsmtl/taf/TestAutomationFrameworkApplication.java Removes @EnableMongoAuditing annotation from main class.
testapi-Service/backend/pom.xml Adds oauth2-client, JaCoCo, encoding config; moves frontend dep to profile.
testapi-Service/backend/pom.docker.xml Adds oauth2-client dependency for Docker build.
testapi-Service/backend/.env Updates JWT expirations and adds refresh expiry.
testapi-Service/TEST-REPORT.md Adds detailed backend test report and coverage summary.
testapi-Service/Dockerfile.local Adjusts Maven test skipping flag during local Docker build.
testapi-Service/CONTRIBUTING.md Adds explicit backend test-running instructions and expectations.
testapi-Service/.dockerignore Adds ignores to reduce Docker build context size.
gateway/src/main/java/ca/etsmtl/taf/gateway/GatewayApplication.java Removes unused import.
docker-compose-local-test.yml Adds mongo-express config and updates backend env vars for OAuth2/JWT refresh.
auth/src/main/java/ca/etsmtl/taf/auth/services/JwtService.java Removes unused imports.
auth/src/main/java/ca/etsmtl/taf/auth/services/CustomUserDetailsService.java Removes unused import.
.gitignore Adds *.py ignore rule and normalizes node_modules ignore.
Comments suppressed due to low confidence (1)

testapi-Service/frontend/src/app/interface-test-api/test-api/test-api.component.ts:49

  • getTestList() creates a new subscription every time it’s called and is invoked repeatedly (e.g., in ngOnInit() and during progressive execution). This will leak subscriptions and can cause duplicated updates. Subscribe once (e.g., in ngOnInit) and store/unsubscribe on destroy, or bind tests$ directly in the template via async pipe.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +37 to +46
User user = userRepository.findByUsername(username).orElseThrow();
if(signUpRequest.getFullName().isEmpty())
if(!signUpRequest.getFullName().isEmpty())
user.setFullName(signUpRequest.getFullName());
if(signUpRequest.getEmail().isEmpty())
if(!signUpRequest.getEmail().isEmpty())
user.setEmail(signUpRequest.getEmail());

return userRepository.save(user);
if (user != null) {
return userRepository.save(user);
}
return user;

Copilot AI Mar 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update() fetches the user via orElseThrow(), so user can never be null here. The if (user != null) branch and return user; are dead code and make the flow harder to read; simplify to a single return userRepository.save(user) after applying updates.

Copilot uses AI. Check for mistakes.
Comment on lines +137 to +143
if (test.input) {
lines.push(` And the input is '${test.input}'`);
}

if (test.expectedOutput) {
lines.push(` And the expected output is '${test.expectedOutput}'`);
}

Copilot AI Mar 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toGherkin() uses truthy checks (if (test.input) / if (test.expectedOutput)) which drop empty-string values. Since parsing now supports And the input is '' / And the expected output is '', converting back to Gherkin should preserve empty strings by checking !== undefined (or != null) instead of truthiness.

Copilot uses AI. Check for mistakes.
Comment on lines +40 to +44
if (userInfoBase64) {
// Decode base64url user info
const json: string = atob(userInfoBase64.replace(/-/g, '+').replace(/_/g, '/'));
const userInfo: Record<string, unknown> = JSON.parse(json);
this.tokenStorage.saveUser(userInfo);

Copilot AI Mar 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backend encodes userInfo with Base64 URL encoding without padding (Base64.getUrlEncoder().withoutPadding()), but the frontend decodes with atob() without restoring padding. atob() can fail for unpadded base64url strings, causing OAuth2 logins to intermittently error. Add padding restoration before calling atob() (or use a dedicated base64url decode helper).

Copilot uses AI. Check for mistakes.
Comment on lines +29 to +35
return next.handle(authReq).pipe(
catchError((error: HttpErrorResponse) => {
// Only attempt refresh on 401 errors and if the request is not itself a refresh/auth request
if (error.status === 401 && !req.url.includes('/api/auth/')) {
return this.handle401Error(authReq, next);
}
return throwError(() => error);

Copilot AI Mar 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 401 refresh guard only excludes URLs containing /api/auth/, but the login endpoint used by AuthService is under /auth/api/ (via the gateway). A 401 from the signin call would incorrectly trigger refresh/logout logic. Exclude the gateway auth paths too (e.g., /auth/api/ and /oauth2/) or use a more explicit allow/deny list for refresh handling.

Copilot uses AI. Check for mistakes.
Comment on lines 124 to +133
addTestOnList(newTest: testModel2){
newTest.id= this.listTests.length+1;
this.listTests.push(newTest);
this.testsSubject.next([...this.listTests]);

// Persist to backend
this.http.post<any>(this.DEFINITIONS_API, this.toBackend(newTest)).subscribe({
next: saved => { newTest.mongoId = saved.id; },
error: err => console.error('Failed to save definition:', err)
});

Copilot AI Mar 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addTestOnList() persists asynchronously and sets newTest.mongoId in the POST callback. If the list entry is edited/replaced (updateTest() assigns this.listTests[index] = updatedTest) before the POST returns, the mongoId will be written to the old object reference and lost, breaking subsequent PUT/DELETE persistence. Consider updating the stored list element by index/id inside the POST callback and re-emitting testsSubject once the mongoId is known (or make add return an Observable and await it).

Copilot uses AI. Check for mistakes.
Comment on lines 71 to 78
// Ouvre le dialogue de suppression de test
deleteTest(id: string) {
this.isPopupOpened = true;
const dialogRef = this.dialog.open(DeleteTestDialogComponent, { data: id });
dialogRef.afterClosed().subscribe(result => {
dialogRef.afterClosed().subscribe(() => {
this.isPopupOpened = false;
this.ngOnInit();
});
this.getTestList();
}

Copilot AI Mar 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deleteTest is typed as (id: string) but testModel2.id is a number and the template calls deleteTest(row.id). With Angular template type-checking enabled this becomes a compile-time error; change the parameter type to number (or coerce explicitly) to match the model.

Copilot uses AI. Check for mistakes.
Comment on lines +28 to +36
@GetMapping("/slow")
public ResponseEntity<Map<String, Object>> slow(
@RequestParam(value = "delay", defaultValue = "15000") int delay) {
long start = System.currentTimeMillis();
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}

Copilot AI Mar 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/slow accepts an unbounded delay and passes it directly to Thread.sleep(delay). Negative values throw IllegalArgumentException (500), and very large values can tie up request threads (easy DoS). Validate/clamp delay (e.g., delay >= 0 and a reasonable max) and return 400 Bad Request for invalid inputs.

Copilot uses AI. Check for mistakes.
Comment on lines 1 to 5
export const environment = {
production: true,
apiUrl: '/my-backend'
apiUrl: '/my-backend',
oauth2BackendUrl: 'http://localhost:8084'
};

Copilot AI Mar 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

environment.prod.ts sets oauth2BackendUrl to http://localhost:8084, which will break Google login/refresh-token calls in a real production deployment and may accidentally send users to a local machine. Use a relative URL (same origin) or a production-specific value injected at build/deploy time.

Copilot uses AI. Check for mistakes.
…tException

- Reject delay < 0 or delay > 120000 ms with 400 Bad Request
- Prevents thread exhaustion from unbounded sleep values
- Addresses Copilot code review on PR #56
- UserService: remove dead null-check after orElseThrow()
- gherkin-parser: use != null instead of truthy for empty string preservation
- oauth2-callback: restore base64url padding before atob() decode
- auth.interceptor: also exclude /auth/api/ and /oauth2/ from 401 refresh
- test-api.service: fix mongoId race condition in addTestOnList POST callback
- test-api.component: fix deleteTest parameter type string -> number
@michelzzw michelzzw changed the title Équipe 3 - Phase 4: Timeout, Response Time Validation & Gherkin Editor Fixes Équipe 3 - Phase 2: Timeout, Response Time Validation & Gherkin Editor Fixes Mar 11, 2026
@michelzzw michelzzw changed the title Équipe 3 - Phase 2: Timeout, Response Time Validation & Gherkin Editor Fixes Équipe 3 – Phase 2: Timeout, Response Time Validation & Gherkin Editor Fixes Mar 11, 2026
michelzzw added a commit that referenced this pull request Mar 11, 2026
@Valeeeu
Valeeeu self-requested a review March 11, 2026 23:54
@Valeeeu
Valeeeu merged commit a0c2f0b into dev Mar 13, 2026
3 of 4 checks passed
@Valeeeu
Valeeeu deleted the feature/Timeout branch March 13, 2026 18:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants