diff --git a/composer.lock b/composer.lock index 8ba1c7b9..3b90e691 100644 --- a/composer.lock +++ b/composer.lock @@ -4399,16 +4399,16 @@ }, { "name": "drupal/helfi_api_base", - "version": "2.8.6", + "version": "2.8.9", "source": { "type": "git", "url": "https://github.com/City-of-Helsinki/drupal-module-helfi-api-base.git", - "reference": "e113eb9e541db8b7e98fbba3a817aeea29ed87e3" + "reference": "ae4d8c126cc42fd4cac3ce7ad9ac6eeea154b248" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/City-of-Helsinki/drupal-module-helfi-api-base/zipball/e113eb9e541db8b7e98fbba3a817aeea29ed87e3", - "reference": "e113eb9e541db8b7e98fbba3a817aeea29ed87e3", + "url": "https://api.github.com/repos/City-of-Helsinki/drupal-module-helfi-api-base/zipball/ae4d8c126cc42fd4cac3ce7ad9ac6eeea154b248", + "reference": "ae4d8c126cc42fd4cac3ce7ad9ac6eeea154b248", "shasum": "" }, "require": { @@ -4419,12 +4419,12 @@ "drupal/monolog": "^3.0", "drupal/raven": "^5.0 || ^6.0", "ext-curl": "*", - "firebase/php-jwt": "^6.5", + "firebase/php-jwt": "^7.0", "php": "^8.1", + "phrity/websocket": "^3.6", "symfony/polyfill-php84": "^1.0", "symfony/polyfill-php85": "^1.0", "t4web/composer-lock-parser": "^1.0", - "textalk/websocket": "^1.6", "webmozart/assert": "^1.0" }, "conflict": { @@ -4450,10 +4450,10 @@ ], "description": "Helfi - API Base", "support": { - "source": "https://github.com/City-of-Helsinki/drupal-module-helfi-api-base/tree/2.8.6", + "source": "https://github.com/City-of-Helsinki/drupal-module-helfi-api-base/tree/2.8.9", "issues": "https://github.com/City-of-Helsinki/drupal-module-helfi-api-base/issues" }, - "time": "2026-01-21T10:19:35+00:00" + "time": "2026-02-19T05:22:34+00:00" }, { "name": "drupal/helfi_azure_fs", @@ -4588,16 +4588,16 @@ }, { "name": "drupal/helfi_hakuvahti", - "version": "1.0.1", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/City-of-Helsinki/drupal-module-helfi-hakuvahti.git", - "reference": "02d48077ff1d72e08d06985a0e6150a7eb23b307" + "reference": "d04ffa2b098173315742b3ba2a44f448ad745d88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/City-of-Helsinki/drupal-module-helfi-hakuvahti/zipball/02d48077ff1d72e08d06985a0e6150a7eb23b307", - "reference": "02d48077ff1d72e08d06985a0e6150a7eb23b307", + "url": "https://api.github.com/repos/City-of-Helsinki/drupal-module-helfi-hakuvahti/zipball/d04ffa2b098173315742b3ba2a44f448ad745d88", + "reference": "d04ffa2b098173315742b3ba2a44f448ad745d88", "shasum": "" }, "require": { @@ -4613,10 +4613,10 @@ ], "description": "Helfi - Hakuvahti", "support": { - "source": "https://github.com/City-of-Helsinki/drupal-module-helfi-hakuvahti/tree/1.0.1", + "source": "https://github.com/City-of-Helsinki/drupal-module-helfi-hakuvahti/tree/1.1.0", "issues": "https://github.com/City-of-Helsinki/drupal-module-helfi-hakuvahti/issues" }, - "time": "2026-01-23T12:16:11+00:00" + "time": "2026-02-16T15:01:04+00:00" }, { "name": "drupal/helfi_navigation", @@ -8335,16 +8335,16 @@ }, { "name": "firebase/php-jwt", - "version": "v6.11.1", + "version": "v7.0.2", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66" + "reference": "5645b43af647b6947daac1d0f659dd1fbe8d3b65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/d1e91ecf8c598d073d0995afa8cd5c75c6e19e66", - "reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/5645b43af647b6947daac1d0f659dd1fbe8d3b65", + "reference": "5645b43af647b6947daac1d0f659dd1fbe8d3b65", "shasum": "" }, "require": { @@ -8392,9 +8392,9 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v6.11.1" + "source": "https://github.com/firebase/php-jwt/tree/v7.0.2" }, - "time": "2025-04-09T20:32:01+00:00" + "time": "2025-12-16T22:17:28+00:00" }, { "name": "galbar/jsonpath", @@ -8449,20 +8449,20 @@ }, { "name": "google/apiclient", - "version": "v2.18.4", + "version": "v2.19.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-api-php-client.git", - "reference": "5b51fdb2cbd2a96088e3dfc6f565bdf6fb0af94b" + "reference": "b18fa8aed7b2b2dd4bcce74e2c7d267e16007ea9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-api-php-client/zipball/5b51fdb2cbd2a96088e3dfc6f565bdf6fb0af94b", - "reference": "5b51fdb2cbd2a96088e3dfc6f565bdf6fb0af94b", + "url": "https://api.github.com/repos/googleapis/google-api-php-client/zipball/b18fa8aed7b2b2dd4bcce74e2c7d267e16007ea9", + "reference": "b18fa8aed7b2b2dd4bcce74e2c7d267e16007ea9", "shasum": "" }, "require": { - "firebase/php-jwt": "^6.0", + "firebase/php-jwt": "^6.0||^7.0", "google/apiclient-services": "~0.350", "google/auth": "^1.37", "guzzlehttp/guzzle": "^7.4.5", @@ -8512,22 +8512,22 @@ ], "support": { "issues": "https://github.com/googleapis/google-api-php-client/issues", - "source": "https://github.com/googleapis/google-api-php-client/tree/v2.18.4" + "source": "https://github.com/googleapis/google-api-php-client/tree/v2.19.0" }, - "time": "2025-09-30T04:23:07+00:00" + "time": "2026-01-09T19:59:47+00:00" }, { "name": "google/apiclient-services", - "version": "v0.423.0", + "version": "v0.433.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-api-php-client-services.git", - "reference": "c8f2e8a92e2848987db421175eaaf7602ef30c33" + "reference": "feb9c13e54457a6f5e157b7eae78b41566df43b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/c8f2e8a92e2848987db421175eaaf7602ef30c33", - "reference": "c8f2e8a92e2848987db421175eaaf7602ef30c33", + "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/feb9c13e54457a6f5e157b7eae78b41566df43b5", + "reference": "feb9c13e54457a6f5e157b7eae78b41566df43b5", "shasum": "" }, "require": { @@ -8556,26 +8556,26 @@ ], "support": { "issues": "https://github.com/googleapis/google-api-php-client-services/issues", - "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.423.0" + "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.433.0" }, - "time": "2025-12-08T01:10:26+00:00" + "time": "2026-02-16T01:42:26+00:00" }, { "name": "google/auth", - "version": "v1.49.0", + "version": "v1.50.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-auth-library-php.git", - "reference": "68e3d88cb59a49f713e3db25d4f6bb3cc0b70764" + "reference": "e1c26a718198e16d8a3c69b1cae136b73f959b0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/68e3d88cb59a49f713e3db25d4f6bb3cc0b70764", - "reference": "68e3d88cb59a49f713e3db25d4f6bb3cc0b70764", + "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/e1c26a718198e16d8a3c69b1cae136b73f959b0f", + "reference": "e1c26a718198e16d8a3c69b1cae136b73f959b0f", "shasum": "" }, "require": { - "firebase/php-jwt": "^6.0", + "firebase/php-jwt": "^6.0||^7.0", "guzzlehttp/guzzle": "^7.4.5", "guzzlehttp/psr7": "^2.4.5", "php": "^8.1", @@ -8585,7 +8585,7 @@ }, "require-dev": { "guzzlehttp/promises": "^2.0", - "kelvinmo/simplejwt": "0.7.1", + "kelvinmo/simplejwt": "^1.1.0", "phpseclib/phpseclib": "^3.0.35", "phpspec/prophecy-phpunit": "^2.1", "phpunit/phpunit": "^9.6", @@ -8593,7 +8593,7 @@ "squizlabs/php_codesniffer": "^4.0", "symfony/filesystem": "^6.3||^7.3", "symfony/process": "^6.0||^7.0", - "webmozart/assert": "^1.11" + "webmozart/assert": "^1.11||^2.0" }, "suggest": { "phpseclib/phpseclib": "May be used in place of OpenSSL for signing strings or for token management. Please require version ^2." @@ -8618,9 +8618,9 @@ "support": { "docs": "https://cloud.google.com/php/docs/reference/auth/latest", "issues": "https://github.com/googleapis/google-auth-library-php/issues", - "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.49.0" + "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.50.0" }, - "time": "2025-11-06T21:27:55+00:00" + "time": "2026-01-08T21:33:57+00:00" }, { "name": "grasmash/expander", @@ -10950,16 +10950,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "3.0.47", + "version": "3.0.49", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "9d6ca36a6c2dd434765b1071b2644a1c683b385d" + "reference": "6233a1e12584754e6b5daa69fe1289b47775c1b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/9d6ca36a6c2dd434765b1071b2644a1c683b385d", - "reference": "9d6ca36a6c2dd434765b1071b2644a1c683b385d", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/6233a1e12584754e6b5daa69fe1289b47775c1b9", + "reference": "6233a1e12584754e6b5daa69fe1289b47775c1b9", "shasum": "" }, "require": { @@ -11040,7 +11040,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.47" + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.49" }, "funding": [ { @@ -11056,31 +11056,213 @@ "type": "tidelift" } ], - "time": "2025-10-06T01:07:24+00:00" + "time": "2026-01-27T09:17:28+00:00" + }, + { + "name": "phrity/comparison", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/sirn-se/phrity-comparison.git", + "reference": "cf80abb822537eeaaeb4142157cd667ca6372a13" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sirn-se/phrity-comparison/zipball/cf80abb822537eeaaeb4142157cd667ca6372a13", + "reference": "cf80abb822537eeaaeb4142157cd667ca6372a13", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "phpstan/phpstan": "^2.0", + "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", + "robiningelbrecht/phpunit-coverage-tools": "^1.9", + "squizlabs/php_codesniffer": "^3.5 || ^4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Phrity\\Comparison\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sören Jensen", + "email": "sirn@sirn.se", + "homepage": "https://phrity.sirn.se" + } + ], + "description": "Interfaces and helper trait for comparing objects. Comparator for sort and filter applications.", + "homepage": "https://phrity.sirn.se/comparison", + "keywords": [ + "comparable", + "comparator", + "comparison", + "equalable", + "filter", + "sort" + ], + "support": { + "issues": "https://github.com/sirn-se/phrity-comparison/issues", + "source": "https://github.com/sirn-se/phrity-comparison/tree/1.4.1" + }, + "time": "2025-12-05T07:38:30+00:00" + }, + { + "name": "phrity/http", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/sirn-se/phrity-http.git", + "reference": "1e7eee67359287b94aae2b7d40b730d5f5394943" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sirn-se/phrity-http/zipball/1e7eee67359287b94aae2b7d40b730d5f5394943", + "reference": "1e7eee67359287b94aae2b7d40b730d5f5394943", + "shasum": "" + }, + "require": { + "php": "^8.1", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0" + }, + "require-dev": { + "guzzlehttp/psr7": "^2.0", + "phpstan/phpstan": "^2.0", + "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", + "robiningelbrecht/phpunit-coverage-tools": "^1.9", + "squizlabs/php_codesniffer": "^3.5 || ^4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Phrity\\Http\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sören Jensen", + "email": "sirn@sirn.se", + "homepage": "https://phrity.sirn.se" + } + ], + "description": "Utilities and interfaces for handling HTTP.", + "homepage": "https://phrity.sirn.se/http", + "keywords": [ + "HTTP Factories", + "HTTP Serializer", + "http", + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/sirn-se/phrity-http/issues", + "source": "https://github.com/sirn-se/phrity-http/tree/1.1.0" + }, + "time": "2025-12-22T20:22:29+00:00" + }, + { + "name": "phrity/net-stream", + "version": "2.3.3", + "source": { + "type": "git", + "url": "https://github.com/sirn-se/phrity-net-stream.git", + "reference": "f46694e1b721867ec3c19731a7fcbbead3c6ac89" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sirn-se/phrity-net-stream/zipball/f46694e1b721867ec3c19731a7fcbbead3c6ac89", + "reference": "f46694e1b721867ec3c19731a7fcbbead3c6ac89", + "shasum": "" + }, + "require": { + "php": "^8.1", + "phrity/util-errorhandler": "^1.1", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0" + }, + "require-dev": { + "phpstan/phpstan": "^2.0", + "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", + "phrity/net-uri": "^2.0", + "robiningelbrecht/phpunit-coverage-tools": "^1.9", + "squizlabs/php_codesniffer": "^3.5 || ^4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Phrity\\Net\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sören Jensen", + "email": "sirn@sirn.se", + "homepage": "https://phrity.sirn.se" + } + ], + "description": "Socket stream classes implementing PSR-7 Stream and PSR-17 StreamFactory", + "homepage": "https://phrity.sirn.se/net-stream", + "keywords": [ + "Socket", + "client", + "psr-17", + "psr-7", + "server", + "stream", + "stream factory" + ], + "support": { + "issues": "https://github.com/sirn-se/phrity-net-stream/issues", + "source": "https://github.com/sirn-se/phrity-net-stream/tree/2.3.3" + }, + "time": "2025-12-24T12:07:07+00:00" }, { "name": "phrity/net-uri", - "version": "1.3.0", + "version": "2.2.1", "source": { "type": "git", "url": "https://github.com/sirn-se/phrity-net-uri.git", - "reference": "3f458e0c4d1ddc0e218d7a5b9420127c63925f43" + "reference": "0737de026b75177ae302ac9fdbbd0ffc2610f3b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sirn-se/phrity-net-uri/zipball/3f458e0c4d1ddc0e218d7a5b9420127c63925f43", - "reference": "3f458e0c4d1ddc0e218d7a5b9420127c63925f43", + "url": "https://api.github.com/repos/sirn-se/phrity-net-uri/zipball/0737de026b75177ae302ac9fdbbd0ffc2610f3b8", + "reference": "0737de026b75177ae302ac9fdbbd0ffc2610f3b8", "shasum": "" }, "require": { - "php": "^7.4 | ^8.0", + "ext-mbstring": "*", + "php": "^8.1", + "phrity/comparison": "^1.0", "psr/http-factory": "^1.0", - "psr/http-message": "^1.0 | ^2.0" + "psr/http-message": "^1.1 | ^2.0" }, "require-dev": { - "php-coveralls/php-coveralls": "^2.0", - "phpunit/phpunit": "^9.0 | ^10.0", - "squizlabs/php_codesniffer": "^3.0" + "phpstan/phpstan": "^2.0", + "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", + "phrity/util-errorhandler": "^1.1", + "robiningelbrecht/phpunit-coverage-tools": "^1.9", + "squizlabs/php_codesniffer": "^3.5 || ^4.0" + }, + "suggest": { + "ext-intl": "Enables IDN conversion for non-ASCII domains" }, "type": "library", "autoload": { @@ -11109,9 +11291,9 @@ ], "support": { "issues": "https://github.com/sirn-se/phrity-net-uri/issues", - "source": "https://github.com/sirn-se/phrity-net-uri/tree/1.3.0" + "source": "https://github.com/sirn-se/phrity-net-uri/tree/2.2.1" }, - "time": "2023-08-21T10:33:06+00:00" + "time": "2025-12-05T10:39:22+00:00" }, { "name": "phrity/util-errorhandler", @@ -11165,6 +11347,71 @@ }, "time": "2025-12-05T21:25:36+00:00" }, + { + "name": "phrity/websocket", + "version": "3.6.2", + "source": { + "type": "git", + "url": "https://github.com/sirn-se/websocket-php.git", + "reference": "b9816ed2b4a10c8c42bd0b6398044ab506869756" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sirn-se/websocket-php/zipball/b9816ed2b4a10c8c42bd0b6398044ab506869756", + "reference": "b9816ed2b4a10c8c42bd0b6398044ab506869756", + "shasum": "" + }, + "require": { + "php": "^8.1", + "phrity/http": "^1.0", + "phrity/net-stream": "^2.3", + "phrity/net-uri": "^2.1", + "psr/http-message": "^1.1 | ^2.0", + "psr/log": "^1.0 || ^2.0 || ^3.0" + }, + "require-dev": { + "guzzlehttp/psr7": "^2.0", + "phpstan/phpstan": "^2.0", + "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", + "phrity/logger-console": "^1.0", + "phrity/net-mock": "^2.3", + "phrity/util-errorhandler": "^1.1", + "robiningelbrecht/phpunit-coverage-tools": "^1.9", + "squizlabs/php_codesniffer": "^3.5 || ^4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "WebSocket\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Fredrik Liljegren" + }, + { + "name": "Sören Jensen", + "email": "sirn@sirn.se", + "homepage": "https://phrity.sirn.se" + } + ], + "description": "WebSocket client and server", + "homepage": "https://phrity.sirn.se/websocket", + "keywords": [ + "client", + "server", + "websocket" + ], + "support": { + "issues": "https://github.com/sirn-se/websocket-php/issues", + "source": "https://github.com/sirn-se/websocket-php/tree/3.6.2" + }, + "time": "2025-12-21T09:58:16+00:00" + }, { "name": "psr/cache", "version": "3.0.0", @@ -11854,16 +12101,16 @@ }, { "name": "sentry/sentry", - "version": "4.19.1", + "version": "4.20.0", "source": { "type": "git", "url": "https://github.com/getsentry/sentry-php.git", - "reference": "1c21d60bebe67c0122335bd3fe977990435af0a3" + "reference": "d7264b972e5f87110492376ade1cc20cbc049345" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/1c21d60bebe67c0122335bd3fe977990435af0a3", - "reference": "1c21d60bebe67c0122335bd3fe977990435af0a3", + "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/d7264b972e5f87110492376ade1cc20cbc049345", + "reference": "d7264b972e5f87110492376ade1cc20cbc049345", "shasum": "" }, "require": { @@ -11886,7 +12133,7 @@ "monolog/monolog": "^1.6|^2.0|^3.0", "phpbench/phpbench": "^1.0", "phpstan/phpstan": "^1.3", - "phpunit/phpunit": "^8.5|^9.6", + "phpunit/phpunit": "^8.5.52|^9.6.34", "vimeo/psalm": "^4.17" }, "suggest": { @@ -11926,7 +12173,7 @@ ], "support": { "issues": "https://github.com/getsentry/sentry-php/issues", - "source": "https://github.com/getsentry/sentry-php/tree/4.19.1" + "source": "https://github.com/getsentry/sentry-php/tree/4.20.0" }, "funding": [ { @@ -11938,7 +12185,7 @@ "type": "custom" } ], - "time": "2025-12-02T15:57:41+00:00" + "time": "2026-02-16T13:47:54+00:00" }, { "name": "stomp-php/stomp-php", @@ -15307,57 +15554,6 @@ }, "time": "2022-02-23T14:59:32+00:00" }, - { - "name": "textalk/websocket", - "version": "1.6.3", - "source": { - "type": "git", - "url": "https://github.com/Textalk/websocket-php.git", - "reference": "67de79745b1a357caf812bfc44e0abf481cee012" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Textalk/websocket-php/zipball/67de79745b1a357caf812bfc44e0abf481cee012", - "reference": "67de79745b1a357caf812bfc44e0abf481cee012", - "shasum": "" - }, - "require": { - "php": "^7.4 | ^8.0", - "phrity/net-uri": "^1.0", - "phrity/util-errorhandler": "^1.0", - "psr/http-message": "^1.0", - "psr/log": "^1.0 | ^2.0 | ^3.0" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.0", - "phpunit/phpunit": "^9.0", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "WebSocket\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Fredrik Liljegren" - }, - { - "name": "Sören Jensen" - } - ], - "description": "WebSocket client and server", - "support": { - "issues": "https://github.com/Textalk/websocket-php/issues", - "source": "https://github.com/Textalk/websocket-php/tree/1.6.3" - }, - "time": "2022-11-07T18:59:33+00:00" - }, { "name": "twig/twig", "version": "v3.23.0", @@ -16824,16 +17020,16 @@ }, { "name": "justinrainbow/json-schema", - "version": "6.6.4", + "version": "v6.7.2", "source": { "type": "git", "url": "https://github.com/jsonrainbow/json-schema.git", - "reference": "2eeb75d21cf73211335888e7f5e6fd7440723ec7" + "reference": "6fea66c7204683af437864e7c4e7abf383d14bc0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/2eeb75d21cf73211335888e7f5e6fd7440723ec7", - "reference": "2eeb75d21cf73211335888e7f5e6fd7440723ec7", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/6fea66c7204683af437864e7c4e7abf383d14bc0", + "reference": "6fea66c7204683af437864e7c4e7abf383d14bc0", "shasum": "" }, "require": { @@ -16893,9 +17089,9 @@ ], "support": { "issues": "https://github.com/jsonrainbow/json-schema/issues", - "source": "https://github.com/jsonrainbow/json-schema/tree/6.6.4" + "source": "https://github.com/jsonrainbow/json-schema/tree/v6.7.2" }, - "time": "2025-12-19T15:01:32+00:00" + "time": "2026-02-15T15:06:22+00:00" }, { "name": "lullabot/mink-selenium2-driver", @@ -18780,16 +18976,16 @@ }, { "name": "phpunit/phpunit", - "version": "11.5.52", + "version": "11.5.55", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "b287d32c26f78768e391843c5a59395f24b62605" + "reference": "adc7262fccc12de2b30f12a8aa0b33775d814f00" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b287d32c26f78768e391843c5a59395f24b62605", - "reference": "b287d32c26f78768e391843c5a59395f24b62605", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/adc7262fccc12de2b30f12a8aa0b33775d814f00", + "reference": "adc7262fccc12de2b30f12a8aa0b33775d814f00", "shasum": "" }, "require": { @@ -18862,7 +19058,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.52" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.55" }, "funding": [ { @@ -18886,7 +19082,7 @@ "type": "tidelift" } ], - "time": "2026-02-08T07:05:14+00:00" + "time": "2026-02-18T12:37:06+00:00" }, { "name": "ramsey/collection", diff --git a/conf/cmi/config_ignore.settings.yml b/conf/cmi/config_ignore.settings.yml index 425b97d3..ce43aadd 100644 --- a/conf/cmi/config_ignore.settings.yml +++ b/conf/cmi/config_ignore.settings.yml @@ -4,9 +4,6 @@ mode: simple ignored_config_entities: - 'easy_breadcrumb.settings:home_segment_title' - 'hdbt_admin_tools.site_settings:site_settings' - - 'helfi_rekry_content.job_listings:hakuvahti_tos_checkbox_label' - - 'helfi_rekry_content.job_listings:hakuvahti_tos_link_text' - - 'helfi_rekry_content.job_listings:hakuvahti_tos_link_url' - 'helfi_rekry_content.job_listings:redirect_403_page' - 'helfi_rekry_content.job_listings:search_page' - 'system.site:page.front' diff --git a/public/modules/custom/helfi_rekry_content/config/schema/helfi_rekry_content.schema.yml b/public/modules/custom/helfi_rekry_content/config/schema/helfi_rekry_content.schema.yml index 03412819..bdaa9d34 100644 --- a/public/modules/custom/helfi_rekry_content/config/schema/helfi_rekry_content.schema.yml +++ b/public/modules/custom/helfi_rekry_content/config/schema/helfi_rekry_content.schema.yml @@ -34,19 +34,3 @@ helfi_rekry_content.job_listings: type: text label: 'City description text' translatable: true - hakuvahti_tos_checkbox_label: - type: label - label: 'Hakuvahti terms of service checkbox label' - translatable: true - hakuvahti_tos_link_text: - type: label - label: 'Hakuvahti terms of service link text' - translatable: true - hakuvahti_tos_link_url: - type: label - label: 'Hakuvahti terms of service URL' - translatable: true - hakuvahti_instructions_link_url: - type: label - label: 'Hakuvahti detailed instructions link URL' - translatable: true diff --git a/public/modules/custom/helfi_rekry_content/helfi_rekry_content.install b/public/modules/custom/helfi_rekry_content/helfi_rekry_content.install index bde2d29a..a8f8ff49 100644 --- a/public/modules/custom/helfi_rekry_content/helfi_rekry_content.install +++ b/public/modules/custom/helfi_rekry_content/helfi_rekry_content.install @@ -8,6 +8,7 @@ declare(strict_types=1); use Drupal\Core\Entity\TranslatableInterface; +use Drupal\language\ConfigurableLanguageManagerInterface; use Drupal\media\Entity\Media; use Drupal\migrate\MigrateExecutable; use Drupal\migrate\MigrateMessage; @@ -490,3 +491,62 @@ function helfi_rekry_content_update_9011(): void { ->dropTable($table_name); } } + +/** + * Implements hook_update_dependencies(). + */ +function helfi_rekry_content_update_dependencies(): array { + return [ + 'helfi_rekry_content' => [ + 11001 => [ + 'helfi_hakuvahti' => 11001, + ], + ], + ]; +} + +/** + * UHF-12723: Move hakuvahti settings to hakuvahti module. + */ +function helfi_rekry_content_update_11001(): void { + $rekryConfig = \Drupal::configFactory()->getEditable('helfi_rekry_content.job_listings'); + + if ($rekryConfig->isNew()) { + return; + } + + $languageManager = \Drupal::languageManager(); + assert($languageManager instanceof ConfigurableLanguageManagerInterface); + + $config = \Drupal::configFactory() + ->getEditable('helfi_hakuvahti.settings'); + + $config + ->set('hakuvahti_tos_link_url', $rekryConfig->get('hakuvahti_tos_link_url')) + ->set('hakuvahti_instructions_link_url', $rekryConfig->get('hakuvahti_instructions_link_url')) + ->save(); + + foreach (['fi', 'sv'] as $langcode) { + $original = $languageManager->getLanguageConfigOverride($langcode, 'helfi_rekry_content.job_listings'); + $override = $languageManager->getLanguageConfigOverride($langcode, 'helfi_hakuvahti.settings'); + + $override + ->set('hakuvahti_tos_link_url', $original->get('hakuvahti_tos_link_url')) + ->set('hakuvahti_instructions_link_url', $original->get('hakuvahti_instructions_link_url')) + ->save(); + + $original + ->clear('hakuvahti_tos_checkbox_label') + ->clear('hakuvahti_tos_link_text') + ->clear('hakuvahti_tos_link_url') + ->clear('hakuvahti_instructions_link_url') + ->save(); + } + + $rekryConfig + ->clear('hakuvahti_tos_checkbox_label') + ->clear('hakuvahti_tos_link_text') + ->clear('hakuvahti_tos_link_url') + ->clear('hakuvahti_instructions_link_url') + ->save(); +} diff --git a/public/modules/custom/helfi_rekry_content/src/EventSubscriber/HakuvahtiSubscriptionSubscriber.php b/public/modules/custom/helfi_rekry_content/src/EventSubscriber/HakuvahtiSubscriptionSubscriber.php index fc530b29..7b491a1b 100644 --- a/public/modules/custom/helfi_rekry_content/src/EventSubscriber/HakuvahtiSubscriptionSubscriber.php +++ b/public/modules/custom/helfi_rekry_content/src/EventSubscriber/HakuvahtiSubscriptionSubscriber.php @@ -4,6 +4,7 @@ namespace Drupal\helfi_rekry_content\EventSubscriber; +use Drupal\Component\Utility\Unicode; use Drupal\helfi_hakuvahti\Event\SubscriptionAlterEvent; use Drupal\helfi_hakuvahti\Event\SubscriptionEvent; use Drupal\helfi_hakuvahti\HakuvahtiRequest; @@ -11,9 +12,9 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** - * {@inheritdoc} + * Hakuvahti event subscriber. */ -class HakuvahtiSubscriptionSubscriber implements EventSubscriberInterface { +readonly class HakuvahtiSubscriptionSubscriber implements EventSubscriberInterface { /** * {@inheritdoc} @@ -43,20 +44,11 @@ public function hakuvahtiAlterSubscription(SubscriptionAlterEvent $event): void $request->lang, includeKeyword: TRUE ); - $data = $request->getServiceRequestData(); // Extract free search term if present, limit to 10 characters. - $freeSearchTerm = $filters['vapaa-sana'][0] ?? ''; - unset($filters['vapaa-sana']); - if (mb_strlen($freeSearchTerm) > 10) { - $freeSearchTerm = mb_substr($freeSearchTerm, 0, 10) . '...'; - } - - $parts = []; - if ($freeSearchTerm) { - $parts[] = $freeSearchTerm; - } + $parts[] = Unicode::truncate($filters['vapaa-sana'][0] ?? '', 10, add_ellipsis: TRUE); + unset($filters['vapaa-sana']); foreach ($filters as $items) { foreach ($items as $item) { if ($item) { @@ -65,8 +57,8 @@ public function hakuvahtiAlterSubscription(SubscriptionAlterEvent $event): void } } - $event->setHakuvahtiRequest(new HakuvahtiRequest(array_merge($data, [ - 'search_description' => implode(', ', $parts), + $event->setHakuvahtiRequest(new HakuvahtiRequest(array_merge((array) $request, [ + 'searchDescription' => implode(', ', array_filter($parts)), ]))); } diff --git a/public/modules/custom/helfi_rekry_content/src/Form/SettingsForm.php b/public/modules/custom/helfi_rekry_content/src/Form/SettingsForm.php index d45a1784..aab8d8c1 100644 --- a/public/modules/custom/helfi_rekry_content/src/Form/SettingsForm.php +++ b/public/modules/custom/helfi_rekry_content/src/Form/SettingsForm.php @@ -87,32 +87,6 @@ public function buildForm(array $form, FormStateInterface $form_state): array { '#description' => $this->t('This description text will be added to all job listings.'), ]; - $form['job_listings']['hakuvahti_tos_checkbox_label'] = [ - '#type' => 'textfield', - '#title' => $this->t('Hakuvahti terms of service checkbox label'), - '#default_value' => $siteConfig->get('hakuvahti_tos_checkbox_label'), - '#description' => $this->t('Label for the terms of service checkbox.'), - ]; - - $form['job_listings']['hakuvahti_tos_link_text'] = [ - '#type' => 'textfield', - '#title' => $this->t('Hakuvahti terms of service link text'), - '#default_value' => $siteConfig->get('hakuvahti_tos_link_text'), - ]; - - $form['job_listings']['hakuvahti_tos_link_url'] = [ - '#type' => 'textfield', - '#title' => $this->t('Hakuvahti terms of service URL'), - '#default_value' => $siteConfig->get('hakuvahti_tos_link_url'), - '#description' => $this->t('URL for the webpage or pdf to the Hakuvahti terms of service.'), - ]; - - $form['job_listings']['hakuvahti_instructions_link_url'] = [ - '#type' => 'textfield', - '#title' => $this->t('More detailed instructions on how to use saved searches'), - '#default_value' => $siteConfig->get('hakuvahti_instructions_link_url'), - ]; - return parent::buildForm($form, $form_state); } @@ -125,10 +99,6 @@ public function submitForm(array &$form, FormStateInterface $form_state) { ->set('redirect_403_page', $form_state->getValue('redirect_403_page')) ->set('city_description_title', $form_state->getValue('city_description_title')) ->set('city_description_text', $form_state->getValue('city_description_text')) - ->set('hakuvahti_tos_checkbox_label', $form_state->getValue('hakuvahti_tos_checkbox_label')) - ->set('hakuvahti_tos_link_text', $form_state->getValue('hakuvahti_tos_link_text')) - ->set('hakuvahti_tos_link_url', $form_state->getValue('hakuvahti_tos_link_url')) - ->set('hakuvahti_instructions_link_url', $form_state->getValue('hakuvahti_instructions_link_url')) ->save(); parent::submitForm($form, $form_state); } diff --git a/public/modules/custom/helfi_rekry_content/src/Hook/JobListingTheme.php b/public/modules/custom/helfi_rekry_content/src/Hook/JobListingTheme.php new file mode 100644 index 00000000..8f833f2b --- /dev/null +++ b/public/modules/custom/helfi_rekry_content/src/Hook/JobListingTheme.php @@ -0,0 +1,57 @@ +getType(); + $langcode = $this->languageManager + ->getCurrentLanguage(LanguageInterface::TYPE_CONTENT) + ->getId(); + + if ($paragraph_type == 'job_search') { + if ($search_result_page_nid = $paragraph->get('field_job_search_result_page')->getString()) { + + $entity = $this->entityTypeManager + ->getStorage('node') + ->load($search_result_page_nid); + + if ($entity->hasTranslation($langcode)) { + $entity = $entity->getTranslation($langcode); + } + + $url = $entity->toUrl()->toString(); + $variables['#attached']['drupalSettings']['helfi_rekry_job_search']['results_page_path'] = $url; + } + } + + // Apply hakuvahti settings. + $this->drupalSettings->applyTo($variables); + } + +} diff --git a/public/modules/custom/helfi_rekry_content/tests/src/Kernel/FilenameTest.php b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/FilenameTest.php index 6b81bf01..dd978789 100644 --- a/public/modules/custom/helfi_rekry_content/tests/src/Kernel/FilenameTest.php +++ b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/FilenameTest.php @@ -4,14 +4,15 @@ namespace Drupal\Tests\helfi_rekry_content\Kernel; -use Drupal\KernelTests\KernelTestBase; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; /** * Tests file name transliteration. - * - * @group helfi_rekry_content */ -class FilenameTest extends KernelTestBase { +#[Group('helfi_rekry_content')] +#[RunTestsInSeparateProcesses] +class FilenameTest extends RekryKernelTestBase { /** * {@inheritdoc} diff --git a/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HakuvahtiEventSubscriberTest.php b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HakuvahtiEventSubscriberTest.php index 93c33c73..34c9e45a 100644 --- a/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HakuvahtiEventSubscriberTest.php +++ b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HakuvahtiEventSubscriberTest.php @@ -7,48 +7,70 @@ use Drupal\helfi_hakuvahti\Event\SubscriptionAlterEvent; use Drupal\helfi_hakuvahti\HakuvahtiRequest; use Drupal\helfi_rekry_content\Service\HakuvahtiTracker; -use Drupal\KernelTests\KernelTestBase; +use Drupal\Tests\helfi_rekry_content\Kernel\RekryKernelTestBase; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; use Prophecy\Argument; use Psr\EventDispatcher\EventDispatcherInterface; /** * Tests hakuvahti event subscriber. */ -class HakuvahtiEventSubscriberTest extends KernelTestBase { +#[RunTestsInSeparateProcesses] +class HakuvahtiEventSubscriberTest extends RekryKernelTestBase { /** - * {@inheritdoc} + * Data provider for search description tests. */ - protected static $modules = [ - 'helfi_rekry_content', - ]; + public static function searchDescriptionDataProvider(): array { + return [ + 'filters are joined' => [ + [['a', 'b', 'c'], ['d']], + 'a, b, c, d', + ], + 'vapaa-sana is included' => [ + ['vapaa-sana' => ['search'], 'other' => ['filter1', 'filter2']], + 'search, filter1, filter2', + ], + 'empty filters' => [ + [], + '', + ], + 'user-provided description is replaced' => [ + [['safe-filter']], + 'safe-filter', + ], + 'vapaa-sana is truncated' => [ + ['vapaa-sana' => ['some keyword']], + 'some keyw…', + ], + ]; + } /** - * Tests alter event. + * Tests that searchDescription is computed correctly from filters. */ - public function testHakuvahtiEventSubscriber(): void { + #[DataProvider('searchDescriptionDataProvider')] + public function testSearchDescription(array $filters, string $expected): void { $tracker = $this->prophesize(HakuvahtiTracker::class); - - $tracker->parseQuery(Argument::any(), Argument::any(), 'sv', Argument::any()) + $tracker->parseQuery(Argument::any(), Argument::any(), Argument::any(), Argument::any()) ->shouldBeCalled() - ->willReturn([['a', 'b', 'c'], ['d']]); - + ->willReturn($filters); $this->container->set(HakuvahtiTracker::class, $tracker->reveal()); - $alterEvent = new SubscriptionAlterEvent(new HakuvahtiRequest([ + $event = new SubscriptionAlterEvent(new HakuvahtiRequest([ 'email' => 'valid@email.fi', 'lang' => 'sv', - 'site_id' => 'rekry', + 'siteId' => 'rekry', 'query' => '?query=123¶meters=4567', - 'elastic_query' => 'this-is_the_base64_encoded_elasticsearch_query', - 'search_description' => 'This, is the query filters string, separated, by comma', + 'elasticQuery' => 'this-is_the_base64_encoded_elasticsearch_query', + 'searchDescription' => 'Original description', ])); $dispatcher = $this->container->get(EventDispatcherInterface::class); - $dispatcher->dispatch($alterEvent); + $dispatcher->dispatch($event); - // Alter event replaces the search description provided by the user. - $this->assertEquals('a, b, c, d', $alterEvent->getHakuvahtiRequest()->searchDescription); + $this->assertEquals($expected, $event->getHakuvahtiRequest()->searchDescription); } } diff --git a/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HakuvahtiSubscribeTest.php b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HakuvahtiSubscribeTest.php index 5be35dfa..e5f69cd0 100644 --- a/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HakuvahtiSubscribeTest.php +++ b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HakuvahtiSubscribeTest.php @@ -10,14 +10,16 @@ use Drupal\Tests\helfi_api_base\Traits\ApiTestTrait; use Drupal\Tests\helfi_media\Kernel\HelfiMediaKernelTestBase; use Drupal\Tests\taxonomy\Traits\TaxonomyTestTrait; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; use Prophecy\Argument; use Symfony\Component\DependencyInjection\Loader\Configurator\Traits\PropertyTrait; /** * Tests file name transliteration. - * - * @group helfi_rekry_content */ +#[RunTestsInSeparateProcesses] +#[Group('helfi_rekry_content')] class HakuvahtiSubscribeTest extends HelfiMediaKernelTestBase { use ApiTestTrait; @@ -38,6 +40,7 @@ class HakuvahtiSubscribeTest extends HelfiMediaKernelTestBase { 'taxonomy', 'options', 'readonly_field_widget', + 'helfi_hakuvahti', 'helfi_rekry_content', ]; diff --git a/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HakuvahtiTrackerTest.php b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HakuvahtiTrackerTest.php index 37330fd8..ffda0ba2 100644 --- a/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HakuvahtiTrackerTest.php +++ b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HakuvahtiTrackerTest.php @@ -7,12 +7,15 @@ use Drupal\Core\Form\FormState; use Drupal\helfi_rekry_content\Form\SelectedFiltersCsvForm; use Drupal\helfi_rekry_content\Service\HakuvahtiTracker; -use Drupal\KernelTests\KernelTestBase; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; /** * Hakuvahti tracker test. */ -class HakuvahtiTrackerTest extends KernelTestBase { +#[RunTestsInSeparateProcesses] +#[Group('helfi_rekry_content')] +class HakuvahtiTrackerTest extends RekryKernelTestBase { /** * {@inheritdoc} @@ -20,7 +23,6 @@ class HakuvahtiTrackerTest extends KernelTestBase { protected static $modules = [ 'system', 'taxonomy', - 'helfi_rekry_content', ]; /** diff --git a/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HelbitMigrationDeriverTest.php b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HelbitMigrationDeriverTest.php index cc0f67bd..1be6b5ad 100644 --- a/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HelbitMigrationDeriverTest.php +++ b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HelbitMigrationDeriverTest.php @@ -8,12 +8,14 @@ use Drupal\helfi_rekry_content\Helbit\Settings; use Drupal\helfi_rekry_content\Plugin\Deriver\HelbitMigrationDeriver; use Drupal\KernelTests\KernelTestBase; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; /** * Tests migration deriver. - * - * @group helfi_rekry_content */ +#[RunTestsInSeparateProcesses] +#[Group('helfi_rekry_content')] class HelbitMigrationDeriverTest extends KernelTestBase { private const TEST_HELBIT_KEY = '1234'; diff --git a/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HelbitOpenJobsTest.php b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HelbitOpenJobsTest.php index 355366ee..56825e27 100644 --- a/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HelbitOpenJobsTest.php +++ b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/HelbitOpenJobsTest.php @@ -10,14 +10,16 @@ use Drupal\KernelTests\KernelTestBase; use Drupal\migrate\Plugin\MigrateIdMapInterface; use Drupal\migrate\Plugin\MigrationInterface; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; /** * Tests migration source plugin. - * - * @group helfi_rekry_content */ +#[RunTestsInSeparateProcesses] +#[Group('helfi_rekry_content')] class HelbitOpenJobsTest extends KernelTestBase { use ProphecyTrait; diff --git a/public/modules/custom/helfi_rekry_content/tests/src/Kernel/JobListingThemeTest.php b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/JobListingThemeTest.php new file mode 100644 index 00000000..9388a085 --- /dev/null +++ b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/JobListingThemeTest.php @@ -0,0 +1,100 @@ +installEntitySchema('user'); + $this->installEntitySchema('node'); + $this->installSchema('node', ['node_access']); + $this->installConfig(['helfi_hakuvahti', 'filter']); + + NodeType::create(['type' => 'page', 'name' => 'Page'])->save(); + } + + /** + * Gets the system under test with real container services. + */ + private function getSut(): JobListingTheme { + return new JobListingTheme( + $this->container->get(LanguageManagerInterface::class), + $this->container->get(EntityTypeManagerInterface::class), + $this->container->get(DrupalSettings::class), + ); + } + + /** + * Builds a mock job_search paragraph pointing to the given node ID. + */ + private function mockJobSearchParagraph(string $nid): Paragraph { + $field = $this->prophesize(FieldItemListInterface::class); + $field->getString()->willReturn($nid); + + $paragraph = $this->prophesize(Paragraph::class); + $paragraph->getType()->willReturn('job_search'); + $paragraph->get('field_job_search_result_page')->willReturn($field->reveal()); + + return $paragraph->reveal(); + } + + /** + * Tests that the result page URL is attached for a job_search paragraph. + */ + public function testResultsPageUrlIsAttached(): void { + $node = Node::create(['type' => 'page', 'title' => 'Jobs']); + $node->save(); + + $variables = ['paragraph' => $this->mockJobSearchParagraph((string) $node->id())]; + + $this->getSut()->preprocessParagraph($variables); + + $this->assertArrayHasKey( + 'results_page_path', + $variables['#attached']['drupalSettings']['helfi_rekry_job_search'], + ); + $this->assertNotEmpty( + $variables['#attached']['drupalSettings']['helfi_rekry_job_search']['results_page_path'], + ); + } + +} diff --git a/public/modules/custom/helfi_rekry_content/tests/src/Kernel/JobMigrationTest.php b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/JobMigrationTest.php index 5cfebd1c..769b8ec1 100644 --- a/public/modules/custom/helfi_rekry_content/tests/src/Kernel/JobMigrationTest.php +++ b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/JobMigrationTest.php @@ -4,28 +4,24 @@ namespace Drupal\Tests\helfi_rekry_content\Kernel; -use Drupal\KernelTests\KernelTestBase; use Drupal\media\OEmbed\Provider; use Drupal\media\OEmbed\ProviderException; use Drupal\media\OEmbed\UrlResolverInterface; use Drupal\migrate\MigrateSkipRowException; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; /** * Job migration tests. */ -class JobMigrationTest extends KernelTestBase { +#[RunTestsInSeparateProcesses] +#[Group('helfi_rekry_content')] +class JobMigrationTest extends RekryKernelTestBase { use ProphecyTrait; - /** - * {@inheritdoc} - */ - protected static $modules = [ - 'helfi_rekry_content', - ]; - /** * Test video URL sanitization. * diff --git a/public/modules/custom/helfi_rekry_content/tests/src/Kernel/RekryKernelTestBase.php b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/RekryKernelTestBase.php new file mode 100644 index 00000000..8553d92d --- /dev/null +++ b/public/modules/custom/helfi_rekry_content/tests/src/Kernel/RekryKernelTestBase.php @@ -0,0 +1,22 @@ +:last-child .component--job-listing-search:last-child{margin-bottom:-115px;padding-bottom:55px}.job-listing-search__result-actions{align-items:flex-end;display:flex;justify-content:space-between}.component--job-listing-search .component__container{padding-bottom:32px;padding-top:32px}@media(min-width:768px){.component--job-listing-search .component__container{padding-bottom:64px;padding-top:64px}}.job-listing-search__sort{min-width:283px}.job-listing-search__result--list{margin-top:24px}@media(min-width:768px){.job-listing-search__result--list{margin-top:32px}}.job-search-form,.job-search-form__title{margin-bottom:32px}@media(min-width:992px){.job-search-form__dropdowns__upper{display:flex;margin-left:-12px;margin-right:-12px}.job-search-form__dropdowns__upper>*{margin-left:12px;margin-right:12px}}.job-search-form__dropdown li+li{margin-top:0}@media(min-width:992px){.job-search-form__dropdown--upper{width:50%}}.job-search-form__dropdown--upper .job-search-form__dropdown{max-width:none;max-width:unset}.job-search-form__filter{margin-bottom:16px;width:100%}@media(min-width:992px){.job-search-form__filter{margin-bottom:24px}}.job-search-form__checkboxes{border:none;margin-bottom:16px;padding:0}@media(min-width:992px){.job-search-form__checkboxes{display:flex}}fieldset .job-search-form__checkbox{--background-selected:var(--hdbt-color-black)}fieldset .job-search-form__checkbox:not(:first-of-type){margin-top:32px}@media(min-width:992px){fieldset .job-search-form__checkbox:not(:first-of-type){margin-left:16px;margin-top:0}}.job-search-form__checkboxes-legend,.job-search__no-results__heading{--line-height:1.5;font-size:1rem;font-weight:700;letter-spacing:.0125rem;line-height:1.5;line-height:var(--line-height);margin-bottom:16px}@media(min-width:992px){.job-search-form__checkboxes-legend,.job-search__no-results__heading{--line-height:1.5555555556;font-size:1.125rem;font-weight:700}}.job-search-form__selections-container{list-style-type:none}html.Dialog-module_dialogVisibleBodyWithHiddenScrollbars__3M__P{overflow:visible!important}.hdbt-search--react__result-top-area-item button.job-search-form__search-monitor__button{max-width:420px;width:100%}@media(min-width:992px){.hdbt-search--react__result-top-area-item button.job-search-form__search-monitor__button{margin-block:24px 8px;max-width:none;max-width:unset;min-width:288px;width:auto}}.job-search-form__search-monitor__content>div{padding-inline:16px;padding-bottom:0}@media(min-width:992px){.job-search-form__search-monitor__content>div{padding-inline:32px}}.job-search-form__search-monitor__content>div>:not(.job-search-form__search-monitor) button:focus{box-shadow:0 0 0 3px #1a1a1a}.job-search-form__search-monitor__content .job-search-form__search-monitor__heading{--line-height:1.3333333333;font-size:1.5rem;font-weight:500;letter-spacing:-.0125rem;line-height:1.3333333333;line-height:var(--line-height)}@media(min-width:992px){.job-search-form__search-monitor__content .job-search-form__search-monitor__heading{--line-height:1.1875;font-size:2rem;font-weight:400;letter-spacing:-.025rem}}.job-search-form__search-monitor__content .job-search-form__search-monitor__heading:focus:after{border-color:#1a1a1a}.job-search-form__search-monitor{margin-bottom:24px}@media(min-width:992px){.job-search-form__search-monitor{margin-bottom:32px}}.job-search-form__search-monitor>p{--line-height:1.5555555556;font-size:1.125rem;font-weight:400;line-height:1.5555555556;line-height:var(--line-height);margin-top:16px}.job-search-form__search-monitor a:focus-visible{outline:3px solid #1a1a1a;outline-offset:4px}.job-search-form__search-monitor__selections-heading{--line-height:1.5;font-size:1rem;font-weight:400;font-weight:500;line-height:var(--line-height);line-height:1.5;margin-top:24px}.job-search-form__search-monitor__no-selections,.job-search-form__search-monitor__selection-tags{margin-top:4px}.job-search-form__search-monitor__email{margin-top:16px}.job-search-form__search-monitor__no-selections+.job-search-form__search-monitor__email{margin-top:24px}.job-search-form__search-monitor__buttons-container{-moz-column-gap:16px;column-gap:16px;display:flex;flex-wrap:wrap;margin-top:8px}.job-search-form__search-monitor__buttons-container>.job-search-form__search-monitor__cancel-button,.job-search-form__search-monitor__buttons-container>.job-search-form__search-monitor__submit-button{margin-bottom:0;margin-top:16px;max-width:none;width:100%}@media(min-width:992px){.job-search-form__search-monitor__buttons-container>.job-search-form__search-monitor__cancel-button,.job-search-form__search-monitor__buttons-container>.job-search-form__search-monitor__submit-button{max-width:200px;width:auto}}.job-search-form__search-monitor__buttons-container>.job-search-form__search-monitor__cancel-button{width:100%}.job-search-form__search-monitor__terms-link{--line-height:1.5;display:block;font-size:1rem;font-weight:400;line-height:1.5;line-height:var(--line-height);margin-top:24px}.job-search-form__search-monitor__error{margin-top:24px}.job-search-form__search-monitor__error>div:focus-visible{outline:3px solid #1a1a1a;outline-offset:8px}.job-search-form__search-monitor__error ul{margin-block:16px 0}.job-search-form__search-monitor__error li+li,.job-search-form__search-monitor__error ul:first-child{margin-block-start:0} \ No newline at end of file +:root{--breakpoint-xs:320px;--breakpoint-s:576px;--breakpoint-m:768px;--breakpoint-l:992px;--breakpoint-xl:1248px;--container-width-xs:288px;--container-width-s:544px;--container-width-m:720px;--container-width-l:944px;--container-width-xl:1200px;--color-brick:#bd2719;--color-brick-light:#ffeeed;--color-brick-medium-light:#facbc8;--color-brick-dark:#800e04;--color-bus:#0000bf;--color-bus-light:#f0f0ff;--color-bus-medium-light:#ccf;--color-bus-dark:#00005e;--color-coat-of-arms:#0072c6;--color-coat-of-arms-light:#e6f4ff;--color-coat-of-arms-medium-light:#b5daf7;--color-coat-of-arms-dark:#005799;--color-copper:#00d7a7;--color-copper-light:#cffaf1;--color-copper-medium-light:#9ef0de;--color-copper-dark:#00a17d;--color-engel:#ffe977;--color-engel-light:#fff9db;--color-engel-medium-light:#fff3b8;--color-engel-dark:#dbc030;--color-fog:#9fc9eb;--color-fog-light:#e8f3fc;--color-fog-medium-light:#d0e6f7;--color-fog-dark:#72a5cf;--color-gold:#c2a251;--color-gold-light:#f7f2e4;--color-gold-medium-light:#e8d7a7;--color-gold-dark:#9e823c;--color-metro:#fd4f00;--color-metro-light:#ffeee6;--color-metro-medium-light:#ffcab3;--color-metro-dark:#bd2f00;--color-silver:#dedfe1;--color-silver-light:#f7f7f8;--color-silver-medium-light:#efeff0;--color-silver-dark:#b0b8bf;--color-summer:#ffc61e;--color-summer-light:#fff4d4;--color-summer-medium-light:#ffe49c;--color-summer-dark:#cc9200;--color-suomenlinna:#f5a3c7;--color-suomenlinna-light:#fff0f7;--color-suomenlinna-medium-light:#ffdbeb;--color-suomenlinna-dark:#e673a5;--color-tram:#008741;--color-tram-light:#dff7eb;--color-tram-medium-light:#a3e3c2;--color-tram-dark:#006631;--color-focus-outline:#0072c6;--color-black:#000;--color-white:#fff;--color-black-5:#f2f2f2;--color-black-10:#e6e6e6;--color-black-20:#ccc;--color-black-30:#b3b3b3;--color-black-40:#999;--color-black-50:grey;--color-black-60:#666;--color-black-70:#4d4d4d;--color-black-80:#333;--color-black-90:#1a1a1a;--color-error:#b01038;--color-error-light:#f6e2e6;--color-error-dark:#8d0d2d;--color-success:#007a64;--color-success-light:#e2f5f3;--color-success-dark:#006250;--color-alert:#ffda07;--color-alert-light:#fff4b4;--color-alert-dark:#d18200;--color-info:#0062b9;--color-info-light:#e5eff8;--color-info-dark:#004f94;--box-shadow-s:0px 2px 10px 0px rgba(0,0,0,.07);--box-shadow-m:0px 2px 10px 0px rgba(0,0,0,.1);--box-shadow-l:0px 2px 20px 0px rgba(0,0,0,.2);--spacing-layout-2-xs:1rem;--spacing-layout-xs:1.5rem;--spacing-layout-s:2rem;--spacing-layout-m:3rem;--spacing-layout-l:4rem;--spacing-layout-xl:6rem;--spacing-layout-2-xl:8rem;--spacing-4-xs:0.125rem;--spacing-3-xs:0.25rem;--spacing-2-xs:0.5rem;--spacing-xs:0.75rem;--spacing-s:1rem;--spacing-m:1.5rem;--spacing-l:2rem;--spacing-xl:2.5rem;--spacing-2-xl:3.0rem;--spacing-3-xl:3.5rem;--spacing-4-xl:4rem;--spacing-5-xl:4.5rem;--fontsize-heading-xxl:4rem;--fontsize-heading-xl:3rem;--fontsize-heading-xl-mobile:2.5rem;--fontsize-heading-l:2rem;--fontsize-heading-m:1.5rem;--fontsize-heading-s:1.25rem;--fontsize-heading-xs:1.125rem;--fontsize-heading-xxs:1rem;--fontsize-body-s:0.875rem;--fontsize-body-m:1rem;--fontsize-body-l:1.125rem;--fontsize-body-xl:1.25rem;--font-default:HelsinkiGrotesk,Arial,sans-serif;--lineheight-s:1;--lineheight-m:1.2;--lineheight-l:1.5;--lineheight-xl:1.75}.job-listing__organization-name{--line-height:1.5555555556;display:flex;font-size:1.125rem;font-weight:400;line-height:1.5555555556;line-height:var(--line-height);margin-top:16px}@media(min-width:768px){.job-listing__organization-name{margin-top:24px}}.organization{display:flex;margin-right:8px;position:relative}.organization:after{content:","}.organization:last-child{margin-right:0}.organization:last-child:after{display:none}.job-listing__item{padding-left:16px;padding-right:16px}@media(min-width:768px){.job-listing__item{padding-left:32px;padding-right:32px}}.job-listing__link-wrapper{margin-top:16px}@media(min-width:768px){.job-listing__link-wrapper{margin-top:24px}}.job-listing__link-wrapper.job-listing__link-wrapper--last{margin-top:32px}@media(min-width:768px){.job-listing__link-wrapper.job-listing__link-wrapper--last{margin-top:48px}}.job-listing__link{width:100%}@media(min-width:768px){.job-listing__link{width:auto}}.job-listing__job-description{--line-height:1.5555555556;font-size:1.125rem;font-weight:400;line-height:1.5555555556;line-height:var(--line-height);margin-top:16px}@media(min-width:768px){.job-listing__job-description{margin-top:48px}}.job-listing__job-description p:first-child{margin-top:0}.job-listing__salary-class__content{--line-height:1.5555555556;font-size:1.125rem;font-weight:400;line-height:1.5555555556;line-height:var(--line-height)}.job-listing__sidebar{background-color:var(--hdbt-color-palette--secondary)}.job-listing__city-description,.job-listing__organization-information{padding:24px}.job-listing__image img{display:block;height:auto;max-width:100%;overflow:hidden}.job-listing__image .image-placeholder{padding-bottom:66.67%}.job-listing__city-description-title,.job-listing__organization{--line-height:1.5;font-size:1rem;font-weight:700;letter-spacing:.0125rem;line-height:1.5;line-height:var(--line-height);margin-top:0}@media(min-width:992px){.job-listing__city-description-title,.job-listing__organization{--line-height:1.5555555556;font-size:1.125rem;font-weight:700}}.job-listing__city-description-text,.job-listing__organization-description{--line-height:1.5;font-size:1rem;font-weight:400;line-height:1.5;line-height:var(--line-height);margin-top:8px}.job-listing__city-description-text p:first-child,.job-listing__organization-description p:first-child{margin-top:0}.node--type-job-listing .component--remote-video{margin-top:32px}@media(min-width:992px){.node--type-job-listing .component--remote-video{margin-top:48px}}.node--type-job-listing.node--view-mode-full .content-tags{margin-top:24px}.block--of-interest{background-color:#f2f2f2;margin-bottom:-98px;margin-top:64px;padding:80px 0}.block--of-interest .block--of-interest__content-container{margin:auto;max-width:1296px;padding-left:16px;padding-right:16px}@media(min-width:768px){.block--of-interest .block--of-interest__content-container{max-width:1328px;padding-left:32px;padding-right:32px}}.block--of-interest h2{margin-bottom:48px;margin-top:0}.block--of-interest .block--of-interest__more-link{margin-top:48px}.component--job-listing-search{background-color:#f2f2f2}.layout-main-wrapper>:last-child .component--job-listing-search:last-child{margin-bottom:-115px;padding-bottom:55px}.job-listing-search__result-actions{align-items:flex-end;display:flex;justify-content:space-between}.component--job-listing-search .component__container{padding-bottom:32px;padding-top:32px}@media(min-width:768px){.component--job-listing-search .component__container{padding-bottom:64px;padding-top:64px}}.job-listing-search__sort{min-width:283px}.job-listing-search__result--list{margin-top:24px}@media(min-width:768px){.job-listing-search__result--list{margin-top:32px}}.job-search-form,.job-search-form__title{margin-bottom:32px}@media(min-width:992px){.job-search-form__dropdowns__upper{display:flex;margin-left:-12px;margin-right:-12px}.job-search-form__dropdowns__upper>*{margin-left:12px;margin-right:12px}}.job-search-form__dropdown li+li{margin-top:0}@media(min-width:992px){.job-search-form__dropdown--upper{width:50%}}.job-search-form__dropdown--upper .job-search-form__dropdown{max-width:none;max-width:unset}.job-search-form__filter{margin-bottom:16px;width:100%}@media(min-width:992px){.job-search-form__filter{margin-bottom:24px}}.job-search-form__checkboxes{border:none;margin-bottom:16px;padding:0}@media(min-width:992px){.job-search-form__checkboxes{display:flex}}fieldset .job-search-form__checkbox{--background-selected:var(--hdbt-color-black)}fieldset .job-search-form__checkbox:not(:first-of-type){margin-top:32px}@media(min-width:992px){fieldset .job-search-form__checkbox:not(:first-of-type){margin-left:16px;margin-top:0}}.job-search-form__checkboxes-legend,.job-search__no-results__heading{--line-height:1.5;font-size:1rem;font-weight:700;letter-spacing:.0125rem;line-height:1.5;line-height:var(--line-height);margin-bottom:16px}@media(min-width:992px){.job-search-form__checkboxes-legend,.job-search__no-results__heading{--line-height:1.5555555556;font-size:1.125rem;font-weight:700}}.job-search-form__selections-container{list-style-type:none} \ No newline at end of file diff --git a/public/themes/custom/hdbt_subtheme/src/scss/06-components/paragraphs/_job-listing-search.scss b/public/themes/custom/hdbt_subtheme/src/scss/06-components/paragraphs/_job-listing-search.scss index 72e0d272..1e9e5f06 100644 --- a/public/themes/custom/hdbt_subtheme/src/scss/06-components/paragraphs/_job-listing-search.scss +++ b/public/themes/custom/hdbt_subtheme/src/scss/06-components/paragraphs/_job-listing-search.scss @@ -1,15 +1,6 @@ // Minimum width for the sort element. Stops weird behavior on wider screens. $sort-minimum-width: 283px; -// Set explicitly to mirror adjacent dropdown styles (hds-defined). -$monitor-button-max-width: 420px; - -// Monitor button min width on larger screens. -$monitor-button-min-width: 288px; - -// Dialog control buttons max width (from sketches). -$monitor-control-max-width: 200px; - .component--job-listing-search { background-color: $color-black-5; } @@ -122,146 +113,3 @@ fieldset .job-search-form__checkbox:not(:first-of-type) { .job-search-form__selections-container { list-style-type: none; } - -// Search monitor styles - -// Fixes a weird issue with hds dialog element. Should be removed if HDS issue is ever fixed. -html.Dialog-module_dialogVisibleBodyWithHiddenScrollbars__3M__P { - overflow: visible !important; -} - -// Override HDS-default style. -// The button that opens the search monitor dialog. -.hdbt-search--react__result-top-area-item button.job-search-form__search-monitor__button { - max-width: $monitor-button-max-width; - width: 100%; - - @include breakpoint($breakpoint-l) { - margin-block: $spacing-and-half $spacing-half; - max-width: unset; - min-width: $monitor-button-min-width; - width: auto; - } -} - -// Override HDS-default style. -// The header that contains title and closing button shouldn't have padding on the bottom. -// Also the paddings on the sides are different. -.job-search-form__search-monitor__content > div { - padding-inline: $spacing; - padding-bottom: 0; - - @include breakpoint($breakpoint-l) { - padding-inline: $spacing-double; - } - - // Override HDS-default style. - // The closing button focus is done using box-shadow with blue color, - // but we want the focus ring to be black-90. - > *:not(.job-search-form__search-monitor) button:focus { - box-shadow: 0 0 0 3px $color-black-90; - } -} - -// Override HDS-default dialog style. -// The dialog header needs to be larger than the HDS-version. -.job-search-form__search-monitor__content .job-search-form__search-monitor__heading { - @include font(h3); - - &:focus::after { - border-color: $color-black-90; - } -} - -.job-search-form__search-monitor { - margin-bottom: $spacing-and-half; - - @include breakpoint($breakpoint-l) { - margin-bottom: $spacing-double; - } - - > p { - @include font('body'); - margin-top: $spacing; - } - - a:focus-visible { - outline: 3px solid $color-black-90; - outline-offset: $spacing-quarter; - } -} - -.job-search-form__search-monitor__selections-heading { - @include font(small); - font-weight: $font-weight-medium; - line-height: $lineheight-l; - margin-top: $spacing-and-half; -} - -.job-search-form__search-monitor__no-selections, -.job-search-form__search-monitor__selection-tags { - margin-top: $spacing-quarter; -} - -// Email field comes right after the tags and tags always have small amount of spacing -// under them so we need to compensate that in the email-elements top margin. -.job-search-form__search-monitor__email { - margin-top: $spacing; -} - -// If the element before email field is the empty-notification, the margin compensation -// used with the tags is not needed. -.job-search-form__search-monitor__no-selections + .job-search-form__search-monitor__email { - margin-top: $spacing-and-half; -} - -.job-search-form__search-monitor__buttons-container { - column-gap: $spacing; - display: flex; - flex-wrap: wrap; - margin-top: $spacing-half; - - > .job-search-form__search-monitor__submit-button, - > .job-search-form__search-monitor__cancel-button { - margin-bottom: 0; - margin-top: $spacing; - max-width: none; - width: 100%; - - @include breakpoint($breakpoint-l) { - max-width: $monitor-control-max-width; - width: auto; - } - } - - > .job-search-form__search-monitor__cancel-button { - width: 100%; - } -} - -.job-search-form__search-monitor__terms-link { - @include font('small'); - display: block; - margin-top: $spacing-and-half; -} - -.job-search-form__search-monitor__error { - margin-top: $spacing-and-half; - - > div:focus-visible { - outline: 3px solid $color-black-90; - outline-offset: $spacing-half; - } - - ul { - margin-block: $spacing 0; - } - - ul:first-child { - margin-block-start: 0; - } - - li + li { - margin-block-start: 0; - } -}