Skip to content

test: add comprehensive coverage for path translator subscribers#3

Open
Decipher wants to merge 1 commit into
1.2.xfrom
feature/coverage-path-translators
Open

test: add comprehensive coverage for path translator subscribers#3
Decipher wants to merge 1 commit into
1.2.xfrom
feature/coverage-path-translators

Conversation

@Decipher

@Decipher Decipher commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Coverage: 0% → 95.1%

Fixes D11 TypeError in Contact + Wildcard subscribers (same bug as #3558380) and undefined array key in DruxtServiceProvider.

Changes

  • Bug fix: Pass route name string (not Route object) to Url::fromRoute() in Contact + Wildcard subscribers
  • Bug fix: Null coalescing on cors.config['enabled'] in DruxtServiceProvider
  • Tests: DruxtServiceProviderTest (unit), Contact/Wildcard/DruxtRequestPath kernel tests
  • CI: Enable coverage reporting on GitLab CI

Coverage breakdown

File Coverage
DruxtServiceProvider.php 100%
DruxtRequestPath.php 100%
ContactPathTranslatorSubscriber.php 95.0%
ViewsPathTranslatorSubscriber.php 95.7%
WildcardPathTranslatorSubscriber.php 92.5%

Remaining 11 uncovered lines are dead code (MethodNotAllowedException catch) and untestable defensive checks.

Summary by CodeRabbit

  • Bug Fixes

    • Improved path translation for contact and wildcard routes, including external URLs and routes with required parameters.
    • Prevented errors when CORS configuration is missing or incomplete by applying safe defaults.
    • Improved handling of routes when optional modules or translated responses are unavailable.
  • Testing

    • Expanded automated coverage for path translation, routing conditions, CORS behavior, and edge cases.
    • Added PHPUnit coverage reporting for supported source code.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Decipher, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 34 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8745ac03-65fd-4333-87fb-ec31f751d4b8

📥 Commits

Reviewing files that changed from the base of the PR and between e91b2a9 and c0f8a4b.

📒 Files selected for processing (9)
  • .gitlab-ci.yml
  • phpunit.gitlab-ci.xml
  • src/DruxtServiceProvider.php
  • src/EventSubscriber/ContactPathTranslatorSubscriber.php
  • src/EventSubscriber/WildcardPathTranslatorSubscriber.php
  • tests/src/Kernel/ContactPathTranslationKernelTest.php
  • tests/src/Kernel/DruxtRequestPathKernelTest.php
  • tests/src/Kernel/WildcardPathTranslationKernelTest.php
  • tests/src/Unit/DruxtServiceProviderTest.php
📝 Walkthrough

Walkthrough

The pull request enables PHPUnit coverage reporting, makes CORS configuration handling null-safe, resolves translated URLs from route names, and adds unit and kernel tests for service-provider, path-translation, and request-path behavior.

Changes

Druxt behavior and validation

Layer / File(s) Summary
PHPUnit coverage reporting
.gitlab-ci.yml, phpunit.gitlab-ci.xml
Coverage is enabled in CI, scoped to Druxt source PHP files, and reported as text plus Cobertura XML.
CORS default handling
src/DruxtServiceProvider.php, tests/src/Unit/DruxtServiceProviderTest.php
Missing or disabled CORS settings are enabled with default headers, while existing custom headers remain unchanged and are tested.
Path translator route resolution
src/EventSubscriber/*PathTranslatorSubscriber.php, tests/src/Kernel/*PathTranslationKernelTest.php
Contact and wildcard URL generation now uses matched route names; kernel tests cover contact, generic, external, invalid, and non-contact paths.
Druxt request-path and subscriber guards
tests/src/Kernel/DruxtRequestPathKernelTest.php
Kernel tests cover condition-plugin evaluation, JSON:API route bypasses, missing dependencies, event propagation, and request-event construction.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main theme of the PR: adding broad test coverage around path translator subscribers.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/coverage-path-translators

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.11%. Comparing base (0efc0fc) to head (c0f8a4b).

Additional details and impacted files
@@             Coverage Diff             @@
##            1.2.x       #3       +/-   ##
===========================================
+ Coverage   42.66%   95.11%   +52.44%     
===========================================
  Files           5        5               
  Lines         225      225               
===========================================
+ Hits           96      214      +118     
+ Misses        129       11      -118     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/src/Unit/DruxtServiceProviderTest.php (1)

22-35: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add a regression test for an array missing enabled.

The current non-array test does not catch the original undefined-key case (['allowedHeaders' => ...] without enabled). Add an explicit test to lock in the behavior changed at src/DruxtServiceProvider.php:23.

Suggested test
+  public function testAlterEnablesCorsWhenEnabledKeyIsMissing(): void {
+    $container = new ContainerBuilder();
+    $container->setParameter('cors.config', ['allowedHeaders' => ['x-custom']]);
+
+    (new DruxtServiceProvider())->alter($container);
+
+    $config = $container->getParameter('cors.config');
+    $this->assertTrue($config['enabled']);
+    $this->assertSame(['x-custom'], $config['allowedHeaders']);
+  }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/src/Unit/DruxtServiceProviderTest.php` around lines 22 - 35, Add a
regression test alongside testAlterWithNonArrayCorsConfig that sets cors.config
to an array containing allowedHeaders but no enabled key, invokes
DruxtServiceProvider::alter, and asserts the resulting configuration supplies
the default enabled value while preserving the provided allowedHeaders.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/EventSubscriber/WildcardPathTranslatorSubscriber.php`:
- Around line 55-57: Update the URL reconstruction in
WildcardPathTranslatorSubscriber to extract only matched route path variables
from $match_info and pass them as Url::fromRoute() parameters instead of an
empty array. Preserve existing behavior for query or non-route metadata, and
update the related test expectations for parameterized routes such as /node/1
and /page/123 from 500 to 200.

---

Nitpick comments:
In `@tests/src/Unit/DruxtServiceProviderTest.php`:
- Around line 22-35: Add a regression test alongside
testAlterWithNonArrayCorsConfig that sets cors.config to an array containing
allowedHeaders but no enabled key, invokes DruxtServiceProvider::alter, and
asserts the resulting configuration supplies the default enabled value while
preserving the provided allowedHeaders.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bc511178-e2b8-440e-b3c1-4e264f576a4d

📥 Commits

Reviewing files that changed from the base of the PR and between 0efc0fc and 17417a4.

📒 Files selected for processing (10)
  • .gitlab-ci.yml
  • phpunit.gitlab-ci.xml
  • src/DruxtServiceProvider.php
  • src/EventSubscriber/ContactPathTranslatorSubscriber.php
  • src/EventSubscriber/WildcardPathTranslatorSubscriber.php
  • tests/src/Kernel/ContactPathTranslationKernelTest.php
  • tests/src/Kernel/DruxtRequestPathKernelTest.php
  • tests/src/Kernel/ViewsPathTranslationKernelTest.php
  • tests/src/Kernel/WildcardPathTranslationKernelTest.php
  • tests/src/Unit/DruxtServiceProviderTest.php

Comment on lines +55 to +57
$route_name = $match_info[RouteObjectInterface::ROUTE_NAME];
try {
$resolved_url = Url::fromRoute($route, [], ['absolute' => TRUE])->toString(TRUE);
$resolved_url = Url::fromRoute($route_name, [], ['absolute' => TRUE])->toString(TRUE);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

ast-grep outline src/EventSubscriber/WildcardPathTranslatorSubscriber.php --items all
sed -n '34,70p' src/EventSubscriber/WildcardPathTranslatorSubscriber.php
sed -n '89,105p' tests/src/Kernel/WildcardPathTranslationKernelTest.php

# Inspect existing route-name URL generation patterns and their parameter inputs.
rg -n -C 3 --glob '*.php' 'Url::fromRoute\(\$route_name' src tests

Repository: Decipher/druxt_drupal

Length of output: 4715


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,130p' src/EventSubscriber/WildcardPathTranslatorSubscriber.php
sed -n '1,130p' src/EventSubscriber/ViewsPathTranslatorSubscriber.php
sed -n '120,200p' tests/src/Kernel/WildcardPathTranslationKernelTest.php

Repository: Decipher/druxt_drupal

Length of output: 7700


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '120,180p' tests/src/Kernel/WildcardPathTranslationKernelTest.php

cat <<'PHP' >/tmp/generate_route_params.php
<?php
$paths = [
  '/node/1',
  '/page/123',
  '/admin/config/system/site-information',
  '/user/login',
];
foreach ($paths as $path) {
  $routePath = str_replace('}', '', str_replace('{', '', $path));
  $tokens = preg_split('/[\/a-zA-Z0-9]+/', $routePath, -1, PREG_SPLIT_NO_EMPTY);
  echo "$path\t" . implode(' ', $tokens) . "\n";
}
PHP
php /tmp/generate_route_params.php

Repository: Decipher/druxt_drupal

Length of output: 232


Preserve matched route parameters when rebuilding the URL.

/node/1 and /page/123 now return 500 because the matched parameters such as {node} are dropped before Url::fromRoute() is called. Filter the matched route variables to route path parameters only and pass them to Url::fromRoute() instead of an empty array; then update the related test expectation to 200.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/EventSubscriber/WildcardPathTranslatorSubscriber.php` around lines 55 -
57, Update the URL reconstruction in WildcardPathTranslatorSubscriber to extract
only matched route path variables from $match_info and pass them as
Url::fromRoute() parameters instead of an empty array. Preserve existing
behavior for query or non-route metadata, and update the related test
expectations for parameterized routes such as /node/1 and /page/123 from 500 to
200.

@Decipher
Decipher force-pushed the feature/coverage-path-translators branch from 17417a4 to e91b2a9 Compare July 24, 2026 06:48

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/src/Kernel/ContactPathTranslationKernelTest.php`:
- Around line 62-76: Update translatePath to handle the subscriber’s
early-return case before calling getResponse(), ensuring unset paths receive an
explicit response by dispatching the controller endpoint or setting/checking the
response. Keep the existing status and JSON data extraction for initialized
responses.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 707e5f5e-073a-496b-9c8c-80a6df8f110c

📥 Commits

Reviewing files that changed from the base of the PR and between 17417a4 and e91b2a9.

📒 Files selected for processing (9)
  • .gitlab-ci.yml
  • phpunit.gitlab-ci.xml
  • src/DruxtServiceProvider.php
  • src/EventSubscriber/ContactPathTranslatorSubscriber.php
  • src/EventSubscriber/WildcardPathTranslatorSubscriber.php
  • tests/src/Kernel/ContactPathTranslationKernelTest.php
  • tests/src/Kernel/DruxtRequestPathKernelTest.php
  • tests/src/Kernel/WildcardPathTranslationKernelTest.php
  • tests/src/Unit/DruxtServiceProviderTest.php
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/DruxtServiceProvider.php
  • src/EventSubscriber/WildcardPathTranslatorSubscriber.php
  • src/EventSubscriber/ContactPathTranslatorSubscriber.php
  • .gitlab-ci.yml
  • tests/src/Unit/DruxtServiceProviderTest.php
  • tests/src/Kernel/WildcardPathTranslationKernelTest.php
  • tests/src/Kernel/DruxtRequestPathKernelTest.php

Comment on lines +62 to +76
private function translatePath(string $path): array {
$request = Request::create('/router/translate-path', 'GET');
$event = new PathTranslatorEvent(
$this->container->get('http_kernel'),
$request,
HttpKernelInterface::MAIN_REQUEST,
$path
);
$this->container->get('druxt.contact_path_translator.subscriber')->onPathTranslation($event);

$response = $event->getResponse();
return [
'status' => $response->getStatusCode(),
'data' => json_decode((string) $response->getContent(), TRUE),
];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -C 4 'class PathTranslatorEvent|function getResponse|function setResponse|onPathTranslation' .

Repository: Decipher/druxt_drupal

Length of output: 7799


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate and inspect PathTranslatorEvent class and getResponse implementation without running repository code.
rg -n -C 6 'class PathTranslatorEvent|function .*\bgetResponse\b' .

# Read focused test and subscriber contexts.
for f in $(git ls-files | rg '(^|/)PathTranslatorEvent\.php$|tests/src/Kernel/(Contact|Views|Wildcard|DruxtRequestPath)PathTranslationKernelTest\.php$'); do
  echo "===== $f ====="
  sed -n '1,220p' "$f"
done

Repository: Decipher/druxt_drupal

Length of output: 159


🏁 Script executed:

#!/bin/bash
set -euo pipefail

grep -RInE 'class PathTranslatorEvent|function .*getResponse|getResponse\(' . || true

git ls-files | grep -E '(^|/)PathTranslatorEvent\.php$|tests/src/Kernel/(Contact|Views|Wildcard|DruxtRequestPath)PathTranslationKernelTest\.php$|EventSubscriber/(Contact|Views|Wildcard)PathTranslatorSubscriber\.php$' || true

Repository: Decipher/druxt_drupal

Length of output: 1324


🌐 Web query:

php drupal decoupled router PathTranslatorEvent getResponse

💡 Result:

In the Drupal Decoupled Router module, PathTranslatorEvent is a custom kernel event used to process path translation requests [1][2]. The getResponse method is a member function of this event class that retrieves the response object associated with the path translation process [1]. When a request is made to the path translation endpoint, the PathTranslator controller dispatches a PathTranslatorEvent [1]. Event subscribers, such as RouterPathTranslatorSubscriber or RedirectPathTranslatorSubscriber, are responsible for handling this event and setting the appropriate response (typically a CacheableJsonResponse) onto the event object [1][2][3]. After the event is dispatched, the PathTranslator controller calls $event->getResponse to retrieve this response object [1]. The controller then further modifies or returns this response to the consumer, ensuring that necessary cacheability metadata and headers (such as Content-Type: application/json) are attached [1]. In summary, the workflow is as follows: 1. The controller creates a PathTranslatorEvent and dispatches it [1]. 2. Event subscribers perform logic to resolve the path and call $event->setResponse($response) to attach the results [1]. 3. The controller retrieves the result using $event->getResponse and returns it to the client [1].

Citations:


🌐 Web query:

github drupydrup/decoupled_router PathTranslatorEvent getResponse setResponse

💡 Result:

In the Drupal Decoupled Router module, PathTranslatorEvent is a custom event class used to facilitate the translation of paths [1][2]. It extends Symfony's KernelEvent and is dispatched by the PathTranslator controller [1][2]. The PathTranslatorEvent class provides methods to manage the response during the path translation process, specifically getResponse and setResponse [1]. These methods allow event subscribers (such as those handling routers or redirects) to intervene in the translation process and provide a response if they can successfully resolve the path [1][2]. When the PathTranslator::translate method is called: 1. A new PathTranslatorEvent object is created [1]. 2. The event is dispatched via the event dispatcher [1]. 3. Event subscribers listen for this event and use setResponse to attach a result (typically a cacheable JSON response) if they identify a valid route or redirect for the requested path [1][2]. 4. Finally, the controller retrieves the response using getResponse and returns it to the client [1]. If no subscriber sets a response, the controller continues its logic to return a default or "not found" response [1].

Citations:


🌐 Web query:

github Realityloop/decoupled_router PathTranslatorEvent.php

💡 Result:

The file PathTranslatorEvent.php is a component of the Drupal module Decoupled Router (maintained by Realityloop) [1][2]. This file defines the PathTranslatorEvent class, which is a KernelEvent used within the module to manage the process of translating incoming front-end paths into Drupal entity information [3]. Key technical details include: - Functionality: The Decoupled Router module provides an API endpoint (typically /router/translate-path) that resolves URL aliases and redirects to their underlying Drupal entities [3][1]. - Role of the Event: When the PathTranslator controller processes a request, it instantiates a PathTranslatorEvent [4]. This event is then dispatched via the event dispatcher to various subscribers (such as RouterPathTranslatorSubscriber and RedirectPathTranslatorSubscriber) that perform the actual resolution logic [5][3]. - Event Lifecycle: Subscribers listening to this event are responsible for setting the appropriate response (typically including cacheability metadata) on the event object [4][3]. The module is designed for decoupled applications, allowing them to resolve paths without needing to be aware of Drupal's internal routing structure [1][2]. It is currently compatible with Drupal 10 and 11 [6][7].

Citations:


🌐 Web query:

site:github.com/Realityloop/decoupled_router "class PathTranslatorEvent" "getResponse"

💡 Result:

There is no standard or widely documented class named PathTranslatorEvent with a getResponse method in common PHP or Drupal frameworks. The available search results identify event subscribers related to path translation in the decoupled_router module for Drupal [1], but they do not define or reference a class named PathTranslatorEvent [1]. It is possible that this class is part of a custom, non-public, or project-specific codebase.

Citations:


🌐 Web query:

"PathTranslatorEvent" "isPropagationStopped" "getResponse"

💡 Result:

PathTranslatorEvent is a custom event class used in the Decoupled Router module for Drupal to handle path translation requests [1][2]. While it is not a core Symfony event, it follows standard patterns common to Symfony-based architectures [1]. In this context: getResponse: This method is used to retrieve the response object associated with the event [2]. Event subscribers are responsible for setting this response, which may include specific cacheability metadata [1][2]. isPropagationStopped: This is a standard method inherited from the Symfony event dispatcher contract (or the underlying event class) [3][4]. It returns a boolean value indicating whether further event listeners should be triggered for this event [3][4]. Typically, when a subscriber processes the PathTranslatorEvent, it performs the necessary translation and uses a method like setResponse to attach the result [2]. Setting a response in such events often implicitly or explicitly involves stopping propagation to ensure no other listeners attempt to override the generated response [3][5][6]. top_results: [1][2][3][4]

Citations:


🌐 Web query:

GitHub decoupled_router PathTranslatorEvent setResponse \$response = null

💡 Result:

In the context of the Drupal Decoupled Router module, the PathTranslatorEvent is a custom event class used to handle the translation of path aliases and redirects into entity-related information [1][2]. The event is dispatched by the PathTranslator controller [3]. Event subscribers, such as RouterPathTranslatorSubscriber and RedirectPathTranslatorSubscriber, listen for this event and are responsible for setting the response by calling the setResponse method on the PathTranslatorEvent instance [3][1][4]. Regarding your specific query about "$response = null", the PathTranslatorEvent class typically includes a protected $response property, which is initialized to null by default [5]. This property is designed to be populated by the relevant event subscribers [3]. If a subscriber determines that it can resolve the path, it calls $event->setResponse($response), where $response is a Symfony Response object (often a CacheableJsonResponse) [3]. If no subscriber handles the event, the $response property remains null [5]. In the PathTranslator controller's translate method, the code retrieves the response using $event->getResponse [3]. If it is still null at that point, the code will likely result in an error or unexpected behavior, as it subsequently attempts to add headers and cacheability metadata to that response object [3]. Therefore, checking if the response is null is an important aspect of ensuring the path translation process has succeeded [3]. top_results: [3][1][4][2][5]

Citations:


Handle the early-return response before dereferencing.

PathTranslatorEvent does not initialize a default 404 response; unset paths need an explicit response before callers can safely read status/content. In the short-circuit test, dispatch the controller endpoint or set/check the response explicitly after the subscriber returns.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/src/Kernel/ContactPathTranslationKernelTest.php` around lines 62 - 76,
Update translatePath to handle the subscriber’s early-return case before calling
getResponse(), ensuring unset paths receive an explicit response by dispatching
the controller endpoint or setting/checking the response. Keep the existing
status and JSON data extraction for initialized responses.

Fix D11 TypeError in Contact and Wildcard subscribers (same bug as
#3558380 in Views subscriber) by passing route name instead of Route
object to Url::fromRoute().

Fix undefined array key warning in DruxtServiceProvider when cors.config
parameter is null or missing 'enabled' key.

Add kernel/unit tests covering all src/ files (95.1% line coverage):
- DruxtServiceProviderTest (unit, CORS defaults)
- ContactPathTranslationKernelTest (contact form translation)
- WildcardPathTranslationKernelTest (generic route translation)
- DruxtRequestPathKernelTest (condition plugin bypass)

Enable GitLab CI coverage reporting via Cobertura XML artifacts.
@Decipher
Decipher force-pushed the feature/coverage-path-translators branch from e91b2a9 to c0f8a4b Compare July 24, 2026 07:14
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.

1 participant